Remove fuse kernel module sources
authorMiklos Szeredi <miklos@szeredi.hu>
Mon, 16 Jun 2008 14:16:02 +0000 (14:16 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Mon, 16 Jun 2008 14:16:02 +0000 (14:16 +0000)
17 files changed:
ChangeLog
Makefile.am
README
README.NFS
configure.in
include/fuse_kernel.h [new file with mode: 0644]
kernel/.cvsignore [deleted file]
kernel/Makefile.in [deleted file]
kernel/configure.ac [deleted file]
kernel/control.c [deleted file]
kernel/dev.c [deleted file]
kernel/dir.c [deleted file]
kernel/file.c [deleted file]
kernel/fuse_i.h [deleted file]
kernel/fuse_kernel.h [deleted file]
kernel/inode.c [deleted file]
makeconf.sh

index 18a479ab39742b9e50e45efccd19189437334593..dee8a3b1b5469ea3d6f9952727ebcdb8a83d775e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-16  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Remove fuse kernel module sources.  Linux 2.6.27 will support
+       NFS exporting.
+
 2008-06-10  Miklos Szeredi <miklos@szeredi.hu>
 
        * Fix theoretical infinite loops in libfuse.  Reported by Szabolcs
index 06014eec8f854932292eb0732b7ffdf0b81cc8a4..772dfcc29dd3f43f62ce88fb6b06c60d5f080225 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = @subdirs@ @subdirs2@
+SUBDIRS = @subdirs2@
 
 EXTRA_DIST =                   \
        fuse.pc.in              \
diff --git a/README b/README
index 4d9dd92ad84f0d799784ef9767e5b9b0fdcc344f..398dd655706ada02b0c205c7ff0076890c3699bf 100644 (file)
--- a/README
+++ b/README
@@ -35,25 +35,8 @@ modprobe fuse
 You may also need to add '/usr/local/lib' to '/etc/ld.so.conf' and/or
 run ldconfig.
 
-Linux kernels 2.6.14 or later contain FUSE support out of the box.  If
-FUSE support is detected, the kernel module in this package will not
-be compiled.  It is possible to override this with the
-'--enable-kernel-module' configure option.
-
-If './configure' cannot find the kernel source or it says the kernel
-source should be prepared, you may either try
-
-  ./configure --disable-kernel-module
-
-or if your kernel does not already contain FUSE support, do the
-following:
-
-  - Extract the kernel source to some directory
-
-  - Copy the running kernel's config (usually found in
-    /boot/config-X.Y.Z) to .config at the top of the source tree
-
-  - Run 'make prepare'
+You'll also need a fuse kernel module, Linux kernels 2.6.14 or later
+contain FUSE support.
 
 For more details see the file 'INSTALL'
 
index a6f48c561e0b92d69f731f2a466e56d169a20205..b805f39239bb448d32aa2f8647d0d7f1b2671c23 100644 (file)
@@ -1,17 +1,4 @@
-FUSE module in official kernels (>= 2.6.14) don't support NFS
-exporting.  In this case if you need NFS exporting capability, use the
-'--enable-kernel-module' configure option to compile the module from
-this package.  And make sure, that the FUSE is not compiled into the
-kernel (CONFIG_FUSE_FS must be 'm' or 'n').
+NFS exporting is supported in Linux kernels 2.6.27 or later.
 
 You need to add an fsid=NNN option to /etc/exports to make exporting a
 FUSE directory work.
-
-You may get ESTALE (Stale NFS file handle) errors with this.  This is
-because the current FUSE kernel API and the userspace library cannot
-handle a situation where the kernel forgets about an inode which is
-still referenced by the remote NFS client.  This problem will be
-addressed in a later version.
-
-In the future it planned that NFS exporting will be done solely in
-userspace.
index 6c4f484d98c6cee2ae029125847a880ae5c06438..61d3ca86bd3cfe4cece61914314171144492538b 100644 (file)
@@ -23,8 +23,6 @@ if test "$ac_env_CFLAGS_set" != set; then
        CFLAGS="-Wall -W -Wno-sign-compare -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -g -O2 -fno-strict-aliasing"
 fi
 
-AC_ARG_ENABLE(kernel-module,
-       [  --enable-kernel-module  Compile kernel module ])
 AC_ARG_ENABLE(lib,
        [  --enable-lib            Compile with library ])
 AC_ARG_ENABLE(util,
@@ -42,10 +40,6 @@ AC_SUBST(pkgconfigdir)
 
 subdirs2="include"
 
-if test "$arch" = linux -a "$enable_kernel_module" != "no"; then
-       AC_CONFIG_SUBDIRS(kernel)
-fi
-
 if test "$enable_lib" != "no"; then
        subdirs2="$subdirs2 lib";
 fi
diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
new file mode 100644 (file)
index 0000000..c9c4c7e
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+    This file defines the kernel interface of FUSE
+    Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
+
+    This program can be distributed under the terms of the GNU GPL.
+    See the file COPYING.
+
+    This -- and only this -- header file may also be distributed under
+    the terms of the BSD Licence as follows:
+
+    Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ *  - new fuse_getattr_in input argument of GETATTR
+ *  - add lk_flags in fuse_lk_in
+ *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ *  - add blksize field to fuse_attr
+ *  - add file flags field to fuse_read_in and fuse_write_in
+ */
+
+#ifndef linux
+#include <sys/types.h>
+#define __u64 uint64_t
+#define __u32 uint32_t
+#define __s32 int32_t
+#else
+#include <asm/types.h>
+#include <linux/major.h>
+#endif
+
+/** Version number of this interface */
+#define FUSE_KERNEL_VERSION 7
+
+/** Minor version number of this interface */
+#define FUSE_KERNEL_MINOR_VERSION 9
+
+/** The node ID of the root inode */
+#define FUSE_ROOT_ID 1
+
+/** The major number of the fuse character device */
+#define FUSE_MAJOR MISC_MAJOR
+
+/** The minor number of the fuse character device */
+#define FUSE_MINOR 229
+
+/* Make sure all structures are padded to 64bit boundary, so 32bit
+   userspace works under 64bit kernels */
+
+struct fuse_attr {
+       __u64   ino;
+       __u64   size;
+       __u64   blocks;
+       __u64   atime;
+       __u64   mtime;
+       __u64   ctime;
+       __u32   atimensec;
+       __u32   mtimensec;
+       __u32   ctimensec;
+       __u32   mode;
+       __u32   nlink;
+       __u32   uid;
+       __u32   gid;
+       __u32   rdev;
+       __u32   blksize;
+       __u32   padding;
+};
+
+struct fuse_kstatfs {
+       __u64   blocks;
+       __u64   bfree;
+       __u64   bavail;
+       __u64   files;
+       __u64   ffree;
+       __u32   bsize;
+       __u32   namelen;
+       __u32   frsize;
+       __u32   padding;
+       __u32   spare[6];
+};
+
+struct fuse_file_lock {
+       __u64   start;
+       __u64   end;
+       __u32   type;
+       __u32   pid; /* tgid */
+};
+
+/**
+ * Bitmasks for fuse_setattr_in.valid
+ */
+#define FATTR_MODE     (1 << 0)
+#define FATTR_UID      (1 << 1)
+#define FATTR_GID      (1 << 2)
+#define FATTR_SIZE     (1 << 3)
+#define FATTR_ATIME    (1 << 4)
+#define FATTR_MTIME    (1 << 5)
+#define FATTR_FH       (1 << 6)
+#define FATTR_ATIME_NOW        (1 << 7)
+#define FATTR_MTIME_NOW        (1 << 8)
+#define FATTR_LOCKOWNER        (1 << 9)
+
+/**
+ * Flags returned by the OPEN request
+ *
+ * FOPEN_DIRECT_IO: bypass page cache for this open file
+ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ */
+#define FOPEN_DIRECT_IO                (1 << 0)
+#define FOPEN_KEEP_CACHE       (1 << 1)
+
+/**
+ * INIT request/reply flags
+ */
+#define FUSE_ASYNC_READ                (1 << 0)
+#define FUSE_POSIX_LOCKS       (1 << 1)
+#define FUSE_FILE_OPS          (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC    (1 << 3)
+#define FUSE_BIG_WRITES                (1 << 5)
+
+/**
+ * Release flags
+ */
+#define FUSE_RELEASE_FLUSH     (1 << 0)
+
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH                (1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK          (1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE       (1 << 0)
+#define FUSE_WRITE_LOCKOWNER   (1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER    (1 << 1)
+
+enum fuse_opcode {
+       FUSE_LOOKUP        = 1,
+       FUSE_FORGET        = 2,  /* no reply */
+       FUSE_GETATTR       = 3,
+       FUSE_SETATTR       = 4,
+       FUSE_READLINK      = 5,
+       FUSE_SYMLINK       = 6,
+       FUSE_MKNOD         = 8,
+       FUSE_MKDIR         = 9,
+       FUSE_UNLINK        = 10,
+       FUSE_RMDIR         = 11,
+       FUSE_RENAME        = 12,
+       FUSE_LINK          = 13,
+       FUSE_OPEN          = 14,
+       FUSE_READ          = 15,
+       FUSE_WRITE         = 16,
+       FUSE_STATFS        = 17,
+       FUSE_RELEASE       = 18,
+       FUSE_FSYNC         = 20,
+       FUSE_SETXATTR      = 21,
+       FUSE_GETXATTR      = 22,
+       FUSE_LISTXATTR     = 23,
+       FUSE_REMOVEXATTR   = 24,
+       FUSE_FLUSH         = 25,
+       FUSE_INIT          = 26,
+       FUSE_OPENDIR       = 27,
+       FUSE_READDIR       = 28,
+       FUSE_RELEASEDIR    = 29,
+       FUSE_FSYNCDIR      = 30,
+       FUSE_GETLK         = 31,
+       FUSE_SETLK         = 32,
+       FUSE_SETLKW        = 33,
+       FUSE_ACCESS        = 34,
+       FUSE_CREATE        = 35,
+       FUSE_INTERRUPT     = 36,
+       FUSE_BMAP          = 37,
+       FUSE_DESTROY       = 38,
+};
+
+/* The read buffer is required to be at least 8k, but may be much larger */
+#define FUSE_MIN_READ_BUFFER 8192
+
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
+struct fuse_entry_out {
+       __u64   nodeid;         /* Inode ID */
+       __u64   generation;     /* Inode generation: nodeid:gen must
+                                  be unique for the fs's lifetime */
+       __u64   entry_valid;    /* Cache timeout for the name */
+       __u64   attr_valid;     /* Cache timeout for the attributes */
+       __u32   entry_valid_nsec;
+       __u32   attr_valid_nsec;
+       struct fuse_attr attr;
+};
+
+struct fuse_forget_in {
+       __u64   nlookup;
+};
+
+struct fuse_getattr_in {
+       __u32   getattr_flags;
+       __u32   dummy;
+       __u64   fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
+struct fuse_attr_out {
+       __u64   attr_valid;     /* Cache timeout for the attributes */
+       __u32   attr_valid_nsec;
+       __u32   dummy;
+       struct fuse_attr attr;
+};
+
+struct fuse_mknod_in {
+       __u32   mode;
+       __u32   rdev;
+};
+
+struct fuse_mkdir_in {
+       __u32   mode;
+       __u32   padding;
+};
+
+struct fuse_rename_in {
+       __u64   newdir;
+};
+
+struct fuse_link_in {
+       __u64   oldnodeid;
+};
+
+struct fuse_setattr_in {
+       __u32   valid;
+       __u32   padding;
+       __u64   fh;
+       __u64   size;
+       __u64   lock_owner;
+       __u64   atime;
+       __u64   mtime;
+       __u64   unused2;
+       __u32   atimensec;
+       __u32   mtimensec;
+       __u32   unused3;
+       __u32   mode;
+       __u32   unused4;
+       __u32   uid;
+       __u32   gid;
+       __u32   unused5;
+};
+
+struct fuse_open_in {
+       __u32   flags;
+       __u32   mode;
+};
+
+struct fuse_open_out {
+       __u64   fh;
+       __u32   open_flags;
+       __u32   padding;
+};
+
+struct fuse_release_in {
+       __u64   fh;
+       __u32   flags;
+       __u32   release_flags;
+       __u64   lock_owner;
+};
+
+struct fuse_flush_in {
+       __u64   fh;
+       __u32   unused;
+       __u32   padding;
+       __u64   lock_owner;
+};
+
+struct fuse_read_in {
+       __u64   fh;
+       __u64   offset;
+       __u32   size;
+       __u32   read_flags;
+       __u64   lock_owner;
+       __u32   flags;
+       __u32   padding;
+};
+
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
+struct fuse_write_in {
+       __u64   fh;
+       __u64   offset;
+       __u32   size;
+       __u32   write_flags;
+       __u64   lock_owner;
+       __u32   flags;
+       __u32   padding;
+};
+
+struct fuse_write_out {
+       __u32   size;
+       __u32   padding;
+};
+
+#define FUSE_COMPAT_STATFS_SIZE 48
+
+struct fuse_statfs_out {
+       struct fuse_kstatfs st;
+};
+
+struct fuse_fsync_in {
+       __u64   fh;
+       __u32   fsync_flags;
+       __u32   padding;
+};
+
+struct fuse_setxattr_in {
+       __u32   size;
+       __u32   flags;
+};
+
+struct fuse_getxattr_in {
+       __u32   size;
+       __u32   padding;
+};
+
+struct fuse_getxattr_out {
+       __u32   size;
+       __u32   padding;
+};
+
+struct fuse_lk_in {
+       __u64   fh;
+       __u64   owner;
+       struct fuse_file_lock lk;
+       __u32   lk_flags;
+       __u32   padding;
+};
+
+struct fuse_lk_out {
+       struct fuse_file_lock lk;
+};
+
+struct fuse_access_in {
+       __u32   mask;
+       __u32   padding;
+};
+
+struct fuse_init_in {
+       __u32   major;
+       __u32   minor;
+       __u32   max_readahead;
+       __u32   flags;
+};
+
+struct fuse_init_out {
+       __u32   major;
+       __u32   minor;
+       __u32   max_readahead;
+       __u32   flags;
+       __u32   unused;
+       __u32   max_write;
+};
+
+struct fuse_interrupt_in {
+       __u64   unique;
+};
+
+struct fuse_bmap_in {
+       __u64   block;
+       __u32   blocksize;
+       __u32   padding;
+};
+
+struct fuse_bmap_out {
+       __u64   block;
+};
+
+struct fuse_in_header {
+       __u32   len;
+       __u32   opcode;
+       __u64   unique;
+       __u64   nodeid;
+       __u32   uid;
+       __u32   gid;
+       __u32   pid;
+       __u32   padding;
+};
+
+struct fuse_out_header {
+       __u32   len;
+       __s32   error;
+       __u64   unique;
+};
+
+struct fuse_dirent {
+       __u64   ino;
+       __u64   off;
+       __u32   namelen;
+       __u32   type;
+       char name[0];
+};
+
+#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
+#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
+#define FUSE_DIRENT_SIZE(d) \
+       FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
diff --git a/kernel/.cvsignore b/kernel/.cvsignore
deleted file mode 100644 (file)
index ed24c33..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Makefile
-configure
-config.*
-*.cache
-.deps
-.*.cmd
-*.mod.c
-*.ko
-*.s
-.tmp_versions
-.*.d
-*.symvers
diff --git a/kernel/Makefile.in b/kernel/Makefile.in
deleted file mode 100644 (file)
index e26c700..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# Makefile.in for kernel module
-
-SHELL = /bin/sh
-INSTALL = @INSTALL@
-mkdir_p = mkdir -p
-VERSION = @PACKAGE_VERSION@
-
-DISTFILES = Makefile.in configure.ac configure config.h.in ../install-sh \
-       dev.c dir.c file.c inode.c fuse_i.h fuse_kernel.h control.c
-
-fusemoduledir = @kmoduledir@/kernel/fs/fuse
-
-fusemodule := fuse.ko
-
-all: all-@ENABLE_FUSE_MODULE@
-install: install-@ENABLE_FUSE_MODULE@
-uninstall: uninstall-@ENABLE_FUSE_MODULE@
-
-all-n:
-install-n:
-uninstall-n:
-
-all-y: all-spec
-
-install-y: all
-       $(mkdir_p) $(DESTDIR)$(fusemoduledir)
-       $(INSTALL) -m 644 $(fusemodule) $(DESTDIR)$(fusemoduledir)/$(fusemodule)
-       -/sbin/depmod -a
-
-uninstall-y:
-       rm -f $(DESTDIR)$(fusemoduledir)/$(fusemodule)
-       -/sbin/depmod -a
-
-clean:
-       -rm -f $(fusemodule) *.o .*.cmd *.mod.c *.ko *.s */*.o
-
-distclean: clean
-       rm -f Makefile
-       rm -f config.h config.log config.status config.cache
-       rm -rf .tmp_versions
-
-maintainer-clean: distclean
-
-distdir: $(DISTFILES)
-       cp -p $(DISTFILES) $(distdir)
-
-EXTRA_CFLAGS += -DFUSE_VERSION=\"$(VERSION)\"
-
-obj-m := fuse.o
-fuse-objs := dev.o dir.o file.o inode.o control.o
-
-all-spec:
-       $(MAKE) -C @kernelsrc@ SUBDIRS=`pwd` @KERNELMAKE_PARAMS@ modules
diff --git a/kernel/configure.ac b/kernel/configure.ac
deleted file mode 100644 (file)
index fb42264..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-AC_INIT(fuse-kernel, 2.8.0-pre0)
-AC_CONFIG_HEADERS([config.h])
-
-AC_PROG_INSTALL
-
-runver=`uname -r`
-bad_kernel_version=no
-ENABLE_FUSE_MODULE=y
-KERNELCFLAGS=
-
-kernelsrc=
-kernelbuild=
-AC_ARG_WITH(kernel,
-       [  --with-kernel=PATH      Specify location of kernel source ],
-       [kernelsrc="$withval"; kernelbuild="$withval"])
-AC_ARG_WITH(kernel-build,
-       [  --with-kernel-build=PATH Specify location of kernel build ],
-       [kernelbuild="$withval"])
-AC_ARG_ENABLE(kernel-module,
-       [  --enable-kernel-module  Compile kernel module ])
-
-if test -z "$enable_kernel_module" -a -z "$kernelbuild" && echo "$runver" | grep -q "^2.6"; then
-       checkmodule=no
-       AC_MSG_CHECKING([if FUSE is loaded as a module])
-       if cat /proc/modules | grep -q "^fuse "; then
-               AC_MSG_RESULT([yes])
-               checkmodule=yes
-       else
-               AC_MSG_RESULT([no])
-               AC_MSG_CHECKING([if FUSE module is built into the kernel])
-               if test -e /sys/class/misc/fuse; then
-                       AC_MSG_RESULT([yes])
-                       ENABLE_FUSE_MODULE=n
-               else
-                       AC_MSG_RESULT([no])
-                       checkmodule=yes
-               fi
-       fi
-       if test "$checkmodule" = yes; then
-               AC_MSG_CHECKING([if FUSE module is from official kernel])
-               if test ! -f /lib/modules/${runver}/kernel/fs/fuse/fuse.ko; then
-                       AC_MSG_RESULT([no])
-               elif fgrep -q "fuse distribution version: " /lib/modules/${runver}/kernel/fs/fuse/fuse.ko 2> /dev/null; then
-                       AC_MSG_RESULT([no])
-               else
-                       AC_MSG_RESULT([yes])
-                       ENABLE_FUSE_MODULE=n
-               fi
-       fi
-fi
-
-if test "$ENABLE_FUSE_MODULE" = y; then
-       AC_MSG_CHECKING([kernel source directory])
-       if test -z "$kernelsrc"; then
-               kernelbuild=
-               sourcelink=/lib/modules/${runver}/source
-               buildlink=/lib/modules/${runver}/build
-
-               if test -e $sourcelink; then
-                       kernelsrc=`(cd $sourcelink; /bin/pwd)`
-               fi
-               if test -e $buildlink; then
-                       kernelbuild=`(cd $buildlink; /bin/pwd)`
-               fi
-               if test -z "$kernelsrc"; then
-                       kernelsrc=$kernelbuild
-               fi
-               if test -z "$kernelsrc" -o -z "$kernelbuild"; then
-                       AC_MSG_RESULT([Not found])
-                       AC_MSG_ERROR([
-       *** Please specify the location of the kernel source with
-       *** the '--with-kernel=SRCDIR' option])
-               fi
-       fi
-       AC_MSG_RESULT([$kernelsrc])
-       AC_MSG_CHECKING([kernel build directory])
-       AC_MSG_RESULT([$kernelbuild])
-
-       AC_MSG_CHECKING([kernel source version])
-       if test -r $kernelbuild/include/linux/version.h && fgrep -q UTS_RELEASE $kernelbuild/include/linux/version.h; then
-               kernsrcver=`(echo "#include <linux/version.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelbuild/include | grep "^kernsrcver=" | cut -d \" -f 2`
-       elif test -r $kernelbuild/include/linux/utsrelease.h && fgrep -q UTS_RELEASE $kernelbuild/include/linux/utsrelease.h; then
-               kernsrcver=`(echo "#include <linux/utsrelease.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelbuild/include | grep "^kernsrcver=" | cut -d \" -f 2`
-       fi
-       if test -z "$kernsrcver"; then
-               AC_MSG_RESULT([Not found])
-               AC_MSG_ERROR([
-       *** Cannot determine the version of the linux kernel source. Please
-       *** prepare the kernel before running this script])
-       fi
-       AC_MSG_RESULT([$kernsrcver])
-       kmoduledir=${INSTALL_MOD_PATH}/lib/modules/$kernsrcver
-       AC_SUBST(kernelsrc)
-       AC_SUBST(kmoduledir)
-
-       if echo "$kernsrcver" | egrep -q ["^(2.4|2.6.[0-8]([^0-9]|\$))"]; then
-               bad_kernel_version=yes
-               AC_MSG_NOTICE([
-NOTE:    Disabled building the kernel module, because this release only
-NOTE:    supports Linux versions 2.6.9 or later.  You can use the kernel
-NOTE:    module from an earlier FUSE release with the library from this
-NOTE:    release.])
-       else
-               fuse_configured=no
-               kernel_autoconf=$kernelbuild/include/linux/autoconf.h
-               AC_MSG_CHECKING([if FUSE is configured in the kernel])
-               if test -f $kernel_autoconf; then
-                       if grep -q "^#define CONFIG_FUSE_FS 1" $kernel_autoconf || grep -q "^#define CONFIG_FUSE_FS_MODULE 1" $kernel_autoconf; then
-                               fuse_configured=yes
-                       fi
-               fi
-               AC_MSG_RESULT([$fuse_configured])
-               if test -z "$enable_kernel_module" -a "$fuse_configured" = yes; then
-                       ENABLE_FUSE_MODULE=n
-               fi
-       fi
-fi
-
-if test "$ENABLE_FUSE_MODULE" = n; then
-       AC_MSG_NOTICE([
-NOTE:     Detected that FUSE is already present in the kernel, so
-NOTE:     building of kernel module is disabled.  To force building
-NOTE:     of kernel module use the '--enable-kernel-module' option.])
-fi
-
-if test "$enable_kernel_module" = no; then
-       ENABLE_FUSE_MODULE=n
-fi
-if test "$bad_kernel_version" = yes; then
-       ENABLE_FUSE_MODULE=n
-fi
-
-AC_SUBST(ENABLE_FUSE_MODULE)
-
-if test "$ENABLE_FUSE_MODULE" = y; then
-       AC_MSG_CHECKING([if kernel defines kzalloc function])
-       if egrep -qw "kzalloc" $kernelsrc/include/linux/slab.h; then
-               AC_DEFINE(HAVE_KZALLOC, 1, [kzalloc() is defined])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-
-       AC_MSG_CHECKING([if kernel defines fs_subsys])
-       if egrep -qw "fs_subsys" $kernelsrc/include/linux/fs.h; then
-               AC_DEFINE(HAVE_FS_SUBSYS, 1, [fs_subsys is defined])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-
-       AC_MSG_CHECKING([whether lookup_instantiate_filp is defined])
-       if test -f $kernelsrc/include/linux/namei.h && egrep -q "lookup_instantiate_filp" $kernelsrc/include/linux/namei.h; then
-               AC_DEFINE(HAVE_LOOKUP_INSTANTIATE_FILP, 1, [lookup_instantiate_filp() is defined])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-
-       AC_MSG_CHECKING([if umount_begin is passed a vfsmount])
-       if egrep -q "\(\*umount_begin\) *\(struct vfsmount \*" $kernelsrc/include/linux/fs.h; then
-               AC_DEFINE(UMOUNT_BEGIN_VFSMOUNT, 1, [umount_begin is passed a vfsmount])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-
-       AC_MSG_CHECKING([if inode has i_blksize field])
-       if egrep -qw "i_blksize" $kernelsrc/include/linux/fs.h; then
-               AC_DEFINE(HAVE_I_BLKSIZE, 1, [inode has i_blksize field])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       AC_MSG_CHECKING([if inode has i_private field])
-       if egrep -qw "i_private" $kernelsrc/include/linux/fs.h; then
-               AC_DEFINE(HAVE_I_PRIVATE, 1, [inode has i_private field])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       AC_MSG_CHECKING([if inode has i_mutex field ])
-       if egrep -qw "i_mutex" $kernelsrc/include/linux/fs.h; then
-               AC_DEFINE(HAVE_I_MUTEX, 1, [inode has i_mutex field])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       AC_MSG_CHECKING([if kernel has mutex.h ])
-       if test -f $kernelsrc/include/linux/mutex.h; then
-               AC_DEFINE(HAVE_MUTEX_H, 1, [kernel has mutex.h])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       AC_MSG_CHECKING([if kernel has exportfs.h ])
-       if test -f $kernelsrc/include/linux/exportfs.h; then
-               AC_DEFINE(HAVE_EXPORTFS_H, 1, [kernel has exportfs.h])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-       AC_MSG_CHECKING([if kernel has BLOCK option ])
-       if test -f $kernelsrc/block/Kconfig && egrep -q "config *BLOCK" $kernelsrc/block/Kconfig; then
-               AC_DEFINE(HAVE_CONFIG_BLOCK, 1, [kernel has BLOCK option])
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-       fi
-
-       isuml=no
-       KERNELMAKE_PARAMS=
-       KERNELCPPFLAGS=
-       AC_MSG_CHECKING([if this is user mode linux])
-       if test -f $kernelbuild/include/linux/autoconf.h && egrep -q "^#define CONFIG_(USERMODE|UML) 1" $kernelbuild/include/linux/autoconf.h; then
-               isuml=yes
-               KERNELMAKE_PARAMS="ARCH=um"
-               KERNELCPPFLAGS="-D__arch_um__ -DSUBARCH=\\\"i386\\\" -D_LARGEFILE64_SOURCE -I${kernelsrc}/arch/um/include -Derrno=kernel_errno -I${kernelsrc}/arch/um/kernel/tt/include -I${kernelsrc}/arch/um/kernel/skas/include"
-       fi
-       AC_MSG_RESULT([$isuml])
-       if test "$kernelbuild" != "$kernelsrc"; then
-               KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$kernelbuild"
-       fi
-       AC_SUBST(KERNELMAKE_PARAMS)
-       AC_SUBST(KERNELCPPFLAGS)
-       AC_SUBST(KERNELCFLAGS)
-fi
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
diff --git a/kernel/control.c b/kernel/control.c
deleted file mode 100644 (file)
index 5ffe6ba..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#include "fuse_i.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#define FUSE_CTL_SUPER_MAGIC 0x65735543
-#ifndef HAVE_I_PRIVATE
-#define i_private u.generic_ip
-#endif
-
-/*
- * This is non-NULL when the single instance of the control filesystem
- * exists.  Protected by fuse_mutex
- */
-static struct super_block *fuse_control_sb;
-
-static struct fuse_conn *fuse_ctl_file_conn_get(struct file *file)
-{
-       struct fuse_conn *fc;
-       mutex_lock(&fuse_mutex);
-       fc = file->f_dentry->d_inode->i_private;
-       if (fc)
-               fc = fuse_conn_get(fc);
-       mutex_unlock(&fuse_mutex);
-       return fc;
-}
-
-static ssize_t fuse_conn_abort_write(struct file *file, const char __user *buf,
-                                    size_t count, loff_t *ppos)
-{
-       struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
-       if (fc) {
-               fuse_abort_conn(fc);
-               fuse_conn_put(fc);
-       }
-       return count;
-}
-
-static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf,
-                                     size_t len, loff_t *ppos)
-{
-       char tmp[32];
-       size_t size;
-
-       if (!*ppos) {
-               struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
-               if (!fc)
-                       return 0;
-
-               file->private_data=(void *)(long)atomic_read(&fc->num_waiting);
-               fuse_conn_put(fc);
-       }
-       size = sprintf(tmp, "%ld\n", (long)file->private_data);
-       return simple_read_from_buffer(buf, len, ppos, tmp, size);
-}
-
-static struct file_operations fuse_ctl_abort_ops = {
-       .open = nonseekable_open,
-       .write = fuse_conn_abort_write,
-};
-
-static struct file_operations fuse_ctl_waiting_ops = {
-       .open = nonseekable_open,
-       .read = fuse_conn_waiting_read,
-};
-
-#ifndef KERNEL_2_6_10_PLUS
-struct dentry *d_alloc_name(struct dentry *parent, const char *name)
-{
-       struct qstr q;
-
-       q.name = (const unsigned char *) name;
-       q.len = strlen(name);
-       q.hash = full_name_hash(q.name, q.len);
-       return d_alloc(parent, &q);
-}
-#endif
-static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
-                                         struct fuse_conn *fc,
-                                         const char *name,
-                                         int mode, int nlink,
-#ifdef KERNEL_2_6_21_PLUS
-                                         const struct inode_operations *iop,
-#else
-                                         struct inode_operations *iop,
-#endif
-#ifdef KERNEL_2_6_17_PLUS
-                                         const struct file_operations *fop
-#else
-                                         struct file_operations *fop
-#endif
-)
-{
-       struct dentry *dentry;
-       struct inode *inode;
-
-       BUG_ON(fc->ctl_ndents >= FUSE_CTL_NUM_DENTRIES);
-       dentry = d_alloc_name(parent, name);
-       if (!dentry)
-               return NULL;
-
-       fc->ctl_dentry[fc->ctl_ndents++] = dentry;
-       inode = new_inode(fuse_control_sb);
-       if (!inode)
-               return NULL;
-
-       inode->i_mode = mode;
-       inode->i_uid = fc->user_id;
-       inode->i_gid = fc->group_id;
-       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-       /* setting ->i_op to NULL is not allowed */
-       if (iop)
-               inode->i_op = iop;
-       inode->i_fop = fop;
-       inode->i_nlink = nlink;
-       inode->i_private = fc;
-       d_add(dentry, inode);
-       return dentry;
-}
-
-/*
- * Add a connection to the control filesystem (if it exists).  Caller
- * must hold fuse_mutex
- */
-int fuse_ctl_add_conn(struct fuse_conn *fc)
-{
-       struct dentry *parent;
-       char name[32];
-
-       if (!fuse_control_sb)
-               return 0;
-
-       parent = fuse_control_sb->s_root;
-       inc_nlink(parent->d_inode);
-       sprintf(name, "%llu", (unsigned long long) fc->id);
-       parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2,
-                                    &simple_dir_inode_operations,
-                                    &simple_dir_operations);
-       if (!parent)
-               goto err;
-
-       if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1,
-                               NULL, &fuse_ctl_waiting_ops) ||
-           !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1,
-                                NULL, &fuse_ctl_abort_ops))
-               goto err;
-
-       return 0;
-
- err:
-       fuse_ctl_remove_conn(fc);
-       return -ENOMEM;
-}
-
-/*
- * Remove a connection from the control filesystem (if it exists).
- * Caller must hold fuse_mutex
- */
-void fuse_ctl_remove_conn(struct fuse_conn *fc)
-{
-       int i;
-
-       if (!fuse_control_sb)
-               return;
-
-       for (i = fc->ctl_ndents - 1; i >= 0; i--) {
-               struct dentry *dentry = fc->ctl_dentry[i];
-               dentry->d_inode->i_private = NULL;
-               d_drop(dentry);
-               dput(dentry);
-       }
-       fuse_control_sb->s_root->d_inode->i_nlink--;
-}
-
-static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
-{
-       struct tree_descr empty_descr = {""};
-       struct fuse_conn *fc;
-       int err;
-
-       err = simple_fill_super(sb, FUSE_CTL_SUPER_MAGIC, &empty_descr);
-       if (err)
-               return err;
-
-       mutex_lock(&fuse_mutex);
-       BUG_ON(fuse_control_sb);
-       fuse_control_sb = sb;
-       list_for_each_entry(fc, &fuse_conn_list, entry) {
-               err = fuse_ctl_add_conn(fc);
-               if (err) {
-                       fuse_control_sb = NULL;
-                       mutex_unlock(&fuse_mutex);
-                       return err;
-               }
-       }
-       mutex_unlock(&fuse_mutex);
-
-       return 0;
-}
-
-#ifdef KERNEL_2_6_18_PLUS
-static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags,
-                       const char *dev_name, void *raw_data,
-                       struct vfsmount *mnt)
-{
-       return get_sb_single(fs_type, flags, raw_data,
-                               fuse_ctl_fill_super, mnt);
-}
-#else
-static struct super_block *fuse_ctl_get_sb(struct file_system_type *fs_type,
-                                          int flags, const char *dev_name,
-                                          void *raw_data)
-{
-       return get_sb_single(fs_type, flags, raw_data, fuse_ctl_fill_super);
-}
-#endif
-
-static void fuse_ctl_kill_sb(struct super_block *sb)
-{
-       struct fuse_conn *fc;
-
-       mutex_lock(&fuse_mutex);
-       fuse_control_sb = NULL;
-       list_for_each_entry(fc, &fuse_conn_list, entry)
-               fc->ctl_ndents = 0;
-       mutex_unlock(&fuse_mutex);
-
-       kill_litter_super(sb);
-}
-
-static struct file_system_type fuse_ctl_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "fusectl",
-       .get_sb         = fuse_ctl_get_sb,
-       .kill_sb        = fuse_ctl_kill_sb,
-};
-
-int __init fuse_ctl_init(void)
-{
-       return register_filesystem(&fuse_ctl_fs_type);
-}
-
-void fuse_ctl_cleanup(void)
-{
-       unregister_filesystem(&fuse_ctl_fs_type);
-}
diff --git a/kernel/dev.c b/kernel/dev.c
deleted file mode 100644 (file)
index f8b7f3a..0000000
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#include "fuse_i.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/uio.h>
-#include <linux/miscdevice.h>
-#include <linux/pagemap.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-
-#ifdef MODULE_ALIAS_MISCDEV
-MODULE_ALIAS_MISCDEV(FUSE_MINOR);
-#endif
-
-static struct kmem_cache *fuse_req_cachep;
-
-static struct fuse_conn *fuse_get_conn(struct file *file)
-{
-       /*
-        * Lockless access is OK, because file->private data is set
-        * once during mount and is valid until the file is released.
-        */
-       return file->private_data;
-}
-
-static void fuse_request_init(struct fuse_req *req)
-{
-       memset(req, 0, sizeof(*req));
-       INIT_LIST_HEAD(&req->list);
-       INIT_LIST_HEAD(&req->intr_entry);
-       init_waitqueue_head(&req->waitq);
-       atomic_set(&req->count, 1);
-}
-
-struct fuse_req *fuse_request_alloc(void)
-{
-       struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL);
-       if (req)
-               fuse_request_init(req);
-       return req;
-}
-
-void fuse_request_free(struct fuse_req *req)
-{
-       kmem_cache_free(fuse_req_cachep, req);
-}
-
-static void block_sigs(sigset_t *oldset)
-{
-       sigset_t mask;
-
-       siginitsetinv(&mask, sigmask(SIGKILL));
-       sigprocmask(SIG_BLOCK, &mask, oldset);
-}
-
-static void restore_sigs(sigset_t *oldset)
-{
-       sigprocmask(SIG_SETMASK, oldset, NULL);
-}
-
-static void __fuse_get_request(struct fuse_req *req)
-{
-       atomic_inc(&req->count);
-}
-
-/* Must be called with > 1 refcount */
-static void __fuse_put_request(struct fuse_req *req)
-{
-       BUG_ON(atomic_read(&req->count) < 2);
-       atomic_dec(&req->count);
-}
-
-static void fuse_req_init_context(struct fuse_req *req)
-{
-       req->in.h.uid = current->fsuid;
-       req->in.h.gid = current->fsgid;
-       req->in.h.pid = current->pid;
-}
-
-struct fuse_req *fuse_get_req(struct fuse_conn *fc)
-{
-       struct fuse_req *req;
-       sigset_t oldset;
-       int intr;
-       int err;
-
-       atomic_inc(&fc->num_waiting);
-       block_sigs(&oldset);
-       intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked);
-       restore_sigs(&oldset);
-       err = -EINTR;
-       if (intr)
-               goto out;
-
-       err = -ENOTCONN;
-       if (!fc->connected)
-               goto out;
-
-       req = fuse_request_alloc();
-       err = -ENOMEM;
-       if (!req)
-               goto out;
-
-       fuse_req_init_context(req);
-       req->waiting = 1;
-       return req;
-
- out:
-       atomic_dec(&fc->num_waiting);
-       return ERR_PTR(err);
-}
-
-/*
- * Return request in fuse_file->reserved_req.  However that may
- * currently be in use.  If that is the case, wait for it to become
- * available.
- */
-static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
-                                        struct file *file)
-{
-       struct fuse_req *req = NULL;
-       struct fuse_file *ff = file->private_data;
-
-       do {
-               wait_event(fc->reserved_req_waitq, ff->reserved_req);
-               spin_lock(&fc->lock);
-               if (ff->reserved_req) {
-                       req = ff->reserved_req;
-                       ff->reserved_req = NULL;
-                       get_file(file);
-                       req->stolen_file = file;
-               }
-               spin_unlock(&fc->lock);
-       } while (!req);
-
-       return req;
-}
-
-/*
- * Put stolen request back into fuse_file->reserved_req
- */
-static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
-{
-       struct file *file = req->stolen_file;
-       struct fuse_file *ff = file->private_data;
-
-       spin_lock(&fc->lock);
-       fuse_request_init(req);
-       BUG_ON(ff->reserved_req);
-       ff->reserved_req = req;
-       wake_up_all(&fc->reserved_req_waitq);
-       spin_unlock(&fc->lock);
-       fput(file);
-}
-
-/*
- * Gets a requests for a file operation, always succeeds
- *
- * This is used for sending the FLUSH request, which must get to
- * userspace, due to POSIX locks which may need to be unlocked.
- *
- * If allocation fails due to OOM, use the reserved request in
- * fuse_file.
- *
- * This is very unlikely to deadlock accidentally, since the
- * filesystem should not have it's own file open.  If deadlock is
- * intentional, it can still be broken by "aborting" the filesystem.
- */
-struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file)
-{
-       struct fuse_req *req;
-
-       atomic_inc(&fc->num_waiting);
-       wait_event(fc->blocked_waitq, !fc->blocked);
-       req = fuse_request_alloc();
-       if (!req)
-               req = get_reserved_req(fc, file);
-
-       fuse_req_init_context(req);
-       req->waiting = 1;
-       return req;
-}
-
-void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
-{
-       if (atomic_dec_and_test(&req->count)) {
-               if (req->waiting)
-                       atomic_dec(&fc->num_waiting);
-
-               if (req->stolen_file)
-                       put_reserved_req(fc, req);
-               else
-                       fuse_request_free(req);
-       }
-}
-
-/*
- * This function is called when a request is finished.  Either a reply
- * has arrived or it was aborted (and not yet sent) or some error
- * occurred during communication with userspace, or the device file
- * was closed.  The requester thread is woken up (if still waiting),
- * the 'end' callback is called if given, else the reference to the
- * request is released
- *
- * Called with fc->lock, unlocks it
- */
-static void request_end(struct fuse_conn *fc, struct fuse_req *req)
-{
-       void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
-       req->end = NULL;
-       list_del(&req->list);
-       list_del(&req->intr_entry);
-       req->state = FUSE_REQ_FINISHED;
-       if (req->background) {
-               if (fc->num_background == FUSE_MAX_BACKGROUND) {
-                       fc->blocked = 0;
-                       wake_up_all(&fc->blocked_waitq);
-               }
-               fc->num_background--;
-       }
-       spin_unlock(&fc->lock);
-       dput(req->dentry);
-       mntput(req->vfsmount);
-       if (req->file)
-               fput(req->file);
-       wake_up(&req->waitq);
-       if (end)
-               end(fc, req);
-       else
-               fuse_put_request(fc, req);
-}
-
-static void wait_answer_interruptible(struct fuse_conn *fc,
-                                     struct fuse_req *req)
-{
-       if (signal_pending(current))
-               return;
-
-       spin_unlock(&fc->lock);
-       wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED);
-       spin_lock(&fc->lock);
-}
-
-static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req)
-{
-       list_add_tail(&req->intr_entry, &fc->interrupts);
-       wake_up(&fc->waitq);
-       kill_fasync(&fc->fasync, SIGIO, POLL_IN);
-}
-
-/* Called with fc->lock held.  Releases, and then reacquires it. */
-static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
-{
-       if (!fc->no_interrupt) {
-               /* Any signal may interrupt this */
-               wait_answer_interruptible(fc, req);
-
-               if (req->aborted)
-                       goto aborted;
-               if (req->state == FUSE_REQ_FINISHED)
-                       return;
-
-               req->interrupted = 1;
-               if (req->state == FUSE_REQ_SENT)
-                       queue_interrupt(fc, req);
-       }
-
-       if (req->force) {
-               spin_unlock(&fc->lock);
-               wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
-               spin_lock(&fc->lock);
-       } else {
-               sigset_t oldset;
-
-               /* Only fatal signals may interrupt this */
-               block_sigs(&oldset);
-               wait_answer_interruptible(fc, req);
-               restore_sigs(&oldset);
-       }
-
-       if (req->aborted)
-               goto aborted;
-       if (req->state == FUSE_REQ_FINISHED)
-               return;
-
-       req->out.h.error = -EINTR;
-       req->aborted = 1;
-
- aborted:
-       if (req->locked) {
-               /* This is uninterruptible sleep, because data is
-                  being copied to/from the buffers of req.  During
-                  locked state, there mustn't be any filesystem
-                  operation (e.g. page fault), since that could lead
-                  to deadlock */
-               spin_unlock(&fc->lock);
-               wait_event(req->waitq, !req->locked);
-               spin_lock(&fc->lock);
-       }
-       if (req->state == FUSE_REQ_PENDING) {
-               list_del(&req->list);
-               __fuse_put_request(req);
-       } else if (req->state == FUSE_REQ_SENT) {
-               spin_unlock(&fc->lock);
-               wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
-               spin_lock(&fc->lock);
-       }
-}
-
-static unsigned len_args(unsigned numargs, struct fuse_arg *args)
-{
-       unsigned nbytes = 0;
-       unsigned i;
-
-       for (i = 0; i < numargs; i++)
-               nbytes += args[i].size;
-
-       return nbytes;
-}
-
-static u64 fuse_get_unique(struct fuse_conn *fc)
- {
-       fc->reqctr++;
-       /* zero is special */
-       if (fc->reqctr == 0)
-               fc->reqctr = 1;
-
-       return fc->reqctr;
-}
-
-static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
-{
-       req->in.h.unique = fuse_get_unique(fc);
-       req->in.h.len = sizeof(struct fuse_in_header) +
-               len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
-       list_add_tail(&req->list, &fc->pending);
-       req->state = FUSE_REQ_PENDING;
-       if (!req->waiting) {
-               req->waiting = 1;
-               atomic_inc(&fc->num_waiting);
-       }
-       wake_up(&fc->waitq);
-       kill_fasync(&fc->fasync, SIGIO, POLL_IN);
-}
-
-void request_send(struct fuse_conn *fc, struct fuse_req *req)
-{
-       req->isreply = 1;
-       spin_lock(&fc->lock);
-       if (!fc->connected)
-               req->out.h.error = -ENOTCONN;
-       else if (fc->conn_error)
-               req->out.h.error = -ECONNREFUSED;
-       else {
-               queue_request(fc, req);
-               /* acquire extra reference, since request is still needed
-                  after request_end() */
-               __fuse_get_request(req);
-
-               request_wait_answer(fc, req);
-       }
-       spin_unlock(&fc->lock);
-}
-
-static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
-{
-       spin_lock(&fc->lock);
-       if (fc->connected) {
-               req->background = 1;
-               fc->num_background++;
-               if (fc->num_background == FUSE_MAX_BACKGROUND)
-                       fc->blocked = 1;
-
-               queue_request(fc, req);
-               spin_unlock(&fc->lock);
-       } else {
-               req->out.h.error = -ENOTCONN;
-               request_end(fc, req);
-       }
-}
-
-void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
-{
-       req->isreply = 0;
-       request_send_nowait(fc, req);
-}
-
-void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
-{
-       req->isreply = 1;
-       request_send_nowait(fc, req);
-}
-
-/*
- * Lock the request.  Up to the next unlock_request() there mustn't be
- * anything that could cause a page-fault.  If the request was already
- * aborted bail out.
- */
-static int lock_request(struct fuse_conn *fc, struct fuse_req *req)
-{
-       int err = 0;
-       if (req) {
-               spin_lock(&fc->lock);
-               if (req->aborted)
-                       err = -ENOENT;
-               else
-                       req->locked = 1;
-               spin_unlock(&fc->lock);
-       }
-       return err;
-}
-
-/*
- * Unlock request.  If it was aborted during being locked, the
- * requester thread is currently waiting for it to be unlocked, so
- * wake it up.
- */
-static void unlock_request(struct fuse_conn *fc, struct fuse_req *req)
-{
-       if (req) {
-               spin_lock(&fc->lock);
-               req->locked = 0;
-               if (req->aborted)
-                       wake_up(&req->waitq);
-               spin_unlock(&fc->lock);
-       }
-}
-
-struct fuse_copy_state {
-       struct fuse_conn *fc;
-       int write;
-       struct fuse_req *req;
-       const struct iovec *iov;
-       unsigned long nr_segs;
-       unsigned long seglen;
-       unsigned long addr;
-       struct page *pg;
-       void *mapaddr;
-       void *buf;
-       unsigned len;
-};
-
-static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc,
-                          int write, struct fuse_req *req,
-                          const struct iovec *iov, unsigned long nr_segs)
-{
-       memset(cs, 0, sizeof(*cs));
-       cs->fc = fc;
-       cs->write = write;
-       cs->req = req;
-       cs->iov = iov;
-       cs->nr_segs = nr_segs;
-}
-
-/* Unmap and put previous page of userspace buffer */
-static void fuse_copy_finish(struct fuse_copy_state *cs)
-{
-       if (cs->mapaddr) {
-               kunmap_atomic(cs->mapaddr, KM_USER0);
-               if (cs->write) {
-                       flush_dcache_page(cs->pg);
-                       set_page_dirty_lock(cs->pg);
-               }
-               put_page(cs->pg);
-               cs->mapaddr = NULL;
-       }
-}
-
-/*
- * Get another pagefull of userspace buffer, and map it to kernel
- * address space, and lock request
- */
-static int fuse_copy_fill(struct fuse_copy_state *cs)
-{
-       unsigned long offset;
-       int err;
-#ifdef DCACHE_BUG
-       struct vm_area_struct *vma;
-#endif
-
-       unlock_request(cs->fc, cs->req);
-       fuse_copy_finish(cs);
-       if (!cs->seglen) {
-               BUG_ON(!cs->nr_segs);
-               cs->seglen = cs->iov[0].iov_len;
-               cs->addr = (unsigned long) cs->iov[0].iov_base;
-               cs->iov ++;
-               cs->nr_segs --;
-       }
-       down_read(&current->mm->mmap_sem);
-#ifndef DCACHE_BUG
-       err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
-                            &cs->pg, NULL);
-#else
-       err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
-                            &cs->pg, &vma);
-#endif
-       up_read(&current->mm->mmap_sem);
-       if (err < 0)
-               return err;
-       BUG_ON(err != 1);
-       offset = cs->addr % PAGE_SIZE;
-       cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
-#ifdef DCACHE_BUG
-       flush_cache_page(vma, cs->addr, page_to_pfn(cs->pg));
-#endif
-       cs->buf = cs->mapaddr + offset;
-       cs->len = min(PAGE_SIZE - offset, cs->seglen);
-       cs->seglen -= cs->len;
-       cs->addr += cs->len;
-
-       return lock_request(cs->fc, cs->req);
-}
-
-/* Do as much copy to/from userspace buffer as we can */
-static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
-{
-       unsigned ncpy = min(*size, cs->len);
-       if (val) {
-               if (cs->write)
-                       memcpy(cs->buf, *val, ncpy);
-               else
-                       memcpy(*val, cs->buf, ncpy);
-               *val += ncpy;
-       }
-       *size -= ncpy;
-       cs->len -= ncpy;
-       cs->buf += ncpy;
-       return ncpy;
-}
-
-/*
- * Copy a page in the request to/from the userspace buffer.  Must be
- * done atomically
- */
-static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
-                         unsigned offset, unsigned count, int zeroing)
-{
-       if (page && zeroing && count < PAGE_SIZE) {
-               void *mapaddr = kmap_atomic(page, KM_USER1);
-               memset(mapaddr, 0, PAGE_SIZE);
-               kunmap_atomic(mapaddr, KM_USER1);
-       }
-       while (count) {
-               int err;
-               if (!cs->len && (err = fuse_copy_fill(cs)))
-                       return err;
-               if (page) {
-                       void *mapaddr = kmap_atomic(page, KM_USER1);
-                       void *buf = mapaddr + offset;
-                       offset += fuse_copy_do(cs, &buf, &count);
-                       kunmap_atomic(mapaddr, KM_USER1);
-               } else
-                       offset += fuse_copy_do(cs, NULL, &count);
-       }
-       if (page && !cs->write)
-               flush_dcache_page(page);
-       return 0;
-}
-
-/* Copy pages in the request to/from userspace buffer */
-static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
-                          int zeroing)
-{
-       unsigned i;
-       struct fuse_req *req = cs->req;
-       unsigned offset = req->page_offset;
-       unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
-
-       for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
-               struct page *page = req->pages[i];
-               int err = fuse_copy_page(cs, page, offset, count, zeroing);
-               if (err)
-                       return err;
-
-               nbytes -= count;
-               count = min(nbytes, (unsigned) PAGE_SIZE);
-               offset = 0;
-       }
-       return 0;
-}
-
-/* Copy a single argument in the request to/from userspace buffer */
-static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
-{
-       while (size) {
-               int err;
-               if (!cs->len && (err = fuse_copy_fill(cs)))
-                       return err;
-               fuse_copy_do(cs, &val, &size);
-       }
-       return 0;
-}
-
-/* Copy request arguments to/from userspace buffer */
-static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
-                         unsigned argpages, struct fuse_arg *args,
-                         int zeroing)
-{
-       int err = 0;
-       unsigned i;
-
-       for (i = 0; !err && i < numargs; i++)  {
-               struct fuse_arg *arg = &args[i];
-               if (i == numargs - 1 && argpages)
-                       err = fuse_copy_pages(cs, arg->size, zeroing);
-               else
-                       err = fuse_copy_one(cs, arg->value, arg->size);
-       }
-       return err;
-}
-
-static int request_pending(struct fuse_conn *fc)
-{
-       return !list_empty(&fc->pending) || !list_empty(&fc->interrupts);
-}
-
-/* Wait until a request is available on the pending list */
-static void request_wait(struct fuse_conn *fc)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       add_wait_queue_exclusive(&fc->waitq, &wait);
-       while (fc->connected && !request_pending(fc)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (signal_pending(current))
-                       break;
-
-               spin_unlock(&fc->lock);
-               schedule();
-               spin_lock(&fc->lock);
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&fc->waitq, &wait);
-}
-
-/*
- * Transfer an interrupt request to userspace
- *
- * Unlike other requests this is assembled on demand, without a need
- * to allocate a separate fuse_req structure.
- *
- * Called with fc->lock held, releases it
- */
-static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
-                              const struct iovec *iov, unsigned long nr_segs)
-{
-       struct fuse_copy_state cs;
-       struct fuse_in_header ih;
-       struct fuse_interrupt_in arg;
-       unsigned reqsize = sizeof(ih) + sizeof(arg);
-       int err;
-
-       list_del_init(&req->intr_entry);
-       req->intr_unique = fuse_get_unique(fc);
-       memset(&ih, 0, sizeof(ih));
-       memset(&arg, 0, sizeof(arg));
-       ih.len = reqsize;
-       ih.opcode = FUSE_INTERRUPT;
-       ih.unique = req->intr_unique;
-       arg.unique = req->in.h.unique;
-
-       spin_unlock(&fc->lock);
-       if (iov_length(iov, nr_segs) < reqsize)
-               return -EINVAL;
-
-       fuse_copy_init(&cs, fc, 1, NULL, iov, nr_segs);
-       err = fuse_copy_one(&cs, &ih, sizeof(ih));
-       if (!err)
-               err = fuse_copy_one(&cs, &arg, sizeof(arg));
-       fuse_copy_finish(&cs);
-
-       return err ? err : reqsize;
-}
-
-/*
- * Read a single request into the userspace filesystem's buffer.  This
- * function waits until a request is available, then removes it from
- * the pending list and copies request data to userspace buffer.  If
- * no reply is needed (FORGET) or request has been aborted or there
- * was an error during the copying then it's finished by calling
- * request_end().  Otherwise add it to the processing list, and set
- * the 'sent' flag.
- */
-static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t *off)
-{
-       int err;
-       struct fuse_req *req;
-       struct fuse_in *in;
-       struct fuse_copy_state cs;
-       unsigned reqsize;
-       struct fuse_conn *fc = fuse_get_conn(file);
-       if (!fc)
-               return -EPERM;
-
- restart:
-       spin_lock(&fc->lock);
-       err = -EAGAIN;
-       if ((file->f_flags & O_NONBLOCK) && fc->connected &&
-           !request_pending(fc))
-               goto err_unlock;
-
-       request_wait(fc);
-       err = -ENODEV;
-       if (!fc->connected)
-               goto err_unlock;
-       err = -ERESTARTSYS;
-       if (!request_pending(fc))
-               goto err_unlock;
-
-       if (!list_empty(&fc->interrupts)) {
-               req = list_entry(fc->interrupts.next, struct fuse_req,
-                                intr_entry);
-               return fuse_read_interrupt(fc, req, iov, nr_segs);
-       }
-
-       req = list_entry(fc->pending.next, struct fuse_req, list);
-       req->state = FUSE_REQ_READING;
-       list_move(&req->list, &fc->io);
-
-       in = &req->in;
-       reqsize = in->h.len;
-       /* If request is too large, reply with an error and restart the read */
-       if (iov_length(iov, nr_segs) < reqsize) {
-               req->out.h.error = -EIO;
-               /* SETXATTR is special, since it may contain too large data */
-               if (in->h.opcode == FUSE_SETXATTR)
-                       req->out.h.error = -E2BIG;
-               request_end(fc, req);
-               goto restart;
-       }
-       spin_unlock(&fc->lock);
-       fuse_copy_init(&cs, fc, 1, req, iov, nr_segs);
-       err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
-       if (!err)
-               err = fuse_copy_args(&cs, in->numargs, in->argpages,
-                                    (struct fuse_arg *) in->args, 0);
-       fuse_copy_finish(&cs);
-       spin_lock(&fc->lock);
-       req->locked = 0;
-       if (!err && req->aborted)
-               err = -ENOENT;
-       if (err) {
-               if (!req->aborted)
-                       req->out.h.error = -EIO;
-               request_end(fc, req);
-               return err;
-       }
-       if (!req->isreply)
-               request_end(fc, req);
-       else {
-               req->state = FUSE_REQ_SENT;
-               list_move_tail(&req->list, &fc->processing);
-               if (req->interrupted)
-                       queue_interrupt(fc, req);
-               spin_unlock(&fc->lock);
-       }
-       return reqsize;
-
- err_unlock:
-       spin_unlock(&fc->lock);
-       return err;
-}
-
-#ifndef KERNEL_2_6_19_PLUS
-static ssize_t fuse_dev_read(struct file *file, char __user *buf,
-                            size_t nbytes, loff_t *off)
-{
-       struct iovec iov;
-       iov.iov_len = nbytes;
-       iov.iov_base = buf;
-       return fuse_dev_readv(file, &iov, 1, off);
-}
-#else
-static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
-                            unsigned long nr_segs, loff_t pos)
-{
-       return fuse_dev_readv(iocb->ki_filp, iov, nr_segs, &pos);
-}
-#endif
-
-/* Look up request on processing list by unique ID */
-static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
-{
-       struct list_head *entry;
-
-       list_for_each(entry, &fc->processing) {
-               struct fuse_req *req;
-               req = list_entry(entry, struct fuse_req, list);
-               if (req->in.h.unique == unique || req->intr_unique == unique)
-                       return req;
-       }
-       return NULL;
-}
-
-static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
-                        unsigned nbytes)
-{
-       unsigned reqsize = sizeof(struct fuse_out_header);
-
-       if (out->h.error)
-               return nbytes != reqsize ? -EINVAL : 0;
-
-       reqsize += len_args(out->numargs, out->args);
-
-       if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
-               return -EINVAL;
-       else if (reqsize > nbytes) {
-               struct fuse_arg *lastarg = &out->args[out->numargs-1];
-               unsigned diffsize = reqsize - nbytes;
-               if (diffsize > lastarg->size)
-                       return -EINVAL;
-               lastarg->size -= diffsize;
-       }
-       return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
-                             out->page_zeroing);
-}
-
-/*
- * Write a single reply to a request.  First the header is copied from
- * the write buffer.  The request is then searched on the processing
- * list by the unique ID found in the header.  If found, then remove
- * it from the list and copy the rest of the buffer to the request.
- * The request is finished by calling request_end()
- */
-static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
-                              unsigned long nr_segs, loff_t *off)
-{
-       int err;
-       unsigned nbytes = iov_length(iov, nr_segs);
-       struct fuse_req *req;
-       struct fuse_out_header oh;
-       struct fuse_copy_state cs;
-       struct fuse_conn *fc = fuse_get_conn(file);
-       if (!fc)
-               return -EPERM;
-
-       fuse_copy_init(&cs, fc, 0, NULL, iov, nr_segs);
-       if (nbytes < sizeof(struct fuse_out_header))
-               return -EINVAL;
-
-       err = fuse_copy_one(&cs, &oh, sizeof(oh));
-       if (err)
-               goto err_finish;
-       err = -EINVAL;
-       if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
-           oh.len != nbytes)
-               goto err_finish;
-
-       spin_lock(&fc->lock);
-       err = -ENOENT;
-       if (!fc->connected)
-               goto err_unlock;
-
-       req = request_find(fc, oh.unique);
-       if (!req)
-               goto err_unlock;
-
-       if (req->aborted) {
-               spin_unlock(&fc->lock);
-               fuse_copy_finish(&cs);
-               spin_lock(&fc->lock);
-               request_end(fc, req);
-               return -ENOENT;
-       }
-       /* Is it an interrupt reply? */
-       if (req->intr_unique == oh.unique) {
-               err = -EINVAL;
-               if (nbytes != sizeof(struct fuse_out_header))
-                       goto err_unlock;
-
-               if (oh.error == -ENOSYS)
-                       fc->no_interrupt = 1;
-               else if (oh.error == -EAGAIN)
-                       queue_interrupt(fc, req);
-
-               spin_unlock(&fc->lock);
-               fuse_copy_finish(&cs);
-               return nbytes;
-       }
-
-       req->state = FUSE_REQ_WRITING;
-       list_move(&req->list, &fc->io);
-       req->out.h = oh;
-       req->locked = 1;
-       cs.req = req;
-       spin_unlock(&fc->lock);
-
-       err = copy_out_args(&cs, &req->out, nbytes);
-       fuse_copy_finish(&cs);
-
-       spin_lock(&fc->lock);
-       req->locked = 0;
-       if (!err) {
-               if (req->aborted)
-                       err = -ENOENT;
-       } else if (!req->aborted)
-               req->out.h.error = -EIO;
-       request_end(fc, req);
-
-       return err ? err : nbytes;
-
- err_unlock:
-       spin_unlock(&fc->lock);
- err_finish:
-       fuse_copy_finish(&cs);
-       return err;
-}
-
-#ifndef KERNEL_2_6_19_PLUS
-static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
-                             size_t nbytes, loff_t *off)
-{
-       struct iovec iov;
-       iov.iov_len = nbytes;
-       iov.iov_base = (char __user *) buf;
-       return fuse_dev_writev(file, &iov, 1, off);
-}
-#else
-static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
-{
-       return fuse_dev_writev(iocb->ki_filp, iov, nr_segs, &pos);
-}
-#endif
-
-static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
-{
-       unsigned mask = POLLOUT | POLLWRNORM;
-       struct fuse_conn *fc = fuse_get_conn(file);
-       if (!fc)
-               return POLLERR;
-
-       poll_wait(file, &fc->waitq, wait);
-
-       spin_lock(&fc->lock);
-       if (!fc->connected)
-               mask = POLLERR;
-       else if (request_pending(fc))
-               mask |= POLLIN | POLLRDNORM;
-       spin_unlock(&fc->lock);
-
-       return mask;
-}
-
-/*
- * Abort all requests on the given list (pending or processing)
- *
- * This function releases and reacquires fc->lock
- */
-static void end_requests(struct fuse_conn *fc, struct list_head *head)
-{
-       while (!list_empty(head)) {
-               struct fuse_req *req;
-               req = list_entry(head->next, struct fuse_req, list);
-               req->out.h.error = -ECONNABORTED;
-               request_end(fc, req);
-               spin_lock(&fc->lock);
-       }
-}
-
-/*
- * Abort requests under I/O
- *
- * The requests are set to aborted and finished, and the request
- * waiter is woken up.  This will make request_wait_answer() wait
- * until the request is unlocked and then return.
- *
- * If the request is asynchronous, then the end function needs to be
- * called after waiting for the request to be unlocked (if it was
- * locked).
- */
-static void end_io_requests(struct fuse_conn *fc)
-{
-       while (!list_empty(&fc->io)) {
-               struct fuse_req *req =
-                       list_entry(fc->io.next, struct fuse_req, list);
-               void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
-
-               req->aborted = 1;
-               req->out.h.error = -ECONNABORTED;
-               req->state = FUSE_REQ_FINISHED;
-               list_del_init(&req->list);
-               wake_up(&req->waitq);
-               if (end) {
-                       req->end = NULL;
-                       /* The end function will consume this reference */
-                       __fuse_get_request(req);
-                       spin_unlock(&fc->lock);
-                       wait_event(req->waitq, !req->locked);
-                       end(fc, req);
-                       spin_lock(&fc->lock);
-               }
-       }
-}
-
-/*
- * Abort all requests.
- *
- * Emergency exit in case of a malicious or accidental deadlock, or
- * just a hung filesystem.
- *
- * The same effect is usually achievable through killing the
- * filesystem daemon and all users of the filesystem.  The exception
- * is the combination of an asynchronous request and the tricky
- * deadlock (see Documentation/filesystems/fuse.txt).
- *
- * During the aborting, progression of requests from the pending and
- * processing lists onto the io list, and progression of new requests
- * onto the pending list is prevented by req->connected being false.
- *
- * Progression of requests under I/O to the processing list is
- * prevented by the req->aborted flag being true for these requests.
- * For this reason requests on the io list must be aborted first.
- */
-void fuse_abort_conn(struct fuse_conn *fc)
-{
-       spin_lock(&fc->lock);
-       if (fc->connected) {
-               fc->connected = 0;
-               fc->blocked = 0;
-               end_io_requests(fc);
-               end_requests(fc, &fc->pending);
-               end_requests(fc, &fc->processing);
-               wake_up_all(&fc->waitq);
-               wake_up_all(&fc->blocked_waitq);
-               kill_fasync(&fc->fasync, SIGIO, POLL_IN);
-       }
-       spin_unlock(&fc->lock);
-}
-
-static int fuse_dev_release(struct inode *inode, struct file *file)
-{
-       struct fuse_conn *fc = fuse_get_conn(file);
-       if (fc) {
-               spin_lock(&fc->lock);
-               fc->connected = 0;
-               end_requests(fc, &fc->pending);
-               end_requests(fc, &fc->processing);
-               spin_unlock(&fc->lock);
-               fasync_helper(-1, file, 0, &fc->fasync);
-               fuse_conn_put(fc);
-       }
-
-       return 0;
-}
-
-static int fuse_dev_fasync(int fd, struct file *file, int on)
-{
-       struct fuse_conn *fc = fuse_get_conn(file);
-       if (!fc)
-               return -EPERM;
-
-       /* No locking - fasync_helper does its own locking */
-       return fasync_helper(fd, file, on, &fc->fasync);
-}
-
-struct file_operations fuse_dev_operations = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-#ifndef KERNEL_2_6_19_PLUS
-       .read           = fuse_dev_read,
-       .readv          = fuse_dev_readv,
-       .write          = fuse_dev_write,
-       .writev         = fuse_dev_writev,
-#else
-       .read           = do_sync_read,
-       .aio_read       = fuse_dev_read,
-       .write          = do_sync_write,
-       .aio_write      = fuse_dev_write,
-#endif
-       .poll           = fuse_dev_poll,
-       .release        = fuse_dev_release,
-       .fasync         = fuse_dev_fasync,
-};
-
-static struct miscdevice fuse_miscdevice = {
-       .minor = FUSE_MINOR,
-       .name  = "fuse",
-       .fops = &fuse_dev_operations,
-};
-
-int __init fuse_dev_init(void)
-{
-       int err = -ENOMEM;
-#ifdef KERNEL_2_6_23_PLUS
-       fuse_req_cachep = kmem_cache_create("fuse_request",
-                                           sizeof(struct fuse_req),
-                                           0, 0, NULL);
-#else
-       fuse_req_cachep = kmem_cache_create("fuse_request",
-                                           sizeof(struct fuse_req),
-                                           0, 0, NULL, NULL);
-#endif
-       if (!fuse_req_cachep)
-               goto out;
-
-       err = misc_register(&fuse_miscdevice);
-       if (err)
-               goto out_cache_clean;
-
-       return 0;
-
- out_cache_clean:
-       kmem_cache_destroy(fuse_req_cachep);
- out:
-       return err;
-}
-
-void fuse_dev_cleanup(void)
-{
-       misc_deregister(&fuse_miscdevice);
-       kmem_cache_destroy(fuse_req_cachep);
-}
diff --git a/kernel/dir.c b/kernel/dir.c
deleted file mode 100644 (file)
index b1fe4c6..0000000
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#include "fuse_i.h"
-
-#include <linux/pagemap.h>
-#include <linux/file.h>
-#include <linux/gfp.h>
-#include <linux/sched.h>
-#include <linux/namei.h>
-
-#if BITS_PER_LONG >= 64
-static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
-{
-       entry->d_time = time;
-}
-
-static inline u64 fuse_dentry_time(struct dentry *entry)
-{
-       return entry->d_time;
-}
-#else
-/*
- * On 32 bit archs store the high 32 bits of time in d_fsdata
- */
-static void fuse_dentry_settime(struct dentry *entry, u64 time)
-{
-       entry->d_time = time;
-       entry->d_fsdata = (void *) (unsigned long) (time >> 32);
-}
-
-static u64 fuse_dentry_time(struct dentry *entry)
-{
-       return (u64) entry->d_time +
-               ((u64) (unsigned long) entry->d_fsdata << 32);
-}
-#endif
-
-/*
- * FUSE caches dentries and attributes with separate timeout.  The
- * time in jiffies until the dentry/attributes are valid is stored in
- * dentry->d_time and fuse_inode->i_time respectively.
- */
-
-/*
- * Calculate the time in jiffies until a dentry/attributes are valid
- */
-static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
-{
-       if (sec || nsec) {
-               struct timespec ts = {sec, nsec};
-               return get_jiffies_64() + timespec_to_jiffies(&ts);
-       } else
-               return 0;
-}
-
-/*
- * Set dentry and possibly attribute timeouts from the lookup/mk*
- * replies
- */
-static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
-{
-       fuse_dentry_settime(entry,
-               time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
-       if (entry->d_inode)
-               get_fuse_inode(entry->d_inode)->i_time =
-                       time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
-}
-
-/*
- * Mark the attributes as stale, so that at the next call to
- * ->getattr() they will be fetched from userspace
- */
-void fuse_invalidate_attr(struct inode *inode)
-{
-       get_fuse_inode(inode)->i_time = 0;
-}
-
-/*
- * Just mark the entry as stale, so that a next attempt to look it up
- * will result in a new lookup call to userspace
- *
- * This is called when a dentry is about to become negative and the
- * timeout is unknown (unlink, rmdir, rename and in some cases
- * lookup)
- */
-static void fuse_invalidate_entry_cache(struct dentry *entry)
-{
-       fuse_dentry_settime(entry, 0);
-}
-
-/*
- * Same as fuse_invalidate_entry_cache(), but also try to remove the
- * dentry from the hash
- */
-static void fuse_invalidate_entry(struct dentry *entry)
-{
-       d_invalidate(entry);
-       fuse_invalidate_entry_cache(entry);
-}
-
-static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
-                            struct dentry *entry,
-                            struct fuse_entry_out *outarg)
-{
-       req->in.h.opcode = FUSE_LOOKUP;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 1;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(struct fuse_entry_out);
-       req->out.args[0].value = outarg;
-}
-
-/*
- * Check whether the dentry is still valid
- *
- * If the entry validity timeout has expired and the dentry is
- * positive, try to redo the lookup.  If the lookup results in a
- * different inode, then let the VFS invalidate the dentry and redo
- * the lookup once more.  If the lookup results in the same inode,
- * then refresh the attributes, timeouts and mark the dentry valid.
- */
-static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
-{
-       struct inode *inode = entry->d_inode;
-
-       if (inode && is_bad_inode(inode))
-               return 0;
-       else if (fuse_dentry_time(entry) < get_jiffies_64()) {
-               int err;
-               struct fuse_entry_out outarg;
-               struct fuse_conn *fc;
-               struct fuse_req *req;
-               struct fuse_req *forget_req;
-               struct dentry *parent;
-
-               /* For negative dentries, always do a fresh lookup */
-               if (!inode)
-                       return 0;
-
-               fc = get_fuse_conn(inode);
-               req = fuse_get_req(fc);
-               if (IS_ERR(req))
-                       return 0;
-
-               forget_req = fuse_get_req(fc);
-               if (IS_ERR(forget_req)) {
-                       fuse_put_request(fc, req);
-                       return 0;
-               }
-
-               parent = dget_parent(entry);
-               fuse_lookup_init(req, parent->d_inode, entry, &outarg);
-               request_send(fc, req);
-               dput(parent);
-               err = req->out.h.error;
-               fuse_put_request(fc, req);
-               /* Zero nodeid is same as -ENOENT */
-               if (!err && !outarg.nodeid)
-                       err = -ENOENT;
-               if (!err) {
-                       struct fuse_inode *fi = get_fuse_inode(inode);
-                       if (outarg.nodeid != get_node_id(inode)) {
-                               fuse_send_forget(fc, forget_req,
-                                                outarg.nodeid, 1);
-                               return 0;
-                       }
-                       spin_lock(&fc->lock);
-                       fi->nlookup ++;
-                       spin_unlock(&fc->lock);
-               }
-               fuse_put_request(fc, forget_req);
-               if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
-                       return 0;
-
-               fuse_change_attributes(inode, &outarg.attr);
-               fuse_change_timeout(entry, &outarg);
-       }
-       return 1;
-}
-
-static int invalid_nodeid(u64 nodeid)
-{
-       return !nodeid || nodeid == FUSE_ROOT_ID;
-}
-
-struct dentry_operations fuse_dentry_operations = {
-       .d_revalidate   = fuse_dentry_revalidate,
-};
-
-int fuse_valid_type(int m)
-{
-       return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
-               S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
-}
-
-/*
- * Add a directory inode to a dentry, ensuring that no other dentry
- * refers to this inode.  Called with fc->inst_mutex.
- */
-static struct dentry *fuse_d_add_directory(struct dentry *entry,
-                                          struct inode *inode)
-{
-       struct dentry *alias = d_find_alias(inode);
-       if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
-               /* This tries to shrink the subtree below alias */
-               fuse_invalidate_entry(alias);
-               dput(alias);
-               if (!list_empty(&inode->i_dentry))
-                       return ERR_PTR(-EBUSY);
-       } else
-               dput(alias);
-       return d_splice_alias(inode, entry);
-}
-
-static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
-                                 struct nameidata *nd)
-{
-       int err;
-       struct fuse_entry_out outarg;
-       struct inode *inode = NULL;
-       struct dentry *newent;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req;
-       struct fuse_req *forget_req;
-
-       if (entry->d_name.len > FUSE_NAME_MAX)
-               return ERR_PTR(-ENAMETOOLONG);
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return ERR_PTR(PTR_ERR(req));
-
-       forget_req = fuse_get_req(fc);
-       if (IS_ERR(forget_req)) {
-               fuse_put_request(fc, req);
-               return ERR_PTR(PTR_ERR(forget_req));
-       }
-
-       fuse_lookup_init(req, dir, entry, &outarg);
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       /* Zero nodeid is same as -ENOENT, but with valid timeout */
-       if (!err && outarg.nodeid &&
-           (invalid_nodeid(outarg.nodeid) ||
-            !fuse_valid_type(outarg.attr.mode)))
-               err = -EIO;
-       if (!err && outarg.nodeid) {
-               inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-                                 &outarg.attr);
-               if (!inode) {
-                       fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
-                       return ERR_PTR(-ENOMEM);
-               }
-       }
-       fuse_put_request(fc, forget_req);
-       if (err && err != -ENOENT)
-               return ERR_PTR(err);
-
-       if (inode && S_ISDIR(inode->i_mode)) {
-               mutex_lock(&fc->inst_mutex);
-               newent = fuse_d_add_directory(entry, inode);
-               mutex_unlock(&fc->inst_mutex);
-               if (IS_ERR(newent)) {
-                       iput(inode);
-                       return newent;
-               }
-       } else
-               newent = d_splice_alias(inode, entry);
-
-       entry = newent ? newent : entry;
-       entry->d_op = &fuse_dentry_operations;
-       if (!err)
-               fuse_change_timeout(entry, &outarg);
-       else
-               fuse_invalidate_entry_cache(entry);
-       return newent;
-}
-
-#ifdef HAVE_LOOKUP_INSTANTIATE_FILP
-/*
- * Synchronous release for the case when something goes wrong in CREATE_OPEN
- */
-static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff,
-                             u64 nodeid, int flags)
-{
-       struct fuse_req *req;
-
-       req = fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
-       req->force = 1;
-       request_send(fc, req);
-       fuse_put_request(fc, req);
-}
-
-/*
- * Atomic create+open operation
- *
- * If the filesystem doesn't support this, then fall back to separate
- * 'mknod' + 'open' requests.
- */
-static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
-                           struct nameidata *nd)
-{
-       int err;
-       struct inode *inode;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req;
-       struct fuse_req *forget_req;
-       struct fuse_open_in inarg;
-       struct fuse_open_out outopen;
-       struct fuse_entry_out outentry;
-       struct fuse_file *ff;
-       struct file *file;
-       int flags = nd->intent.open.flags - 1;
-
-       if (fc->no_create)
-               return -ENOSYS;
-
-       forget_req = fuse_get_req(fc);
-       if (IS_ERR(forget_req))
-               return PTR_ERR(forget_req);
-
-       req = fuse_get_req(fc);
-       err = PTR_ERR(req);
-       if (IS_ERR(req))
-               goto out_put_forget_req;
-
-       err = -ENOMEM;
-       ff = fuse_file_alloc();
-       if (!ff)
-               goto out_put_request;
-
-       flags &= ~O_NOCTTY;
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = flags;
-       inarg.mode = mode;
-       req->in.h.opcode = FUSE_CREATE;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       req->out.numargs = 2;
-       req->out.args[0].size = sizeof(outentry);
-       req->out.args[0].value = &outentry;
-       req->out.args[1].size = sizeof(outopen);
-       req->out.args[1].value = &outopen;
-       request_send(fc, req);
-       err = req->out.h.error;
-       if (err) {
-               if (err == -ENOSYS)
-                       fc->no_create = 1;
-               goto out_free_ff;
-       }
-
-       err = -EIO;
-       if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
-               goto out_free_ff;
-
-       fuse_put_request(fc, req);
-       inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
-                         &outentry.attr);
-       if (!inode) {
-               flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
-               ff->fh = outopen.fh;
-               fuse_sync_release(fc, ff, outentry.nodeid, flags);
-               fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
-               return -ENOMEM;
-       }
-       fuse_put_request(fc, forget_req);
-       d_instantiate(entry, inode);
-       fuse_invalidate_attr(dir);
-       fuse_change_timeout(entry, &outentry);
-       file = lookup_instantiate_filp(nd, entry, generic_file_open);
-       if (IS_ERR(file)) {
-               ff->fh = outopen.fh;
-               fuse_sync_release(fc, ff, outentry.nodeid, flags);
-               return PTR_ERR(file);
-       }
-       fuse_finish_open(inode, file, ff, &outopen);
-       return 0;
-
- out_free_ff:
-       fuse_file_free(ff);
- out_put_request:
-       fuse_put_request(fc, req);
- out_put_forget_req:
-       fuse_put_request(fc, forget_req);
-       return err;
-}
-#endif
-
-/*
- * Code shared between mknod, mkdir, symlink and link
- */
-static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
-                           struct inode *dir, struct dentry *entry,
-                           int mode)
-{
-       struct fuse_entry_out outarg;
-       struct inode *inode;
-       int err;
-       struct fuse_req *forget_req;
-
-       forget_req = fuse_get_req(fc);
-       if (IS_ERR(forget_req)) {
-               fuse_put_request(fc, req);
-               return PTR_ERR(forget_req);
-       }
-
-       req->in.h.nodeid = get_node_id(dir);
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err)
-               goto out_put_forget_req;
-
-       err = -EIO;
-       if (invalid_nodeid(outarg.nodeid))
-               goto out_put_forget_req;
-
-       if ((outarg.attr.mode ^ mode) & S_IFMT)
-               goto out_put_forget_req;
-
-       inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-                         &outarg.attr);
-       if (!inode) {
-               fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
-               return -ENOMEM;
-       }
-       fuse_put_request(fc, forget_req);
-
-       if (S_ISDIR(inode->i_mode)) {
-               struct dentry *alias;
-               mutex_lock(&fc->inst_mutex);
-               alias = d_find_alias(inode);
-               if (alias) {
-                       /* New directory must have moved since mkdir */
-                       mutex_unlock(&fc->inst_mutex);
-                       dput(alias);
-                       iput(inode);
-                       return -EBUSY;
-               }
-               d_instantiate(entry, inode);
-               mutex_unlock(&fc->inst_mutex);
-       } else
-               d_instantiate(entry, inode);
-
-       fuse_change_timeout(entry, &outarg);
-       fuse_invalidate_attr(dir);
-       return 0;
-
- out_put_forget_req:
-       fuse_put_request(fc, forget_req);
-       return err;
-}
-
-static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
-                     dev_t rdev)
-{
-       struct fuse_mknod_in inarg;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.mode = mode;
-       inarg.rdev = new_encode_dev(rdev);
-       req->in.h.opcode = FUSE_MKNOD;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       return create_new_entry(fc, req, dir, entry, mode);
-}
-
-static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
-                      struct nameidata *nd)
-{
-#ifdef HAVE_LOOKUP_INSTANTIATE_FILP
-       if (nd && (nd->flags & LOOKUP_OPEN)) {
-               int err = fuse_create_open(dir, entry, mode, nd);
-               if (err != -ENOSYS)
-                       return err;
-               /* Fall back on mknod */
-       }
-#endif
-       return fuse_mknod(dir, entry, mode, 0);
-}
-
-static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
-{
-       struct fuse_mkdir_in inarg;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.mode = mode;
-       req->in.h.opcode = FUSE_MKDIR;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       return create_new_entry(fc, req, dir, entry, S_IFDIR);
-}
-
-static int fuse_symlink(struct inode *dir, struct dentry *entry,
-                       const char *link)
-{
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       unsigned len = strlen(link) + 1;
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_SYMLINK;
-       req->in.numargs = 2;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       req->in.args[1].size = len;
-       req->in.args[1].value = link;
-       return create_new_entry(fc, req, dir, entry, S_IFLNK);
-}
-
-static int fuse_unlink(struct inode *dir, struct dentry *entry)
-{
-       int err;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_UNLINK;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 1;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err) {
-               struct inode *inode = entry->d_inode;
-
-               /* Set nlink to zero so the inode can be cleared, if
-                   the inode does have more links this will be
-                   discovered at the next lookup/getattr */
-               clear_nlink(inode);
-               fuse_invalidate_attr(inode);
-               fuse_invalidate_attr(dir);
-               fuse_invalidate_entry_cache(entry);
-       } else if (err == -EINTR)
-               fuse_invalidate_entry(entry);
-       return err;
-}
-
-static int fuse_rmdir(struct inode *dir, struct dentry *entry)
-{
-       int err;
-       struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_RMDIR;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 1;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err) {
-               clear_nlink(entry->d_inode);
-               fuse_invalidate_attr(dir);
-               fuse_invalidate_entry_cache(entry);
-       } else if (err == -EINTR)
-               fuse_invalidate_entry(entry);
-       return err;
-}
-
-static int fuse_rename(struct inode *olddir, struct dentry *oldent,
-                      struct inode *newdir, struct dentry *newent)
-{
-       int err;
-       struct fuse_rename_in inarg;
-       struct fuse_conn *fc = get_fuse_conn(olddir);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.newdir = get_node_id(newdir);
-       req->in.h.opcode = FUSE_RENAME;
-       req->in.h.nodeid = get_node_id(olddir);
-       req->in.numargs = 3;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = oldent->d_name.len + 1;
-       req->in.args[1].value = oldent->d_name.name;
-       req->in.args[2].size = newent->d_name.len + 1;
-       req->in.args[2].value = newent->d_name.name;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err) {
-               /* ctime changes */
-               fuse_invalidate_attr(oldent->d_inode);
-
-               fuse_invalidate_attr(olddir);
-               if (olddir != newdir)
-                       fuse_invalidate_attr(newdir);
-
-               /* newent will end up negative */
-               if (newent->d_inode)
-                       fuse_invalidate_entry_cache(newent);
-       } else if (err == -EINTR) {
-               /* If request was interrupted, DEITY only knows if the
-                  rename actually took place.  If the invalidation
-                  fails (e.g. some process has CWD under the renamed
-                  directory), then there can be inconsistency between
-                  the dcache and the real filesystem.  Tough luck. */
-               fuse_invalidate_entry(oldent);
-               if (newent->d_inode)
-                       fuse_invalidate_entry(newent);
-       }
-
-       return err;
-}
-
-static int fuse_link(struct dentry *entry, struct inode *newdir,
-                    struct dentry *newent)
-{
-       int err;
-       struct fuse_link_in inarg;
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.oldnodeid = get_node_id(inode);
-       req->in.h.opcode = FUSE_LINK;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = newent->d_name.len + 1;
-       req->in.args[1].value = newent->d_name.name;
-       err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
-       /* Contrary to "normal" filesystems it can happen that link
-          makes two "logical" inodes point to the same "physical"
-          inode.  We invalidate the attributes of the old one, so it
-          will reflect changes in the backing inode (link count,
-          etc.)
-       */
-       if (!err || err == -EINTR)
-               fuse_invalidate_attr(inode);
-       return err;
-}
-
-int fuse_do_getattr(struct inode *inode)
-{
-       int err;
-       struct fuse_attr_out arg;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_GETATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(arg);
-       req->out.args[0].value = &arg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err) {
-               if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
-#ifndef KERNEL_2_6_12_PLUS
-                       if (get_node_id(inode) != FUSE_ROOT_ID)
-                               make_bad_inode(inode);
-#else
-                       make_bad_inode(inode);
-#endif
-                       err = -EIO;
-               } else {
-                       struct fuse_inode *fi = get_fuse_inode(inode);
-                       fuse_change_attributes(inode, &arg.attr);
-                       fi->i_time = time_to_jiffies(arg.attr_valid,
-                                                    arg.attr_valid_nsec);
-               }
-       }
-       return err;
-}
-
-/*
- * Calling into a user-controlled filesystem gives the filesystem
- * daemon ptrace-like capabilities over the requester process.  This
- * means, that the filesystem daemon is able to record the exact
- * filesystem operations performed, and can also control the behavior
- * of the requester process in otherwise impossible ways.  For example
- * it can delay the operation for arbitrary length of time allowing
- * DoS against the requester.
- *
- * For this reason only those processes can call into the filesystem,
- * for which the owner of the mount has ptrace privilege.  This
- * excludes processes started by other users, suid or sgid processes.
- */
-int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
-{
-       if (fc->flags & FUSE_ALLOW_OTHER)
-               return 1;
-
-       if (task->euid == fc->user_id &&
-           task->suid == fc->user_id &&
-           task->uid == fc->user_id &&
-           task->egid == fc->group_id &&
-           task->sgid == fc->group_id &&
-           task->gid == fc->group_id)
-               return 1;
-
-       return 0;
-}
-
-/*
- * Check whether the inode attributes are still valid
- *
- * If the attribute validity timeout has expired, then fetch the fresh
- * attributes with a 'getattr' request
- *
- * I'm not sure why cached attributes are never returned for the root
- * inode, this is probably being too cautious.
- */
-static int fuse_revalidate(struct dentry *entry)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_inode *fi = get_fuse_inode(inode);
-       struct fuse_conn *fc = get_fuse_conn(inode);
-
-       if (!fuse_allow_task(fc, current))
-               return -EACCES;
-       if (get_node_id(inode) != FUSE_ROOT_ID &&
-           fi->i_time >= get_jiffies_64())
-               return 0;
-
-       return fuse_do_getattr(inode);
-}
-
-static int fuse_access(struct inode *inode, int mask)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_access_in inarg;
-       int err;
-
-       if (fc->no_access)
-               return 0;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.mask = mask;
-       req->in.h.opcode = FUSE_ACCESS;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS) {
-               fc->no_access = 1;
-               err = 0;
-       }
-       return err;
-}
-
-/*
- * Check permission.  The two basic access models of FUSE are:
- *
- * 1) Local access checking ('default_permissions' mount option) based
- * on file mode.  This is the plain old disk filesystem permission
- * modell.
- *
- * 2) "Remote" access checking, where server is responsible for
- * checking permission in each inode operation.  An exception to this
- * is if ->permission() was invoked from sys_access() in which case an
- * access request is sent.  Execute permission is still checked
- * locally based on file mode.
- */
-static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-
-       if (!fuse_allow_task(fc, current))
-               return -EACCES;
-       else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
-#ifdef KERNEL_2_6_10_PLUS
-               int err = generic_permission(inode, mask, NULL);
-#else
-               int err = vfs_permission(inode, mask);
-#endif
-
-               /* If permission is denied, try to refresh file
-                  attributes.  This is also needed, because the root
-                  node will at first have no permissions */
-               if (err == -EACCES) {
-                       err = fuse_do_getattr(inode);
-                       if (!err)
-#ifdef KERNEL_2_6_10_PLUS
-                               err = generic_permission(inode, mask, NULL);
-#else
-                               err = vfs_permission(inode, mask);
-#endif
-               }
-
-               /* Note: the opposite of the above test does not
-                  exist.  So if permissions are revoked this won't be
-                  noticed immediately, only after the attribute
-                  timeout has expired */
-
-               return err;
-       } else {
-               int mode = inode->i_mode;
-#ifndef KERNEL_2_6_11_PLUS
-               if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
-                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-                        return -EROFS;
-#endif
-               if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
-                       return -EACCES;
-
-#ifndef LOOKUP_CHDIR
-#define LOOKUP_CHDIR 0
-#endif
-               if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
-                       return fuse_access(inode, mask);
-               return 0;
-       }
-}
-
-static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
-                        void *dstbuf, filldir_t filldir)
-{
-       while (nbytes >= FUSE_NAME_OFFSET) {
-               struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
-               size_t reclen = FUSE_DIRENT_SIZE(dirent);
-               int over;
-               if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
-                       return -EIO;
-               if (reclen > nbytes)
-                       break;
-
-               over = filldir(dstbuf, dirent->name, dirent->namelen,
-                              file->f_pos, dirent->ino, dirent->type);
-               if (over)
-                       break;
-
-               buf += reclen;
-               nbytes -= reclen;
-               file->f_pos = dirent->off;
-       }
-
-       return 0;
-}
-
-static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
-{
-       int err;
-       size_t nbytes;
-       struct page *page;
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       page = alloc_page(GFP_KERNEL);
-       if (!page) {
-               fuse_put_request(fc, req);
-               return -ENOMEM;
-       }
-       req->num_pages = 1;
-       req->pages[0] = page;
-       fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
-       request_send(fc, req);
-       nbytes = req->out.args[0].size;
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err)
-               err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
-                                   filldir);
-
-       __free_page(page);
-       fuse_invalidate_attr(inode); /* atime changed */
-       return err;
-}
-
-static char *read_link(struct dentry *dentry)
-{
-       struct inode *inode = dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req(fc);
-       char *link;
-
-       if (IS_ERR(req))
-               return ERR_PTR(PTR_ERR(req));
-
-       link = (char *) __get_free_page(GFP_KERNEL);
-       if (!link) {
-               link = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-       req->in.h.opcode = FUSE_READLINK;
-       req->in.h.nodeid = get_node_id(inode);
-       req->out.argvar = 1;
-       req->out.numargs = 1;
-       req->out.args[0].size = PAGE_SIZE - 1;
-       req->out.args[0].value = link;
-       request_send(fc, req);
-       if (req->out.h.error) {
-               free_page((unsigned long) link);
-               link = ERR_PTR(req->out.h.error);
-       } else
-               link[req->out.args[0].size] = '\0';
- out:
-       fuse_put_request(fc, req);
-       fuse_invalidate_attr(inode); /* atime changed */
-       return link;
-}
-
-static void free_link(char *link)
-{
-       if (!IS_ERR(link))
-               free_page((unsigned long) link);
-}
-
-#ifdef KERNEL_2_6_13_PLUS
-static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       nd_set_link(nd, read_link(dentry));
-       return NULL;
-}
-
-static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
-{
-       free_link(nd_get_link(nd));
-}
-#else
-static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
-       nd_set_link(nd, read_link(dentry));
-       return 0;
-}
-
-static void fuse_put_link(struct dentry *dentry, struct nameidata *nd)
-{
-       free_link(nd_get_link(nd));
-}
-#endif
-
-static int fuse_dir_open(struct inode *inode, struct file *file)
-{
-       return fuse_open_common(inode, file, 1);
-}
-
-static int fuse_dir_release(struct inode *inode, struct file *file)
-{
-       return fuse_release_common(inode, file, 1);
-}
-
-static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
-{
-       /* nfsd can call this with no file */
-       return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
-}
-
-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
-{
-       unsigned ivalid = iattr->ia_valid;
-
-       if (ivalid & ATTR_MODE)
-               arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
-       if (ivalid & ATTR_UID)
-               arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
-       if (ivalid & ATTR_GID)
-               arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
-       if (ivalid & ATTR_SIZE)
-               arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
-       /* You can only _set_ these together (they may change by themselves) */
-       if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
-               arg->valid |= FATTR_ATIME | FATTR_MTIME;
-               arg->atime = iattr->ia_atime.tv_sec;
-               arg->mtime = iattr->ia_mtime.tv_sec;
-       }
-#ifdef ATTR_FILE
-       if (ivalid & ATTR_FILE) {
-               struct fuse_file *ff = iattr->ia_file->private_data;
-               arg->valid |= FATTR_FH;
-               arg->fh = ff->fh;
-       }
-#endif
-}
-
-static void fuse_vmtruncate(struct inode *inode, loff_t offset)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       int need_trunc;
-
-       spin_lock(&fc->lock);
-       need_trunc = inode->i_size > offset;
-       i_size_write(inode, offset);
-       spin_unlock(&fc->lock);
-
-       if (need_trunc) {
-               struct address_space *mapping = inode->i_mapping;
-               unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
-               truncate_inode_pages(mapping, offset);
-       }
-}
-
-/*
- * Set attributes, and at the same time refresh them.
- *
- * Truncation is slightly complicated, because the 'truncate' request
- * may fail, in which case we don't want to touch the mapping.
- * vmtruncate() doesn't allow for this case, so do the rlimit checking
- * and the actual truncation by hand.
- */
-static int fuse_setattr(struct dentry *entry, struct iattr *attr)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_inode *fi = get_fuse_inode(inode);
-       struct fuse_req *req;
-       struct fuse_setattr_in inarg;
-       struct fuse_attr_out outarg;
-       int err;
-       int is_truncate = 0;
-
-       if (!fuse_allow_task(fc, current))
-               return -EACCES;
-
-       if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
-               err = inode_change_ok(inode, attr);
-               if (err)
-                       return err;
-       }
-
-       if (attr->ia_valid & ATTR_SIZE) {
-               unsigned long limit;
-               is_truncate = 1;
-               if (IS_SWAPFILE(inode))
-                       return -ETXTBSY;
-#ifdef KERNEL_2_6_10_PLUS
-               limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
-#else
-               limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
-#endif
-               if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
-                       send_sig(SIGXFSZ, current, 0);
-                       return -EFBIG;
-               }
-       }
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       iattr_to_fattr(attr, &inarg);
-       /* Defend against future expansion of ATTR_FILE use */
-       if (S_ISDIR(inode->i_mode))
-               inarg.valid &= ~FATTR_FH;
-       req->in.h.opcode = FUSE_SETATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err) {
-               if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
-#ifndef KERNEL_2_6_12_PLUS
-                       if (get_node_id(inode) != FUSE_ROOT_ID)
-                               make_bad_inode(inode);
-#else
-                       make_bad_inode(inode);
-#endif
-                       err = -EIO;
-               } else {
-                       if (is_truncate)
-                               fuse_vmtruncate(inode, outarg.attr.size);
-                       fuse_change_attributes(inode, &outarg.attr);
-                       fi->i_time = time_to_jiffies(outarg.attr_valid,
-                                                    outarg.attr_valid_nsec);
-               }
-       } else if (err == -EINTR)
-               fuse_invalidate_attr(inode);
-
-       return err;
-}
-
-static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
-                       struct kstat *stat)
-{
-       struct inode *inode = entry->d_inode;
-       int err = fuse_revalidate(entry);
-       if (!err)
-               /* FIXME: may want specialized function because of
-                  st_blksize on block devices on 2.6.19+ */
-               generic_fillattr(inode, stat);
-
-       return err;
-}
-
-static int fuse_setxattr(struct dentry *entry, const char *name,
-                        const void *value, size_t size, int flags)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_setxattr_in inarg;
-       int err;
-
-       if (fc->no_setxattr)
-               return -EOPNOTSUPP;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.size = size;
-       inarg.flags = flags;
-       req->in.h.opcode = FUSE_SETXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 3;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = strlen(name) + 1;
-       req->in.args[1].value = name;
-       req->in.args[2].size = size;
-       req->in.args[2].value = value;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS) {
-               fc->no_setxattr = 1;
-               err = -EOPNOTSUPP;
-       }
-       return err;
-}
-
-static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
-                            void *value, size_t size)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_getxattr_in inarg;
-       struct fuse_getxattr_out outarg;
-       ssize_t ret;
-
-       if (fc->no_getxattr)
-               return -EOPNOTSUPP;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.size = size;
-       req->in.h.opcode = FUSE_GETXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = strlen(name) + 1;
-       req->in.args[1].value = name;
-       /* This is really two different operations rolled into one */
-       req->out.numargs = 1;
-       if (size) {
-               req->out.argvar = 1;
-               req->out.args[0].size = size;
-               req->out.args[0].value = value;
-       } else {
-               req->out.args[0].size = sizeof(outarg);
-               req->out.args[0].value = &outarg;
-       }
-       request_send(fc, req);
-       ret = req->out.h.error;
-       if (!ret)
-               ret = size ? req->out.args[0].size : outarg.size;
-       else {
-               if (ret == -ENOSYS) {
-                       fc->no_getxattr = 1;
-                       ret = -EOPNOTSUPP;
-               }
-       }
-       fuse_put_request(fc, req);
-       return ret;
-}
-
-static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_getxattr_in inarg;
-       struct fuse_getxattr_out outarg;
-       ssize_t ret;
-
-       if (!fuse_allow_task(fc, current))
-               return -EACCES;
-
-       if (fc->no_listxattr)
-               return -EOPNOTSUPP;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.size = size;
-       req->in.h.opcode = FUSE_LISTXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       /* This is really two different operations rolled into one */
-       req->out.numargs = 1;
-       if (size) {
-               req->out.argvar = 1;
-               req->out.args[0].size = size;
-               req->out.args[0].value = list;
-       } else {
-               req->out.args[0].size = sizeof(outarg);
-               req->out.args[0].value = &outarg;
-       }
-       request_send(fc, req);
-       ret = req->out.h.error;
-       if (!ret)
-               ret = size ? req->out.args[0].size : outarg.size;
-       else {
-               if (ret == -ENOSYS) {
-                       fc->no_listxattr = 1;
-                       ret = -EOPNOTSUPP;
-               }
-       }
-       fuse_put_request(fc, req);
-       return ret;
-}
-
-static int fuse_removexattr(struct dentry *entry, const char *name)
-{
-       struct inode *inode = entry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       int err;
-
-       if (fc->no_removexattr)
-               return -EOPNOTSUPP;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_REMOVEXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = strlen(name) + 1;
-       req->in.args[0].value = name;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS) {
-               fc->no_removexattr = 1;
-               err = -EOPNOTSUPP;
-       }
-       return err;
-}
-
-static struct inode_operations fuse_dir_inode_operations = {
-       .lookup         = fuse_lookup,
-       .mkdir          = fuse_mkdir,
-       .symlink        = fuse_symlink,
-       .unlink         = fuse_unlink,
-       .rmdir          = fuse_rmdir,
-       .rename         = fuse_rename,
-       .link           = fuse_link,
-       .setattr        = fuse_setattr,
-       .create         = fuse_create,
-       .mknod          = fuse_mknod,
-       .permission     = fuse_permission,
-       .getattr        = fuse_getattr,
-       .setxattr       = fuse_setxattr,
-       .getxattr       = fuse_getxattr,
-       .listxattr      = fuse_listxattr,
-       .removexattr    = fuse_removexattr,
-};
-
-static struct file_operations fuse_dir_operations = {
-       .llseek         = generic_file_llseek,
-       .read           = generic_read_dir,
-       .readdir        = fuse_readdir,
-       .open           = fuse_dir_open,
-       .release        = fuse_dir_release,
-       .fsync          = fuse_dir_fsync,
-};
-
-static struct inode_operations fuse_common_inode_operations = {
-       .setattr        = fuse_setattr,
-       .permission     = fuse_permission,
-       .getattr        = fuse_getattr,
-       .setxattr       = fuse_setxattr,
-       .getxattr       = fuse_getxattr,
-       .listxattr      = fuse_listxattr,
-       .removexattr    = fuse_removexattr,
-};
-
-static struct inode_operations fuse_symlink_inode_operations = {
-       .setattr        = fuse_setattr,
-       .follow_link    = fuse_follow_link,
-       .put_link       = fuse_put_link,
-       .readlink       = generic_readlink,
-       .getattr        = fuse_getattr,
-       .setxattr       = fuse_setxattr,
-       .getxattr       = fuse_getxattr,
-       .listxattr      = fuse_listxattr,
-       .removexattr    = fuse_removexattr,
-};
-
-void fuse_init_common(struct inode *inode)
-{
-       inode->i_op = &fuse_common_inode_operations;
-}
-
-void fuse_init_dir(struct inode *inode)
-{
-       inode->i_op = &fuse_dir_inode_operations;
-       inode->i_fop = &fuse_dir_operations;
-}
-
-void fuse_init_symlink(struct inode *inode)
-{
-       inode->i_op = &fuse_symlink_inode_operations;
-}
diff --git a/kernel/file.c b/kernel/file.c
deleted file mode 100644 (file)
index 16a2d02..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#include "fuse_i.h"
-
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#ifndef KERNEL_2_6_11_PLUS
-static inline loff_t page_offset(struct page *page)
-{
-       return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
-}
-#endif
-static struct file_operations fuse_direct_io_file_operations;
-
-static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
-                         struct fuse_open_out *outargp)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_open_in inarg;
-       struct fuse_req *req;
-       int err;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-       req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(*outargp);
-       req->out.args[0].value = outargp;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-
-       return err;
-}
-
-struct fuse_file *fuse_file_alloc(void)
-{
-       struct fuse_file *ff;
-       ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
-       if (ff) {
-               ff->reserved_req = fuse_request_alloc();
-               if (!ff->reserved_req) {
-                       kfree(ff);
-                       ff = NULL;
-               }
-       }
-       return ff;
-}
-
-void fuse_file_free(struct fuse_file *ff)
-{
-       fuse_request_free(ff->reserved_req);
-       kfree(ff);
-}
-
-void fuse_finish_open(struct inode *inode, struct file *file,
-                     struct fuse_file *ff, struct fuse_open_out *outarg)
-{
-       if (outarg->open_flags & FOPEN_DIRECT_IO)
-               file->f_op = &fuse_direct_io_file_operations;
-       if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
-#ifdef KERNEL_2_6_21_PLUS
-               invalidate_mapping_pages(inode->i_mapping, 0, -1);
-#else
-               invalidate_inode_pages(inode->i_mapping);
-#endif
-       ff->fh = outarg->fh;
-       file->private_data = ff;
-}
-
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
-{
-       struct fuse_open_out outarg;
-       struct fuse_file *ff;
-       int err;
-
-       /* VFS checks this, but only _after_ ->open() */
-       if (file->f_flags & O_DIRECT)
-               return -EINVAL;
-
-       err = generic_file_open(inode, file);
-       if (err)
-               return err;
-
-       /* If opening the root node, no lookup has been performed on
-          it, so the attributes must be refreshed */
-       if (get_node_id(inode) == FUSE_ROOT_ID) {
-               err = fuse_do_getattr(inode);
-               if (err)
-                       return err;
-       }
-
-       ff = fuse_file_alloc();
-       if (!ff)
-               return -ENOMEM;
-
-       err = fuse_send_open(inode, file, isdir, &outarg);
-       if (err)
-               fuse_file_free(ff);
-       else {
-               if (isdir)
-                       outarg.open_flags &= ~FOPEN_DIRECT_IO;
-               fuse_finish_open(inode, file, ff, &outarg);
-       }
-
-       return err;
-}
-
-struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
-                                  int opcode)
-{
-       struct fuse_req *req = ff->reserved_req;
-       struct fuse_release_in *inarg = &req->misc.release_in;
-
-       inarg->fh = ff->fh;
-       inarg->flags = flags;
-       req->in.h.opcode = opcode;
-       req->in.h.nodeid = nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(struct fuse_release_in);
-       req->in.args[0].value = inarg;
-       kfree(ff);
-
-       return req;
-}
-
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
-{
-       struct fuse_file *ff = file->private_data;
-       if (ff) {
-               struct fuse_conn *fc = get_fuse_conn(inode);
-               struct fuse_req *req;
-
-               req = fuse_release_fill(ff, get_node_id(inode), file->f_flags,
-                                       isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
-
-               /* Hold vfsmount and dentry until release is finished */
-               req->vfsmount = mntget(file->f_vfsmnt);
-               req->dentry = dget(file->f_dentry);
-               request_send_background(fc, req);
-       }
-
-       /* Return value is ignored by VFS */
-       return 0;
-}
-
-static int fuse_open(struct inode *inode, struct file *file)
-{
-       return fuse_open_common(inode, file, 0);
-}
-
-static int fuse_release(struct inode *inode, struct file *file)
-{
-       return fuse_release_common(inode, file, 0);
-}
-
-/*
- * Scramble the ID space with XTEA, so that the value of the files_struct
- * pointer is not exposed to userspace.
- */
-static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
-{
-       u32 *k = fc->scramble_key;
-       u64 v = (unsigned long) id;
-       u32 v0 = v;
-       u32 v1 = v >> 32;
-       u32 sum = 0;
-       int i;
-
-       for (i = 0; i < 32; i++) {
-               v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
-               sum += 0x9E3779B9;
-               v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
-       }
-
-       return (u64) v0 + ((u64) v1 << 32);
-}
-
-#ifdef KERNEL_2_6_18_PLUS
-static int fuse_flush(struct file *file, fl_owner_t id)
-#else
-static int fuse_flush(struct file *file)
-#endif
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_req *req;
-       struct fuse_flush_in inarg;
-       int err;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       if (fc->no_flush)
-               return 0;
-
-       req = fuse_get_req_nofail(fc, file);
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.fh = ff->fh;
-#ifdef KERNEL_2_6_18_PLUS
-       inarg.lock_owner = fuse_lock_owner_id(fc, id);
-#else
-       inarg.lock_owner = fuse_lock_owner_id(fc, NULL);
-#endif
-       req->in.h.opcode = FUSE_FLUSH;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->force = 1;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS) {
-               fc->no_flush = 1;
-               err = 0;
-       }
-       return err;
-}
-
-int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
-                     int isdir)
-{
-       struct inode *inode = de->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_req *req;
-       struct fuse_fsync_in inarg;
-       int err;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
-               return 0;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.fh = ff->fh;
-       inarg.fsync_flags = datasync ? 1 : 0;
-       req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS) {
-               if (isdir)
-                       fc->no_fsyncdir = 1;
-               else
-                       fc->no_fsync = 1;
-               err = 0;
-       }
-       return err;
-}
-
-static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
-{
-       return fuse_fsync_common(file, de, datasync, 0);
-}
-
-void fuse_read_fill(struct fuse_req *req, struct file *file,
-                   struct inode *inode, loff_t pos, size_t count, int opcode)
-{
-       struct fuse_file *ff = file->private_data;
-       struct fuse_read_in *inarg = &req->misc.read_in;
-
-       inarg->fh = ff->fh;
-       inarg->offset = pos;
-       inarg->size = count;
-       req->in.h.opcode = opcode;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(struct fuse_read_in);
-       req->in.args[0].value = inarg;
-       req->out.argpages = 1;
-       req->out.argvar = 1;
-       req->out.numargs = 1;
-       req->out.args[0].size = count;
-}
-
-static size_t fuse_send_read(struct fuse_req *req, struct file *file,
-                            struct inode *inode, loff_t pos, size_t count)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
-       request_send(fc, req);
-       return req->out.args[0].size;
-}
-
-static int fuse_readpage(struct file *file, struct page *page)
-{
-       struct inode *inode = page->mapping->host;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       int err;
-
-       err = -EIO;
-       if (is_bad_inode(inode))
-               goto out;
-
-       req = fuse_get_req(fc);
-       err = PTR_ERR(req);
-       if (IS_ERR(req))
-               goto out;
-
-       req->out.page_zeroing = 1;
-       req->num_pages = 1;
-       req->pages[0] = page;
-       fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err)
-               SetPageUptodate(page);
-       fuse_invalidate_attr(inode); /* atime changed */
- out:
-       unlock_page(page);
-       return err;
-}
-
-static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
-{
-       int i;
-
-       fuse_invalidate_attr(req->pages[0]->mapping->host); /* atime changed */
-
-       for (i = 0; i < req->num_pages; i++) {
-               struct page *page = req->pages[i];
-               if (!req->out.h.error)
-                       SetPageUptodate(page);
-               else
-                       SetPageError(page);
-               unlock_page(page);
-       }
-       fuse_put_request(fc, req);
-}
-
-static void fuse_send_readpages(struct fuse_req *req, struct file *file,
-                               struct inode *inode)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       loff_t pos = page_offset(req->pages[0]);
-       size_t count = req->num_pages << PAGE_CACHE_SHIFT;
-       req->out.page_zeroing = 1;
-       fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
-       if (fc->async_read) {
-               get_file(file);
-               req->file = file;
-               req->end = fuse_readpages_end;
-               request_send_background(fc, req);
-       } else {
-               request_send(fc, req);
-               fuse_readpages_end(fc, req);
-       }
-}
-
-struct fuse_readpages_data {
-       struct fuse_req *req;
-       struct file *file;
-       struct inode *inode;
-};
-
-static int fuse_readpages_fill(void *_data, struct page *page)
-{
-       struct fuse_readpages_data *data = _data;
-       struct fuse_req *req = data->req;
-       struct inode *inode = data->inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       int err;
-
-       if (req && req->num_pages &&
-           (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
-            (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
-            req->pages[req->num_pages - 1]->index + 1 != page->index)) {
-               fuse_send_readpages(req, data->file, inode);
-               req = NULL;
-       }
-       if (!req) {
-               err = -EIO;
-               if (is_bad_inode(inode))
-                       goto out_unlock_page;
-
-               data->req = req = fuse_get_req(fc);
-               err = PTR_ERR(req);
-               if (IS_ERR(req))
-                       goto out_unlock_page;
-       }
-       req->pages[req->num_pages] = page;
-       req->num_pages ++;
-       return 0;
-
- out_unlock_page:
-       unlock_page(page);
-       return err;
-}
-
-static int fuse_readpages(struct file *file, struct address_space *mapping,
-                         struct list_head *pages, unsigned nr_pages)
-{
-       struct inode *inode = mapping->host;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_readpages_data data;
-       int err;
-
-       data.file = file;
-       data.inode = inode;
-       data.req = NULL;
-
-       err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
-       if (!err && data.req) {
-               if (data.req->num_pages)
-                       fuse_send_readpages(data.req, file, inode);
-               else
-                       fuse_put_request(fc, data.req);
-       }
-       return err;
-}
-
-static size_t fuse_send_write(struct fuse_req *req, struct file *file,
-                             struct inode *inode, loff_t pos, size_t count)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_write_in inarg;
-       struct fuse_write_out outarg;
-
-       memset(&inarg, 0, sizeof(struct fuse_write_in));
-       inarg.fh = ff->fh;
-       inarg.offset = pos;
-       inarg.size = count;
-       req->in.h.opcode = FUSE_WRITE;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.argpages = 1;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(struct fuse_write_in);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = count;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(struct fuse_write_out);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       return outarg.size;
-}
-
-static int fuse_prepare_write(struct file *file, struct page *page,
-                             unsigned offset, unsigned to)
-{
-       /* No op */
-       return 0;
-}
-
-static int fuse_commit_write(struct file *file, struct page *page,
-                            unsigned offset, unsigned to)
-{
-       int err;
-       size_t nres;
-       unsigned count = to - offset;
-       struct inode *inode = page->mapping->host;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       loff_t pos = page_offset(page) + offset;
-       struct fuse_req *req;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->num_pages = 1;
-       req->pages[0] = page;
-       req->page_offset = offset;
-       nres = fuse_send_write(req, file, inode, pos, count);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err && nres != count)
-               err = -EIO;
-       if (!err) {
-               pos += count;
-               spin_lock(&fc->lock);
-               if (pos > inode->i_size)
-                       i_size_write(inode, pos);
-               spin_unlock(&fc->lock);
-
-               if (offset == 0 && to == PAGE_CACHE_SIZE)
-                       SetPageUptodate(page);
-       }
-       fuse_invalidate_attr(inode);
-       return err;
-}
-
-static void fuse_release_user_pages(struct fuse_req *req, int write)
-{
-       unsigned i;
-
-       for (i = 0; i < req->num_pages; i++) {
-               struct page *page = req->pages[i];
-               if (write)
-                       set_page_dirty_lock(page);
-               put_page(page);
-       }
-}
-
-static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
-                              unsigned nbytes, int write)
-{
-       unsigned long user_addr = (unsigned long) buf;
-       unsigned offset = user_addr & ~PAGE_MASK;
-       int npages;
-
-       /* This doesn't work with nfsd */
-       if (!current->mm)
-               return -EPERM;
-
-       nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
-       npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       npages = max(npages, 1);
-       npages = min(npages, FUSE_MAX_PAGES_PER_REQ);
-       down_read(&current->mm->mmap_sem);
-       npages = get_user_pages(current, current->mm, user_addr, npages, write,
-                               0, req->pages, NULL);
-       up_read(&current->mm->mmap_sem);
-       if (npages < 0)
-               return npages;
-
-       req->num_pages = npages;
-       req->page_offset = offset;
-       return 0;
-}
-
-static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
-                             size_t count, loff_t *ppos, int write)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       size_t nmax = write ? fc->max_write : fc->max_read;
-       loff_t pos = *ppos;
-       ssize_t res = 0;
-       struct fuse_req *req;
-
-       if (is_bad_inode(inode))
-               return -EIO;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       while (count) {
-               size_t nres;
-               size_t nbytes = min(count, nmax);
-               int err = fuse_get_user_pages(req, buf, nbytes, !write);
-               if (err) {
-                       res = err;
-                       break;
-               }
-               nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
-               nbytes = min(count, nbytes);
-               if (write)
-                       nres = fuse_send_write(req, file, inode, pos, nbytes);
-               else
-                       nres = fuse_send_read(req, file, inode, pos, nbytes);
-               fuse_release_user_pages(req, !write);
-               if (req->out.h.error) {
-                       if (!res)
-                               res = req->out.h.error;
-                       break;
-               } else if (nres > nbytes) {
-                       res = -EIO;
-                       break;
-               }
-               count -= nres;
-               res += nres;
-               pos += nres;
-               buf += nres;
-               if (nres != nbytes)
-                       break;
-               if (count) {
-                       fuse_put_request(fc, req);
-                       req = fuse_get_req(fc);
-                       if (IS_ERR(req))
-                               break;
-               }
-       }
-       fuse_put_request(fc, req);
-       if (res > 0) {
-               if (write) {
-                       spin_lock(&fc->lock);
-                       if (pos > inode->i_size)
-                               i_size_write(inode, pos);
-                       spin_unlock(&fc->lock);
-               }
-               *ppos = pos;
-       }
-       fuse_invalidate_attr(inode);
-
-       return res;
-}
-
-static ssize_t fuse_direct_read(struct file *file, char __user *buf,
-                                    size_t count, loff_t *ppos)
-{
-       return fuse_direct_io(file, buf, count, ppos, 0);
-}
-
-static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
-                                size_t count, loff_t *ppos)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       ssize_t res;
-       /* Don't allow parallel writes to the same file */
-       mutex_lock(&inode->i_mutex);
-       res = generic_write_checks(file, ppos, &count, 0);
-       if (!res)
-               res = fuse_direct_io(file, buf, count, ppos, 1);
-       mutex_unlock(&inode->i_mutex);
-       return res;
-}
-
-static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       if ((vma->vm_flags & VM_SHARED)) {
-               if ((vma->vm_flags & VM_WRITE))
-                       return -ENODEV;
-               else
-                       vma->vm_flags &= ~VM_MAYWRITE;
-       }
-       return generic_file_mmap(file, vma);
-}
-
-static int fuse_set_page_dirty(struct page *page)
-{
-       printk("fuse_set_page_dirty: should not happen\n");
-       dump_stack();
-       return 0;
-}
-
-static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
-                                 struct file_lock *fl)
-{
-       switch (ffl->type) {
-       case F_UNLCK:
-               break;
-
-       case F_RDLCK:
-       case F_WRLCK:
-               if (ffl->start > OFFSET_MAX || ffl->end > OFFSET_MAX ||
-                   ffl->end < ffl->start)
-                       return -EIO;
-
-               fl->fl_start = ffl->start;
-               fl->fl_end = ffl->end;
-               fl->fl_pid = ffl->pid;
-               break;
-
-       default:
-               return -EIO;
-       }
-       fl->fl_type = ffl->type;
-       return 0;
-}
-
-static void fuse_lk_fill(struct fuse_req *req, struct file *file,
-                        const struct file_lock *fl, int opcode, pid_t pid)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_lk_in *arg = &req->misc.lk_in;
-
-       arg->fh = ff->fh;
-       arg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
-       arg->lk.start = fl->fl_start;
-       arg->lk.end = fl->fl_end;
-       arg->lk.type = fl->fl_type;
-       arg->lk.pid = pid;
-       req->in.h.opcode = opcode;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(*arg);
-       req->in.args[0].value = arg;
-}
-
-static int fuse_getlk(struct file *file, struct file_lock *fl)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_lk_out outarg;
-       int err;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       fuse_lk_fill(req, file, fl, FUSE_GETLK, 0);
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (!err)
-               err = convert_fuse_file_lock(&outarg.lk, fl);
-
-       return err;
-}
-
-static int fuse_setlk(struct file *file, struct file_lock *fl)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
-       pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
-       int err;
-
-#ifdef KERNEL_2_6_18_PLUS
-       /* Unlock on close is handled by the flush method */
-       if (fl->fl_flags & FL_CLOSE)
-               return 0;
-
-       req = fuse_get_req(fc);
-#else
-       /* If it's (possibly) unlock on close, don't fail the allocation */
-       if (fl->fl_type == F_UNLCK && fl->fl_start == 0 &&
-           fl->fl_end == OFFSET_MAX)
-               req = fuse_get_req_nofail(fc, file);
-       else {
-               /* Hack: add dummy lock, otherwise unlock on close is
-                  optimized away */
-               struct file_lock **flp;
-               for (flp = &inode->i_flock;
-                    *flp && !((*flp)->fl_flags & FL_POSIX);
-                    flp = &(*flp)->fl_next);
-               if (!*flp) {
-                       struct file_lock *dummy =
-                               kmalloc(sizeof(struct file_lock), GFP_KERNEL);
-                       if (!dummy)
-                               return -ENOLCK;
-                       locks_init_lock(dummy);
-                       dummy->fl_flags |= FL_POSIX;
-                       *flp = dummy;
-               }
-               req = fuse_get_req(fc);
-       }
-#endif
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       fuse_lk_fill(req, file, fl, opcode, pid);
-       request_send(fc, req);
-       err = req->out.h.error;
-       /* locking is restartable */
-       if (err == -EINTR)
-               err = -ERESTARTSYS;
-       fuse_put_request(fc, req);
-       return err;
-}
-
-static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
-{
-       struct inode *inode = file->f_dentry->d_inode;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       int err;
-
-       if (cmd == F_GETLK) {
-               if (fc->no_lock) {
-#ifdef KERNEL_2_6_22_PLUS
-                       posix_test_lock(file, fl);
-#elif defined(KERNEL_2_6_17_PLUS)
-                       if (!posix_test_lock(file, fl, fl))
-                               fl->fl_type = F_UNLCK;
-#else
-                       struct file_lock *cfl = posix_test_lock(file, fl);
-                       if (!cfl)
-                               fl->fl_type = F_UNLCK;
-                       else
-                               *fl = *cfl;
-#endif
-                       err = 0;
-               } else
-                       err = fuse_getlk(file, fl);
-       } else {
-               if (fc->no_lock)
-                       err = posix_lock_file_wait(file, fl);
-               else
-                       err = fuse_setlk(file, fl);
-       }
-       return err;
-}
-
-static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
-{
-       struct inode *inode = mapping->host;
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
-       struct fuse_bmap_in inarg;
-       struct fuse_bmap_out outarg;
-       int err;
-
-       if (!inode->i_sb->s_bdev || fc->no_bmap)
-               return 0;
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return 0;
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.block = block;
-       inarg.blocksize = inode->i_sb->s_blocksize;
-       req->in.h.opcode = FUSE_BMAP;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
-       if (err == -ENOSYS)
-               fc->no_bmap = 1;
-
-       return err ? 0 : outarg.block;
-}
-
-static struct file_operations fuse_file_operations = {
-       .llseek         = generic_file_llseek,
-#ifndef KERNEL_2_6_19_PLUS
-       .read           = generic_file_read,
-       .write          = generic_file_write,
-#else
-       .read           = do_sync_read,
-       .aio_read       = generic_file_aio_read,
-       .write          = do_sync_write,
-       .aio_write      = generic_file_aio_write,
-#endif
-       .mmap           = fuse_file_mmap,
-       .open           = fuse_open,
-       .flush          = fuse_flush,
-       .release        = fuse_release,
-       .fsync          = fuse_fsync,
-       .lock           = fuse_file_lock,
-#ifdef KERNEL_2_6_23_PLUS
-       .splice_read    = generic_file_splice_read,
-#else
-       .sendfile       = generic_file_sendfile,
-#endif
-};
-
-static struct file_operations fuse_direct_io_file_operations = {
-       .llseek         = generic_file_llseek,
-       .read           = fuse_direct_read,
-       .write          = fuse_direct_write,
-       .open           = fuse_open,
-       .flush          = fuse_flush,
-       .release        = fuse_release,
-       .fsync          = fuse_fsync,
-       .lock           = fuse_file_lock,
-       /* no mmap and sendfile */
-};
-
-static struct address_space_operations fuse_file_aops  = {
-       .readpage       = fuse_readpage,
-       .prepare_write  = fuse_prepare_write,
-       .commit_write   = fuse_commit_write,
-       .readpages      = fuse_readpages,
-       .set_page_dirty = fuse_set_page_dirty,
-       .bmap           = fuse_bmap,
-};
-
-void fuse_init_file_inode(struct inode *inode)
-{
-       inode->i_fop = &fuse_file_operations;
-       inode->i_data.a_ops = &fuse_file_aops;
-}
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
deleted file mode 100644 (file)
index a43fc97..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#ifdef FUSE_MAINLINE
-#include <linux/fuse.h>
-#else
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-#error Kernel versions earlier than 2.6.9 are not supported
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-#  define KERNEL_2_6_10_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
-#  define KERNEL_2_6_11_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
-#  define KERNEL_2_6_12_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-#  define KERNEL_2_6_13_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-#  define KERNEL_2_6_16_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)
-#  define KERNEL_2_6_17_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-#  define KERNEL_2_6_18_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-#  define KERNEL_2_6_19_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
-#  define KERNEL_2_6_21_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-#  define KERNEL_2_6_22_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
-#  define KERNEL_2_6_23_PLUS
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#  define KERNEL_2_6_24_PLUS
-#endif
-
-#if defined(__arm__) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-#define DCACHE_BUG
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-#define kmem_cache kmem_cache_s
-#endif
-
-#include "fuse_kernel.h"
-#include "config.h"
-#endif /* FUSE_MAINLINE */
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/backing-dev.h>
-#ifdef HAVE_MUTEX_H
-#include <linux/mutex.h>
-#else
-#include <asm/semaphore.h>
-#define DEFINE_MUTEX(m) DECLARE_MUTEX(m)
-#define mutex_init(m) init_MUTEX(m)
-#define mutex_destroy(m) do { } while (0)
-#define mutex_lock(m) down(m)
-#define mutex_unlock(m) up(m)
-#define mutex semaphore
-#endif
-#ifndef HAVE_I_MUTEX
-#ifndef mutex_destroy
-/* Some RHEL kernels include a backported mutex.h, which lacks mutex_destroy */
-#define mutex_destroy(m) do { } while (0)
-#endif
-#define i_mutex i_sem  /* Hack for struct inode */
-#endif
-#ifndef KERNEL_2_6_19_PLUS
-#define clear_nlink(inode) (inode)->i_nlink = 0
-#define inc_nlink(inode) (inode)->i_nlink++
-#endif
-#ifndef HAVE_CONFIG_BLOCK
-#define CONFIG_BLOCK
-#endif
-#ifndef FS_HAS_SUBTYPE
-#define FS_HAS_SUBTYPE 0
-#endif
-#ifndef FS_SAFE
-#define FS_SAFE 0
-#endif
-
-/** Max number of pages that can be used in a single read request */
-#define FUSE_MAX_PAGES_PER_REQ 32
-
-/** Maximum number of outstanding background requests */
-#define FUSE_MAX_BACKGROUND 10
-
-/** It could be as large as PATH_MAX, but would that have any uses? */
-#define FUSE_NAME_MAX 1024
-
-/** Number of dentries for each connection in the control filesystem */
-#define FUSE_CTL_NUM_DENTRIES 3
-
-/** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
-    module will check permissions based on the file mode.  Otherwise no
-    permission checking is done in the kernel */
-#define FUSE_DEFAULT_PERMISSIONS (1 << 0)
-
-/** If the FUSE_ALLOW_OTHER flag is given, then not only the user
-    doing the mount will be allowed to access the filesystem */
-#define FUSE_ALLOW_OTHER         (1 << 1)
-
-/** List of active connections */
-extern struct list_head fuse_conn_list;
-
-/** Global mutex protecting fuse_conn_list and the control filesystem */
-extern struct mutex fuse_mutex;
-
-/** FUSE inode */
-struct fuse_inode {
-       /** Inode data */
-       struct inode inode;
-
-       /** Unique ID, which identifies the inode between userspace
-        * and kernel */
-       u64 nodeid;
-
-       /** Number of lookups on this inode */
-       u64 nlookup;
-
-       /** The request used for sending the FORGET message */
-       struct fuse_req *forget_req;
-
-       /** Time in jiffies until the file attributes are valid */
-       u64 i_time;
-};
-
-/** FUSE specific file data */
-struct fuse_file {
-       /** Request reserved for flush and release */
-       struct fuse_req *reserved_req;
-
-       /** File handle used by userspace */
-       u64 fh;
-};
-
-/** One input argument of a request */
-struct fuse_in_arg {
-       unsigned size;
-       const void *value;
-};
-
-/** The request input */
-struct fuse_in {
-       /** The request header */
-       struct fuse_in_header h;
-
-       /** True if the data for the last argument is in req->pages */
-       unsigned argpages:1;
-
-       /** Number of arguments */
-       unsigned numargs;
-
-       /** Array of arguments */
-       struct fuse_in_arg args[3];
-};
-
-/** One output argument of a request */
-struct fuse_arg {
-       unsigned size;
-       void *value;
-};
-
-/** The request output */
-struct fuse_out {
-       /** Header returned from userspace */
-       struct fuse_out_header h;
-
-       /*
-        * The following bitfields are not changed during the request
-        * processing
-        */
-
-       /** Last argument is variable length (can be shorter than
-           arg->size) */
-       unsigned argvar:1;
-
-       /** Last argument is a list of pages to copy data to */
-       unsigned argpages:1;
-
-       /** Zero partially or not copied pages */
-       unsigned page_zeroing:1;
-
-       /** Number or arguments */
-       unsigned numargs;
-
-       /** Array of arguments */
-       struct fuse_arg args[3];
-};
-
-/** The request state */
-enum fuse_req_state {
-       FUSE_REQ_INIT = 0,
-       FUSE_REQ_PENDING,
-       FUSE_REQ_READING,
-       FUSE_REQ_SENT,
-       FUSE_REQ_WRITING,
-       FUSE_REQ_FINISHED
-};
-
-struct fuse_conn;
-
-/**
- * A request to the client
- */
-struct fuse_req {
-       /** This can be on either pending processing or io lists in
-           fuse_conn */
-       struct list_head list;
-
-       /** Entry on the interrupts list  */
-       struct list_head intr_entry;
-
-       /** refcount */
-       atomic_t count;
-
-       /** Unique ID for the interrupt request */
-       u64 intr_unique;
-
-       /*
-        * The following bitfields are either set once before the
-        * request is queued or setting/clearing them is protected by
-        * fuse_conn->lock
-        */
-
-       /** True if the request has reply */
-       unsigned isreply:1;
-
-       /** Force sending of the request even if interrupted */
-       unsigned force:1;
-
-       /** The request was aborted */
-       unsigned aborted:1;
-
-       /** Request is sent in the background */
-       unsigned background:1;
-
-       /** The request has been interrupted */
-       unsigned interrupted:1;
-
-       /** Data is being copied to/from the request */
-       unsigned locked:1;
-
-       /** Request is counted as "waiting" */
-       unsigned waiting:1;
-
-       /** State of the request */
-       enum fuse_req_state state;
-
-       /** The request input */
-       struct fuse_in in;
-
-       /** The request output */
-       struct fuse_out out;
-
-       /** Used to wake up the task waiting for completion of request*/
-       wait_queue_head_t waitq;
-
-       /** Data for asynchronous requests */
-       union {
-               struct fuse_forget_in forget_in;
-               struct fuse_release_in release_in;
-               struct fuse_init_in init_in;
-               struct fuse_init_out init_out;
-               struct fuse_read_in read_in;
-               struct fuse_lk_in lk_in;
-       } misc;
-
-       /** page vector */
-       struct page *pages[FUSE_MAX_PAGES_PER_REQ];
-
-       /** number of pages in vector */
-       unsigned num_pages;
-
-       /** offset of data on first page */
-       unsigned page_offset;
-
-       /** File used in the request (or NULL) */
-       struct file *file;
-
-       /** vfsmount used in release */
-       struct vfsmount *vfsmount;
-
-       /** dentry used in release */
-       struct dentry *dentry;
-
-       /** Request completion callback */
-       void (*end)(struct fuse_conn *, struct fuse_req *);
-
-       /** Request is stolen from fuse_file->reserved_req */
-       struct file *stolen_file;
-};
-
-/**
- * A Fuse connection.
- *
- * This structure is created, when the filesystem is mounted, and is
- * destroyed, when the client device is closed and the filesystem is
- * unmounted.
- */
-struct fuse_conn {
-       /** Lock protecting accessess to  members of this structure */
-       spinlock_t lock;
-
-       /** Mutex protecting against directory alias creation */
-       struct mutex inst_mutex;
-
-       /** Refcount */
-       atomic_t count;
-
-       /** The user id for this mount */
-       uid_t user_id;
-
-       /** The group id for this mount */
-       gid_t group_id;
-
-       /** The fuse mount flags for this mount */
-       unsigned flags;
-
-       /** Maximum read size */
-       unsigned max_read;
-
-       /** Maximum write size */
-       unsigned max_write;
-
-       /** Readers of the connection are waiting on this */
-       wait_queue_head_t waitq;
-
-       /** The list of pending requests */
-       struct list_head pending;
-
-       /** The list of requests being processed */
-       struct list_head processing;
-
-       /** The list of requests under I/O */
-       struct list_head io;
-
-       /** Number of requests currently in the background */
-       unsigned num_background;
-
-       /** Pending interrupts */
-       struct list_head interrupts;
-
-       /** Flag indicating if connection is blocked.  This will be
-           the case before the INIT reply is received, and if there
-           are too many outstading backgrounds requests */
-       int blocked;
-
-       /** waitq for blocked connection */
-       wait_queue_head_t blocked_waitq;
-
-       /** waitq for reserved requests */
-       wait_queue_head_t reserved_req_waitq;
-
-       /** The next unique request id */
-       u64 reqctr;
-
-       /** Connection established, cleared on umount, connection
-           abort and device release */
-       unsigned connected;
-
-       /** Connection failed (version mismatch).  Cannot race with
-           setting other bitfields since it is only set once in INIT
-           reply, before any other request, and never cleared */
-       unsigned conn_error : 1;
-
-       /** Connection successful.  Only set in INIT */
-       unsigned conn_init : 1;
-
-       /** Do readpages asynchronously?  Only set in INIT */
-       unsigned async_read : 1;
-
-       /*
-        * The following bitfields are only for optimization purposes
-        * and hence races in setting them will not cause malfunction
-        */
-
-       /** Is fsync not implemented by fs? */
-       unsigned no_fsync : 1;
-
-       /** Is fsyncdir not implemented by fs? */
-       unsigned no_fsyncdir : 1;
-
-       /** Is flush not implemented by fs? */
-       unsigned no_flush : 1;
-
-       /** Is setxattr not implemented by fs? */
-       unsigned no_setxattr : 1;
-
-       /** Is getxattr not implemented by fs? */
-       unsigned no_getxattr : 1;
-
-       /** Is listxattr not implemented by fs? */
-       unsigned no_listxattr : 1;
-
-       /** Is removexattr not implemented by fs? */
-       unsigned no_removexattr : 1;
-
-       /** Are file locking primitives not implemented by fs? */
-       unsigned no_lock : 1;
-
-       /** Is access not implemented by fs? */
-       unsigned no_access : 1;
-
-       /** Is create not implemented by fs? */
-       unsigned no_create : 1;
-
-       /** Is interrupt not implemented by fs? */
-       unsigned no_interrupt : 1;
-
-       /** Is bmap not implemented by fs? */
-       unsigned no_bmap : 1;
-
-       /** The number of requests waiting for completion */
-       atomic_t num_waiting;
-
-       /** Negotiated minor version */
-       unsigned minor;
-
-       /** Backing dev info */
-       struct backing_dev_info bdi;
-
-       /** Entry on the fuse_conn_list */
-       struct list_head entry;
-
-       /** Unique ID */
-       u64 id;
-
-       /** Dentries in the control filesystem */
-       struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES];
-
-       /** number of dentries used in the above array */
-       int ctl_ndents;
-
-       /** O_ASYNC requests */
-       struct fasync_struct *fasync;
-
-       /** Key for lock owner ID scrambling */
-       u32 scramble_key[4];
-
-       /** Reserved request for the DESTROY message */
-       struct fuse_req *destroy_req;
-};
-
-static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
-{
-       return sb->s_fs_info;
-}
-
-static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
-{
-       return get_fuse_conn_super(inode->i_sb);
-}
-
-static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
-{
-       return container_of(inode, struct fuse_inode, inode);
-}
-
-static inline u64 get_node_id(struct inode *inode)
-{
-       return get_fuse_inode(inode)->nodeid;
-}
-
-/** Device operations */
-extern struct file_operations fuse_dev_operations;
-
-/**
- * Get a filled in inode
- */
-struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-                       int generation, struct fuse_attr *attr);
-
-/**
- * Send FORGET command
- */
-void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
-                     unsigned long nodeid, u64 nlookup);
-
-/**
- * Initialize READ or READDIR request
- */
-void fuse_read_fill(struct fuse_req *req, struct file *file,
-                   struct inode *inode, loff_t pos, size_t count, int opcode);
-
-/**
- * Send OPEN or OPENDIR request
- */
-int fuse_open_common(struct inode *inode, struct file *file, int isdir);
-
-struct fuse_file *fuse_file_alloc(void);
-void fuse_file_free(struct fuse_file *ff);
-void fuse_finish_open(struct inode *inode, struct file *file,
-                     struct fuse_file *ff, struct fuse_open_out *outarg);
-
-/** */
-struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
-                                  int opcode);
-/**
- * Send RELEASE or RELEASEDIR request
- */
-int fuse_release_common(struct inode *inode, struct file *file, int isdir);
-
-/**
- * Send FSYNC or FSYNCDIR request
- */
-int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
-                     int isdir);
-
-/**
- * Initialize file operations on a regular file
- */
-void fuse_init_file_inode(struct inode *inode);
-
-/**
- * Initialize inode operations on regular files and special files
- */
-void fuse_init_common(struct inode *inode);
-
-/**
- * Initialize inode and file operations on a directory
- */
-void fuse_init_dir(struct inode *inode);
-
-/**
- * Initialize inode operations on a symlink
- */
-void fuse_init_symlink(struct inode *inode);
-
-/**
- * Change attributes of an inode
- */
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
-
-/**
- * Initialize the client device
- */
-int fuse_dev_init(void);
-
-/**
- * Cleanup the client device
- */
-void fuse_dev_cleanup(void);
-
-int fuse_ctl_init(void);
-void fuse_ctl_cleanup(void);
-
-/**
- * Allocate a request
- */
-struct fuse_req *fuse_request_alloc(void);
-
-/**
- * Free a request
- */
-void fuse_request_free(struct fuse_req *req);
-
-/**
- * Get a request, may fail with -ENOMEM
- */
-struct fuse_req *fuse_get_req(struct fuse_conn *fc);
-
-/**
- * Gets a requests for a file operation, always succeeds
- */
-struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file);
-
-/**
- * Decrement reference count of a request.  If count goes to zero free
- * the request.
- */
-void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
-
-/**
- * Send a request (synchronous)
- */
-void request_send(struct fuse_conn *fc, struct fuse_req *req);
-
-/**
- * Send a request with no reply
- */
-void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
-
-/**
- * Send a request in the background
- */
-void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
-
-/* Abort all requests */
-void fuse_abort_conn(struct fuse_conn *fc);
-
-/**
- * Get the attributes of a file
- */
-int fuse_do_getattr(struct inode *inode);
-
-/**
- * Invalidate inode attributes
- */
-void fuse_invalidate_attr(struct inode *inode);
-
-/**
- * Acquire reference to fuse_conn
- */
-struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
-
-/**
- * Release reference to fuse_conn
- */
-void fuse_conn_put(struct fuse_conn *fc);
-
-/**
- * Add connection to control filesystem
- */
-int fuse_ctl_add_conn(struct fuse_conn *fc);
-
-/**
- * Remove connection from control filesystem
- */
-void fuse_ctl_remove_conn(struct fuse_conn *fc);
-
-/**
- * Is file type valid?
- */
-int fuse_valid_type(int m);
-
-/**
- * Is task allowed to perform filesystem operation?
- */
-int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
-
-extern struct dentry_operations fuse_dentry_operations;
diff --git a/kernel/fuse_kernel.h b/kernel/fuse_kernel.h
deleted file mode 100644 (file)
index c9c4c7e..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
-    This file defines the kernel interface of FUSE
-    Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-    This program can be distributed under the terms of the GNU GPL.
-    See the file COPYING.
-
-    This -- and only this -- header file may also be distributed under
-    the terms of the BSD Licence as follows:
-
-    Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-
-    THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-*/
-
-/*
- * This file defines the kernel interface of FUSE
- *
- * Protocol changelog:
- *
- * 7.9:
- *  - new fuse_getattr_in input argument of GETATTR
- *  - add lk_flags in fuse_lk_in
- *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
- *  - add blksize field to fuse_attr
- *  - add file flags field to fuse_read_in and fuse_write_in
- */
-
-#ifndef linux
-#include <sys/types.h>
-#define __u64 uint64_t
-#define __u32 uint32_t
-#define __s32 int32_t
-#else
-#include <asm/types.h>
-#include <linux/major.h>
-#endif
-
-/** Version number of this interface */
-#define FUSE_KERNEL_VERSION 7
-
-/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 9
-
-/** The node ID of the root inode */
-#define FUSE_ROOT_ID 1
-
-/** The major number of the fuse character device */
-#define FUSE_MAJOR MISC_MAJOR
-
-/** The minor number of the fuse character device */
-#define FUSE_MINOR 229
-
-/* Make sure all structures are padded to 64bit boundary, so 32bit
-   userspace works under 64bit kernels */
-
-struct fuse_attr {
-       __u64   ino;
-       __u64   size;
-       __u64   blocks;
-       __u64   atime;
-       __u64   mtime;
-       __u64   ctime;
-       __u32   atimensec;
-       __u32   mtimensec;
-       __u32   ctimensec;
-       __u32   mode;
-       __u32   nlink;
-       __u32   uid;
-       __u32   gid;
-       __u32   rdev;
-       __u32   blksize;
-       __u32   padding;
-};
-
-struct fuse_kstatfs {
-       __u64   blocks;
-       __u64   bfree;
-       __u64   bavail;
-       __u64   files;
-       __u64   ffree;
-       __u32   bsize;
-       __u32   namelen;
-       __u32   frsize;
-       __u32   padding;
-       __u32   spare[6];
-};
-
-struct fuse_file_lock {
-       __u64   start;
-       __u64   end;
-       __u32   type;
-       __u32   pid; /* tgid */
-};
-
-/**
- * Bitmasks for fuse_setattr_in.valid
- */
-#define FATTR_MODE     (1 << 0)
-#define FATTR_UID      (1 << 1)
-#define FATTR_GID      (1 << 2)
-#define FATTR_SIZE     (1 << 3)
-#define FATTR_ATIME    (1 << 4)
-#define FATTR_MTIME    (1 << 5)
-#define FATTR_FH       (1 << 6)
-#define FATTR_ATIME_NOW        (1 << 7)
-#define FATTR_MTIME_NOW        (1 << 8)
-#define FATTR_LOCKOWNER        (1 << 9)
-
-/**
- * Flags returned by the OPEN request
- *
- * FOPEN_DIRECT_IO: bypass page cache for this open file
- * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
- */
-#define FOPEN_DIRECT_IO                (1 << 0)
-#define FOPEN_KEEP_CACHE       (1 << 1)
-
-/**
- * INIT request/reply flags
- */
-#define FUSE_ASYNC_READ                (1 << 0)
-#define FUSE_POSIX_LOCKS       (1 << 1)
-#define FUSE_FILE_OPS          (1 << 2)
-#define FUSE_ATOMIC_O_TRUNC    (1 << 3)
-#define FUSE_BIG_WRITES                (1 << 5)
-
-/**
- * Release flags
- */
-#define FUSE_RELEASE_FLUSH     (1 << 0)
-
-/**
- * Getattr flags
- */
-#define FUSE_GETATTR_FH                (1 << 0)
-
-/**
- * Lock flags
- */
-#define FUSE_LK_FLOCK          (1 << 0)
-
-/**
- * WRITE flags
- *
- * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
- * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
- */
-#define FUSE_WRITE_CACHE       (1 << 0)
-#define FUSE_WRITE_LOCKOWNER   (1 << 1)
-
-/**
- * Read flags
- */
-#define FUSE_READ_LOCKOWNER    (1 << 1)
-
-enum fuse_opcode {
-       FUSE_LOOKUP        = 1,
-       FUSE_FORGET        = 2,  /* no reply */
-       FUSE_GETATTR       = 3,
-       FUSE_SETATTR       = 4,
-       FUSE_READLINK      = 5,
-       FUSE_SYMLINK       = 6,
-       FUSE_MKNOD         = 8,
-       FUSE_MKDIR         = 9,
-       FUSE_UNLINK        = 10,
-       FUSE_RMDIR         = 11,
-       FUSE_RENAME        = 12,
-       FUSE_LINK          = 13,
-       FUSE_OPEN          = 14,
-       FUSE_READ          = 15,
-       FUSE_WRITE         = 16,
-       FUSE_STATFS        = 17,
-       FUSE_RELEASE       = 18,
-       FUSE_FSYNC         = 20,
-       FUSE_SETXATTR      = 21,
-       FUSE_GETXATTR      = 22,
-       FUSE_LISTXATTR     = 23,
-       FUSE_REMOVEXATTR   = 24,
-       FUSE_FLUSH         = 25,
-       FUSE_INIT          = 26,
-       FUSE_OPENDIR       = 27,
-       FUSE_READDIR       = 28,
-       FUSE_RELEASEDIR    = 29,
-       FUSE_FSYNCDIR      = 30,
-       FUSE_GETLK         = 31,
-       FUSE_SETLK         = 32,
-       FUSE_SETLKW        = 33,
-       FUSE_ACCESS        = 34,
-       FUSE_CREATE        = 35,
-       FUSE_INTERRUPT     = 36,
-       FUSE_BMAP          = 37,
-       FUSE_DESTROY       = 38,
-};
-
-/* The read buffer is required to be at least 8k, but may be much larger */
-#define FUSE_MIN_READ_BUFFER 8192
-
-#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
-
-struct fuse_entry_out {
-       __u64   nodeid;         /* Inode ID */
-       __u64   generation;     /* Inode generation: nodeid:gen must
-                                  be unique for the fs's lifetime */
-       __u64   entry_valid;    /* Cache timeout for the name */
-       __u64   attr_valid;     /* Cache timeout for the attributes */
-       __u32   entry_valid_nsec;
-       __u32   attr_valid_nsec;
-       struct fuse_attr attr;
-};
-
-struct fuse_forget_in {
-       __u64   nlookup;
-};
-
-struct fuse_getattr_in {
-       __u32   getattr_flags;
-       __u32   dummy;
-       __u64   fh;
-};
-
-#define FUSE_COMPAT_ATTR_OUT_SIZE 96
-
-struct fuse_attr_out {
-       __u64   attr_valid;     /* Cache timeout for the attributes */
-       __u32   attr_valid_nsec;
-       __u32   dummy;
-       struct fuse_attr attr;
-};
-
-struct fuse_mknod_in {
-       __u32   mode;
-       __u32   rdev;
-};
-
-struct fuse_mkdir_in {
-       __u32   mode;
-       __u32   padding;
-};
-
-struct fuse_rename_in {
-       __u64   newdir;
-};
-
-struct fuse_link_in {
-       __u64   oldnodeid;
-};
-
-struct fuse_setattr_in {
-       __u32   valid;
-       __u32   padding;
-       __u64   fh;
-       __u64   size;
-       __u64   lock_owner;
-       __u64   atime;
-       __u64   mtime;
-       __u64   unused2;
-       __u32   atimensec;
-       __u32   mtimensec;
-       __u32   unused3;
-       __u32   mode;
-       __u32   unused4;
-       __u32   uid;
-       __u32   gid;
-       __u32   unused5;
-};
-
-struct fuse_open_in {
-       __u32   flags;
-       __u32   mode;
-};
-
-struct fuse_open_out {
-       __u64   fh;
-       __u32   open_flags;
-       __u32   padding;
-};
-
-struct fuse_release_in {
-       __u64   fh;
-       __u32   flags;
-       __u32   release_flags;
-       __u64   lock_owner;
-};
-
-struct fuse_flush_in {
-       __u64   fh;
-       __u32   unused;
-       __u32   padding;
-       __u64   lock_owner;
-};
-
-struct fuse_read_in {
-       __u64   fh;
-       __u64   offset;
-       __u32   size;
-       __u32   read_flags;
-       __u64   lock_owner;
-       __u32   flags;
-       __u32   padding;
-};
-
-#define FUSE_COMPAT_WRITE_IN_SIZE 24
-
-struct fuse_write_in {
-       __u64   fh;
-       __u64   offset;
-       __u32   size;
-       __u32   write_flags;
-       __u64   lock_owner;
-       __u32   flags;
-       __u32   padding;
-};
-
-struct fuse_write_out {
-       __u32   size;
-       __u32   padding;
-};
-
-#define FUSE_COMPAT_STATFS_SIZE 48
-
-struct fuse_statfs_out {
-       struct fuse_kstatfs st;
-};
-
-struct fuse_fsync_in {
-       __u64   fh;
-       __u32   fsync_flags;
-       __u32   padding;
-};
-
-struct fuse_setxattr_in {
-       __u32   size;
-       __u32   flags;
-};
-
-struct fuse_getxattr_in {
-       __u32   size;
-       __u32   padding;
-};
-
-struct fuse_getxattr_out {
-       __u32   size;
-       __u32   padding;
-};
-
-struct fuse_lk_in {
-       __u64   fh;
-       __u64   owner;
-       struct fuse_file_lock lk;
-       __u32   lk_flags;
-       __u32   padding;
-};
-
-struct fuse_lk_out {
-       struct fuse_file_lock lk;
-};
-
-struct fuse_access_in {
-       __u32   mask;
-       __u32   padding;
-};
-
-struct fuse_init_in {
-       __u32   major;
-       __u32   minor;
-       __u32   max_readahead;
-       __u32   flags;
-};
-
-struct fuse_init_out {
-       __u32   major;
-       __u32   minor;
-       __u32   max_readahead;
-       __u32   flags;
-       __u32   unused;
-       __u32   max_write;
-};
-
-struct fuse_interrupt_in {
-       __u64   unique;
-};
-
-struct fuse_bmap_in {
-       __u64   block;
-       __u32   blocksize;
-       __u32   padding;
-};
-
-struct fuse_bmap_out {
-       __u64   block;
-};
-
-struct fuse_in_header {
-       __u32   len;
-       __u32   opcode;
-       __u64   unique;
-       __u64   nodeid;
-       __u32   uid;
-       __u32   gid;
-       __u32   pid;
-       __u32   padding;
-};
-
-struct fuse_out_header {
-       __u32   len;
-       __s32   error;
-       __u64   unique;
-};
-
-struct fuse_dirent {
-       __u64   ino;
-       __u64   off;
-       __u32   namelen;
-       __u32   type;
-       char name[0];
-};
-
-#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
-#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
-#define FUSE_DIRENT_SIZE(d) \
-       FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
diff --git a/kernel/inode.c b/kernel/inode.c
deleted file mode 100644 (file)
index 0a5900e..0000000
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*
-  FUSE: Filesystem in Userspace
-  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
-
-  This program can be distributed under the terms of the GNU GPL.
-  See the file COPYING.
-*/
-
-#include "fuse_i.h"
-
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/file.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/parser.h>
-#include <linux/statfs.h>
-#include <linux/random.h>
-#include <linux/sched.h>
-
-MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
-MODULE_DESCRIPTION("Filesystem in Userspace");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
-
-static struct kmem_cache *fuse_inode_cachep;
-struct list_head fuse_conn_list;
-DEFINE_MUTEX(fuse_mutex);
-
-#define FUSE_SUPER_MAGIC 0x65735546
-
-#ifndef MAX_LFS_FILESIZE
-#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
-#endif
-struct fuse_mount_data {
-       int fd;
-       unsigned rootmode;
-       unsigned user_id;
-       unsigned group_id;
-       unsigned fd_present : 1;
-       unsigned rootmode_present : 1;
-       unsigned user_id_present : 1;
-       unsigned group_id_present : 1;
-       unsigned flags;
-       unsigned max_read;
-       unsigned blksize;
-};
-
-static struct inode *fuse_alloc_inode(struct super_block *sb)
-{
-       struct inode *inode;
-       struct fuse_inode *fi;
-
-       inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL);
-       if (!inode)
-               return NULL;
-
-       fi = get_fuse_inode(inode);
-       fi->i_time = 0;
-       fi->nodeid = 0;
-       fi->nlookup = 0;
-       fi->forget_req = fuse_request_alloc();
-       if (!fi->forget_req) {
-               kmem_cache_free(fuse_inode_cachep, inode);
-               return NULL;
-       }
-
-       return inode;
-}
-
-static void fuse_destroy_inode(struct inode *inode)
-{
-       struct fuse_inode *fi = get_fuse_inode(inode);
-       if (fi->forget_req)
-               fuse_request_free(fi->forget_req);
-#ifndef KERNEL_2_6_18_PLUS
-       if (inode->i_flock) {
-               WARN_ON(inode->i_flock->fl_next);
-               kfree(inode->i_flock);
-               inode->i_flock = NULL;
-       }
-#endif
-       kmem_cache_free(fuse_inode_cachep, inode);
-}
-
-static void fuse_read_inode(struct inode *inode)
-{
-       /* No op */
-}
-
-void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
-                     unsigned long nodeid, u64 nlookup)
-{
-       struct fuse_forget_in *inarg = &req->misc.forget_in;
-       inarg->nlookup = nlookup;
-       req->in.h.opcode = FUSE_FORGET;
-       req->in.h.nodeid = nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(struct fuse_forget_in);
-       req->in.args[0].value = inarg;
-       request_send_noreply(fc, req);
-}
-
-static void fuse_clear_inode(struct inode *inode)
-{
-       if (inode->i_sb->s_flags & MS_ACTIVE) {
-               struct fuse_conn *fc = get_fuse_conn(inode);
-               struct fuse_inode *fi = get_fuse_inode(inode);
-               fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup);
-               fi->forget_req = NULL;
-       }
-}
-
-static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
-{
-       if (*flags & MS_MANDLOCK)
-               return -EINVAL;
-
-       return 0;
-}
-
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
-{
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
-#ifdef KERNEL_2_6_21_PLUS
-               invalidate_mapping_pages(inode->i_mapping, 0, -1);
-#else
-               invalidate_inode_pages(inode->i_mapping);
-#endif
-
-       inode->i_ino     = attr->ino;
-       inode->i_mode    = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
-       inode->i_nlink   = attr->nlink;
-       inode->i_uid     = attr->uid;
-       inode->i_gid     = attr->gid;
-       spin_lock(&fc->lock);
-       i_size_write(inode, attr->size);
-       spin_unlock(&fc->lock);
-#ifdef HAVE_I_BLKSIZE
-       inode->i_blksize = PAGE_CACHE_SIZE;
-#endif
-       inode->i_blocks  = attr->blocks;
-       inode->i_atime.tv_sec   = attr->atime;
-       inode->i_atime.tv_nsec  = attr->atimensec;
-       inode->i_mtime.tv_sec   = attr->mtime;
-       inode->i_mtime.tv_nsec  = attr->mtimensec;
-       inode->i_ctime.tv_sec   = attr->ctime;
-       inode->i_ctime.tv_nsec  = attr->ctimensec;
-}
-
-static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
-{
-       inode->i_mode = attr->mode & S_IFMT;
-       inode->i_size = attr->size;
-       if (S_ISREG(inode->i_mode)) {
-               fuse_init_common(inode);
-               fuse_init_file_inode(inode);
-       } else if (S_ISDIR(inode->i_mode))
-               fuse_init_dir(inode);
-       else if (S_ISLNK(inode->i_mode))
-               fuse_init_symlink(inode);
-       else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
-                S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
-               fuse_init_common(inode);
-               init_special_inode(inode, inode->i_mode,
-                                  new_decode_dev(attr->rdev));
-       } else
-               BUG();
-}
-
-static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
-{
-       unsigned long nodeid = *(unsigned long *) _nodeidp;
-       if (get_node_id(inode) == nodeid)
-               return 1;
-       else
-               return 0;
-}
-
-static int fuse_inode_set(struct inode *inode, void *_nodeidp)
-{
-       unsigned long nodeid = *(unsigned long *) _nodeidp;
-       get_fuse_inode(inode)->nodeid = nodeid;
-       return 0;
-}
-
-struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-                       int generation, struct fuse_attr *attr)
-{
-       struct inode *inode;
-       struct fuse_inode *fi;
-       struct fuse_conn *fc = get_fuse_conn_super(sb);
-
- retry:
-       inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
-       if (!inode)
-               return NULL;
-
-       if ((inode->i_state & I_NEW)) {
-               inode->i_flags |= S_NOATIME|S_NOCMTIME;
-               inode->i_generation = generation;
-               inode->i_data.backing_dev_info = &fc->bdi;
-               fuse_init_inode(inode, attr);
-               unlock_new_inode(inode);
-       } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
-               /* Inode has changed type, any I/O on the old should fail */
-               make_bad_inode(inode);
-               iput(inode);
-               goto retry;
-       }
-
-       fi = get_fuse_inode(inode);
-       spin_lock(&fc->lock);
-       fi->nlookup ++;
-       spin_unlock(&fc->lock);
-       fuse_change_attributes(inode, attr);
-       return inode;
-}
-
-#ifdef UMOUNT_BEGIN_VFSMOUNT
-static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags)
-{
-       if (flags & MNT_FORCE)
-               fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb));
-}
-#else
-static void fuse_umount_begin(struct super_block *sb)
-{
-       fuse_abort_conn(get_fuse_conn_super(sb));
-}
-#endif
-
-static void fuse_send_destroy(struct fuse_conn *fc)
-{
-       struct fuse_req *req = fc->destroy_req;
-       if (req && fc->conn_init) {
-               fc->destroy_req = NULL;
-               req->in.h.opcode = FUSE_DESTROY;
-               req->force = 1;
-               request_send(fc, req);
-               fuse_put_request(fc, req);
-       }
-}
-
-static void fuse_put_super(struct super_block *sb)
-{
-       struct fuse_conn *fc = get_fuse_conn_super(sb);
-
-       fuse_send_destroy(fc);
-       spin_lock(&fc->lock);
-       fc->connected = 0;
-       fc->blocked = 0;
-       spin_unlock(&fc->lock);
-       /* Flush all readers on this fs */
-       kill_fasync(&fc->fasync, SIGIO, POLL_IN);
-       wake_up_all(&fc->waitq);
-       wake_up_all(&fc->blocked_waitq);
-       wake_up_all(&fc->reserved_req_waitq);
-       mutex_lock(&fuse_mutex);
-       list_del(&fc->entry);
-       fuse_ctl_remove_conn(fc);
-       mutex_unlock(&fuse_mutex);
-       fuse_conn_put(fc);
-}
-
-static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
-{
-       stbuf->f_type    = FUSE_SUPER_MAGIC;
-       stbuf->f_bsize   = attr->bsize;
-       stbuf->f_frsize  = attr->frsize;
-       stbuf->f_blocks  = attr->blocks;
-       stbuf->f_bfree   = attr->bfree;
-       stbuf->f_bavail  = attr->bavail;
-       stbuf->f_files   = attr->files;
-       stbuf->f_ffree   = attr->ffree;
-       stbuf->f_namelen = attr->namelen;
-       /* fsid is left zero */
-}
-
-#ifdef KERNEL_2_6_18_PLUS
-static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
-#else
-static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
-#endif
-{
-#ifdef KERNEL_2_6_18_PLUS
-       struct super_block *sb = dentry->d_sb;
-#endif
-       struct fuse_conn *fc = get_fuse_conn_super(sb);
-       struct fuse_req *req;
-       struct fuse_statfs_out outarg;
-       int err;
-
-       if (!fuse_allow_task(fc, current)) {
-               buf->f_type = FUSE_SUPER_MAGIC;
-               return 0;
-       }
-
-       req = fuse_get_req(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       memset(&outarg, 0, sizeof(outarg));
-       req->in.numargs = 0;
-       req->in.h.opcode = FUSE_STATFS;
-#ifdef KERNEL_2_6_18_PLUS
-       req->in.h.nodeid = get_node_id(dentry->d_inode);
-#endif
-       req->out.numargs = 1;
-       req->out.args[0].size =
-               fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       if (!err)
-               convert_fuse_statfs(buf, &outarg.st);
-       fuse_put_request(fc, req);
-       return err;
-}
-
-enum {
-       OPT_FD,
-       OPT_ROOTMODE,
-       OPT_USER_ID,
-       OPT_GROUP_ID,
-       OPT_DEFAULT_PERMISSIONS,
-       OPT_ALLOW_OTHER,
-       OPT_MAX_READ,
-       OPT_BLKSIZE,
-       OPT_ERR
-};
-
-static match_table_t tokens = {
-       {OPT_FD,                        "fd=%u"},
-       {OPT_ROOTMODE,                  "rootmode=%o"},
-       {OPT_USER_ID,                   "user_id=%u"},
-       {OPT_GROUP_ID,                  "group_id=%u"},
-       {OPT_DEFAULT_PERMISSIONS,       "default_permissions"},
-       {OPT_ALLOW_OTHER,               "allow_other"},
-       {OPT_MAX_READ,                  "max_read=%u"},
-       {OPT_BLKSIZE,                   "blksize=%u"},
-       {OPT_ERR,                       NULL}
-};
-
-static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
-{
-       char *p;
-       memset(d, 0, sizeof(struct fuse_mount_data));
-       d->max_read = ~0;
-       d->blksize = 512;
-
-       /*
-        * For unprivileged mounts use current uid/gid.  Still allow
-        * "user_id" and "group_id" options for compatibility, but
-        * only if they match these values.
-        */
-       if (!capable(CAP_SYS_ADMIN)) {
-               d->user_id = current->uid;
-               d->user_id_present = 1;
-               d->group_id = current->gid;
-               d->group_id_present = 1;
-
-       }
-
-       while ((p = strsep(&opt, ",")) != NULL) {
-               int token;
-               int value;
-               substring_t args[MAX_OPT_ARGS];
-               if (!*p)
-                       continue;
-
-               token = match_token(p, tokens, args);
-               switch (token) {
-               case OPT_FD:
-                       if (match_int(&args[0], &value))
-                               return 0;
-                       d->fd = value;
-                       d->fd_present = 1;
-                       break;
-
-               case OPT_ROOTMODE:
-                       if (match_octal(&args[0], &value))
-                               return 0;
-                       if (!fuse_valid_type(value))
-                               return 0;
-                       d->rootmode = value;
-                       d->rootmode_present = 1;
-                       break;
-
-               case OPT_USER_ID:
-                       if (match_int(&args[0], &value))
-                               return 0;
-                       if (d->user_id_present && d->user_id != value)
-                               return 0;
-                       d->user_id = value;
-                       d->user_id_present = 1;
-                       break;
-
-               case OPT_GROUP_ID:
-                       if (match_int(&args[0], &value))
-                               return 0;
-                       if (d->group_id_present && d->group_id != value)
-                               return 0;
-                       d->group_id = value;
-                       d->group_id_present = 1;
-                       break;
-
-               case OPT_DEFAULT_PERMISSIONS:
-                       d->flags |= FUSE_DEFAULT_PERMISSIONS;
-                       break;
-
-               case OPT_ALLOW_OTHER:
-                       d->flags |= FUSE_ALLOW_OTHER;
-                       break;
-
-               case OPT_MAX_READ:
-                       if (match_int(&args[0], &value))
-                               return 0;
-                       d->max_read = value;
-                       break;
-
-               case OPT_BLKSIZE:
-                       if (!is_bdev || match_int(&args[0], &value))
-                               return 0;
-                       d->blksize = value;
-                       break;
-
-               default:
-                       return 0;
-               }
-       }
-
-       if (!d->fd_present || !d->rootmode_present ||
-           !d->user_id_present || !d->group_id_present)
-               return 0;
-
-       return 1;
-}
-
-static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
-{
-       struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb);
-
-       seq_printf(m, ",user_id=%u", fc->user_id);
-       seq_printf(m, ",group_id=%u", fc->group_id);
-       if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
-               seq_puts(m, ",default_permissions");
-       if (fc->flags & FUSE_ALLOW_OTHER)
-               seq_puts(m, ",allow_other");
-       if (fc->max_read != ~0)
-               seq_printf(m, ",max_read=%u", fc->max_read);
-       return 0;
-}
-
-#ifndef HAVE_KZALLOC
-static void *kzalloc(size_t size, int flags)
-{
-       void *ret = kmalloc(size, flags);
-       if (ret)
-               memset(ret, 0, size);
-       return ret;
-}
-#endif
-static struct fuse_conn *new_conn(void)
-{
-       struct fuse_conn *fc;
-
-       fc = kzalloc(sizeof(*fc), GFP_KERNEL);
-       if (fc) {
-               spin_lock_init(&fc->lock);
-               mutex_init(&fc->inst_mutex);
-               atomic_set(&fc->count, 1);
-               init_waitqueue_head(&fc->waitq);
-               init_waitqueue_head(&fc->blocked_waitq);
-               init_waitqueue_head(&fc->reserved_req_waitq);
-               INIT_LIST_HEAD(&fc->pending);
-               INIT_LIST_HEAD(&fc->processing);
-               INIT_LIST_HEAD(&fc->io);
-               INIT_LIST_HEAD(&fc->interrupts);
-               atomic_set(&fc->num_waiting, 0);
-               fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
-               fc->bdi.unplug_io_fn = default_unplug_io_fn;
-               fc->reqctr = 0;
-               fc->blocked = 1;
-               get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
-       }
-       return fc;
-}
-
-void fuse_conn_put(struct fuse_conn *fc)
-{
-       if (atomic_dec_and_test(&fc->count)) {
-               if (fc->destroy_req)
-                       fuse_request_free(fc->destroy_req);
-               mutex_destroy(&fc->inst_mutex);
-               kfree(fc);
-       }
-}
-
-struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
-{
-       atomic_inc(&fc->count);
-       return fc;
-}
-
-static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
-{
-       struct fuse_attr attr;
-       memset(&attr, 0, sizeof(attr));
-
-       attr.mode = mode;
-       attr.ino = FUSE_ROOT_ID;
-       attr.nlink = 1;
-       return fuse_iget(sb, 1, 0, &attr);
-}
-#ifndef FUSE_MAINLINE
-#ifdef HAVE_EXPORTFS_H
-#include <linux/exportfs.h>
-#endif
-
-struct fuse_inode_handle
-{
-       u64 nodeid;
-       u32 generation;
-};
-
-static struct dentry *fuse_get_dentry(struct super_block *sb,
-                                     struct fuse_inode_handle *handle)
-{
-       struct inode *inode;
-       struct dentry *entry;
-
-       if (handle->nodeid == 0)
-               return ERR_PTR(-ESTALE);
-
-       inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid);
-       if (!inode)
-               return ERR_PTR(-ESTALE);
-       if (inode->i_generation != handle->generation) {
-               iput(inode);
-               return ERR_PTR(-ESTALE);
-       }
-
-       entry = d_alloc_anon(inode);
-       if (!entry) {
-               iput(inode);
-               return ERR_PTR(-ENOMEM);
-       }
-       entry->d_op = &fuse_dentry_operations;
-
-       return entry;
-}
-
-static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len,
-                          int connectable)
-{
-       struct inode *inode = dentry->d_inode;
-       int len = *max_len;
-       int type = 1;
-       u64 nodeid;
-       u32 generation;
-
-       if (len < 3 || (connectable && len < 6))
-               return  255;
-
-       nodeid = get_fuse_inode(inode)->nodeid;
-       generation = inode->i_generation;
-
-       len = 3;
-       fh[0] = (u32)(nodeid >> 32);
-       fh[1] = (u32)(nodeid & 0xffffffff);
-       fh[2] = generation;
-
-       if (connectable && !S_ISDIR(inode->i_mode)) {
-               struct inode *parent;
-
-               spin_lock(&dentry->d_lock);
-               parent = dentry->d_parent->d_inode;
-               nodeid = get_fuse_inode(parent)->nodeid;
-               generation = parent->i_generation;
-
-               fh[3] = (u32)(nodeid >> 32);
-               fh[4] = (u32)(nodeid & 0xffffffff);
-               fh[5] = generation;
-               spin_unlock(&dentry->d_lock);
-
-               len = 6;
-               type = 2;
-       }
-
-       *max_len = len;
-       return type;
-}
-
-#ifdef KERNEL_2_6_24_PLUS
-static struct dentry *fuse_fh_to_dentry(struct super_block *sb,
-               struct fid *fid, int fh_len, int fh_type)
-{
-       struct fuse_inode_handle handle;
-
-       if (fh_len < 3 || fh_type > 2)
-               return NULL;
-
-       handle.nodeid = (u64) fid->raw[0] << 32;
-       handle.nodeid |= (u64) fid->raw[1];
-       handle.generation = fid->raw[2];
-       return fuse_get_dentry(sb, &handle);
-}
-
-static struct dentry *fuse_fh_to_parent(struct super_block *sb,
-               struct fid *fid, int fh_len, int fh_type)
-{
-       struct fuse_inode_handle parent;
-
-       if (fh_type != 2 || fh_len < 6)
-               return NULL;
-
-       parent.nodeid = (u64) fid->raw[3] << 32;
-       parent.nodeid |= (u64) fid->raw[4];
-       parent.generation = fid->raw[5];
-       return fuse_get_dentry(sb, &parent);
-}
-
-
-static const struct export_operations fuse_export_operations = {
-       .fh_to_dentry   = fuse_fh_to_dentry,
-       .fh_to_parent   = fuse_fh_to_parent,
-       .encode_fh      = fuse_encode_fh,
-};
-#else
-static struct dentry *fuse_get_dentry_old(struct super_block *sb, void *objp)
-{
-       return fuse_get_dentry(sb, objp);
-}
-
-static struct export_operations fuse_export_operations;
-
-static struct dentry *fuse_decode_fh(struct super_block *sb, u32 *fh,
-                       int fh_len, int fileid_type,
-                       int (*acceptable)(void *context, struct dentry *de),
-                       void *context)
-{
-       struct fuse_inode_handle handle;
-       struct fuse_inode_handle parent;
-
-       if (fh_len < 3 || fileid_type > 2)
-               return NULL;
-
-       if (fileid_type == 2) {
-               if (fh_len < 6)
-                       return NULL;
-
-               parent.nodeid = (u64) fh[3] << 32;
-               parent.nodeid |= (u64) fh[4];
-               parent.generation = fh[5];
-       } else {
-               parent.nodeid = 0;
-               parent.generation = 0;
-       }
-
-       handle.nodeid = (u64) fh[0] << 32;
-       handle.nodeid |= (u64) fh[1];
-       handle.generation = fh[2];
-
-       return fuse_export_operations.
-               find_exported_dentry(sb, &handle, &parent, acceptable, context);
-}
-
-static struct export_operations fuse_export_operations = {
-       .get_dentry     = fuse_get_dentry_old,
-       .encode_fh      = fuse_encode_fh,
-       .decode_fh      = fuse_decode_fh,
-};
-#endif
-#endif
-
-static struct super_operations fuse_super_operations = {
-       .alloc_inode    = fuse_alloc_inode,
-       .destroy_inode  = fuse_destroy_inode,
-       .read_inode     = fuse_read_inode,
-       .clear_inode    = fuse_clear_inode,
-       .drop_inode     = generic_delete_inode,
-       .remount_fs     = fuse_remount_fs,
-       .put_super      = fuse_put_super,
-       .umount_begin   = fuse_umount_begin,
-       .statfs         = fuse_statfs,
-       .show_options   = fuse_show_options,
-};
-
-static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
-{
-       struct fuse_init_out *arg = &req->misc.init_out;
-
-       if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION)
-               fc->conn_error = 1;
-       else {
-               unsigned long ra_pages;
-
-               if (arg->minor >= 6) {
-                       ra_pages = arg->max_readahead / PAGE_CACHE_SIZE;
-                       if (arg->flags & FUSE_ASYNC_READ)
-                               fc->async_read = 1;
-                       if (!(arg->flags & FUSE_POSIX_LOCKS))
-                               fc->no_lock = 1;
-               } else {
-                       ra_pages = fc->max_read / PAGE_CACHE_SIZE;
-                       fc->no_lock = 1;
-               }
-
-               fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages);
-               fc->minor = arg->minor;
-               fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
-               fc->conn_init = 1;
-       }
-       fuse_put_request(fc, req);
-       fc->blocked = 0;
-       wake_up_all(&fc->blocked_waitq);
-}
-
-static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
-{
-       struct fuse_init_in *arg = &req->misc.init_in;
-
-       arg->major = FUSE_KERNEL_VERSION;
-       arg->minor = FUSE_KERNEL_MINOR_VERSION;
-       arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-       arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
-       req->in.h.opcode = FUSE_INIT;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(*arg);
-       req->in.args[0].value = arg;
-       req->out.numargs = 1;
-       /* Variable length arguement used for backward compatibility
-          with interface version < 7.5.  Rest of init_out is zeroed
-          by do_get_request(), so a short reply is not a problem */
-       req->out.argvar = 1;
-       req->out.args[0].size = sizeof(struct fuse_init_out);
-       req->out.args[0].value = &req->misc.init_out;
-       req->end = process_init_reply;
-       request_send_background(fc, req);
-}
-
-static u64 conn_id(void)
-{
-       static u64 ctr = 1;
-       return ctr++;
-}
-
-static int fuse_fill_super(struct super_block *sb, void *data, int silent)
-{
-       struct fuse_conn *fc;
-       struct inode *root;
-       struct fuse_mount_data d;
-       struct file *file;
-       struct dentry *root_dentry;
-       struct fuse_req *init_req;
-       int err;
-       int is_bdev = sb->s_bdev != NULL;
-
-       if (sb->s_flags & MS_MANDLOCK)
-               return -EINVAL;
-
-       if (!parse_fuse_opt((char *) data, &d, is_bdev))
-               return -EINVAL;
-
-       /* This is a privileged option */
-       if ((d.flags & FUSE_ALLOW_OTHER) && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       if (is_bdev) {
-#ifdef CONFIG_BLOCK
-               if (!sb_set_blocksize(sb, d.blksize))
-                       return -EINVAL;
-#endif
-       } else {
-               sb->s_blocksize = PAGE_CACHE_SIZE;
-               sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-       }
-       sb->s_magic = FUSE_SUPER_MAGIC;
-       sb->s_op = &fuse_super_operations;
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
-#ifndef FUSE_MAINLINE
-       sb->s_export_op = &fuse_export_operations;
-#endif
-
-       file = fget(d.fd);
-       if (!file)
-               return -EINVAL;
-
-       if (file->f_op != &fuse_dev_operations)
-               return -EINVAL;
-
-       fc = new_conn();
-       if (!fc)
-               return -ENOMEM;
-
-       fc->flags = d.flags;
-       fc->user_id = d.user_id;
-       fc->group_id = d.group_id;
-       fc->max_read = d.max_read;
-
-       /* Used by get_root_inode() */
-       sb->s_fs_info = fc;
-
-       err = -ENOMEM;
-       root = get_root_inode(sb, d.rootmode);
-       if (!root)
-               goto err;
-
-       root_dentry = d_alloc_root(root);
-       if (!root_dentry) {
-               iput(root);
-               goto err;
-       }
-
-       init_req = fuse_request_alloc();
-       if (!init_req)
-               goto err_put_root;
-
-       if (is_bdev) {
-               fc->destroy_req = fuse_request_alloc();
-               if (!fc->destroy_req)
-                       goto err_put_root;
-       }
-
-       mutex_lock(&fuse_mutex);
-       err = -EINVAL;
-       if (file->private_data)
-               goto err_unlock;
-
-       fc->id = conn_id();
-       err = fuse_ctl_add_conn(fc);
-       if (err)
-               goto err_unlock;
-
-       list_add_tail(&fc->entry, &fuse_conn_list);
-       sb->s_root = root_dentry;
-       fc->connected = 1;
-       file->private_data = fuse_conn_get(fc);
-       mutex_unlock(&fuse_mutex);
-       /*
-        * atomic_dec_and_test() in fput() provides the necessary
-        * memory barrier for file->private_data to be visible on all
-        * CPUs after this
-        */
-       fput(file);
-
-       fuse_send_init(fc, init_req);
-
-       return 0;
-
- err_unlock:
-       mutex_unlock(&fuse_mutex);
-       fuse_request_free(init_req);
- err_put_root:
-       dput(root_dentry);
- err:
-       fput(file);
-       fuse_conn_put(fc);
-       return err;
-}
-
-#ifdef KERNEL_2_6_18_PLUS
-static int fuse_get_sb(struct file_system_type *fs_type,
-                      int flags, const char *dev_name,
-                      void *raw_data, struct vfsmount *mnt)
-{
-       return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt);
-}
-#else
-static struct super_block *fuse_get_sb(struct file_system_type *fs_type,
-                                      int flags, const char *dev_name,
-                                      void *raw_data)
-{
-       return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);
-}
-#endif
-
-static struct file_system_type fuse_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "fuse",
-       .get_sb         = fuse_get_sb,
-       .kill_sb        = kill_anon_super,
-       .fs_flags       = FS_HAS_SUBTYPE | FS_SAFE,
-};
-
-#ifdef CONFIG_BLOCK
-#ifdef KERNEL_2_6_18_PLUS
-static int fuse_get_sb_blk(struct file_system_type *fs_type,
-                          int flags, const char *dev_name,
-                          void *raw_data, struct vfsmount *mnt)
-{
-       return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super,
-                          mnt);
-}
-#else
-static struct super_block *fuse_get_sb_blk(struct file_system_type *fs_type,
-                                          int flags, const char *dev_name,
-                                          void *raw_data)
-{
-       return get_sb_bdev(fs_type, flags, dev_name, raw_data,
-                          fuse_fill_super);
-}
-#endif
-
-static struct file_system_type fuseblk_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "fuseblk",
-       .get_sb         = fuse_get_sb_blk,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
-};
-
-static inline int register_fuseblk(void)
-{
-       return register_filesystem(&fuseblk_fs_type);
-}
-
-static inline void unregister_fuseblk(void)
-{
-       unregister_filesystem(&fuseblk_fs_type);
-}
-#else
-static inline int register_fuseblk(void)
-{
-       return 0;
-}
-
-static inline void unregister_fuseblk(void)
-{
-}
-#endif
-
-#ifndef HAVE_FS_SUBSYS
-static decl_subsys(fs, NULL, NULL);
-#endif
-static decl_subsys(fuse, NULL, NULL);
-static decl_subsys(connections, NULL, NULL);
-
-#ifdef KERNEL_2_6_24_PLUS
-static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo)
-#else
-static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep,
-                                unsigned long flags)
-#endif
-{
-       struct inode * inode = foo;
-
-#ifndef KERNEL_2_6_22_PLUS
-       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-           SLAB_CTOR_CONSTRUCTOR)
-#endif
-       inode_init_once(inode);
-}
-
-static int __init fuse_fs_init(void)
-{
-       int err;
-
-       err = register_filesystem(&fuse_fs_type);
-       if (err)
-               goto out;
-
-       err = register_fuseblk();
-       if (err)
-               goto out_unreg;
-
-#ifdef KERNEL_2_6_23_PLUS
-       fuse_inode_cachep = kmem_cache_create("fuse_inode",
-                                             sizeof(struct fuse_inode),
-                                             0, SLAB_HWCACHE_ALIGN,
-                                             fuse_inode_init_once);
-#else
-       fuse_inode_cachep = kmem_cache_create("fuse_inode",
-                                             sizeof(struct fuse_inode),
-                                             0, SLAB_HWCACHE_ALIGN,
-                                             fuse_inode_init_once, NULL);
-#endif
-
-       err = -ENOMEM;
-       if (!fuse_inode_cachep)
-               goto out_unreg2;
-
-       return 0;
-
- out_unreg2:
-       unregister_fuseblk();
- out_unreg:
-       unregister_filesystem(&fuse_fs_type);
- out:
-       return err;
-}
-
-static void fuse_fs_cleanup(void)
-{
-       unregister_filesystem(&fuse_fs_type);
-       unregister_fuseblk();
-       kmem_cache_destroy(fuse_inode_cachep);
-}
-
-static int fuse_sysfs_init(void)
-{
-       int err;
-
-#ifndef HAVE_FS_SUBSYS
-       err = subsystem_register(&fs_subsys);
-       if (err)
-               return err;
-#endif
-#ifdef KERNEL_2_6_22_PLUS
-       kobj_set_kset_s(&fuse_subsys, fs_subsys);
-#else
-       kset_set_kset_s(&fuse_subsys, fs_subsys);
-#endif
-       err = subsystem_register(&fuse_subsys);
-       if (err)
-               goto out_err;
-
-#ifdef KERNEL_2_6_22_PLUS
-       kobj_set_kset_s(&connections_subsys, fuse_subsys);
-#else
-       kset_set_kset_s(&connections_subsys, fuse_subsys);
-#endif
-       err = subsystem_register(&connections_subsys);
-       if (err)
-               goto out_fuse_unregister;
-
-       return 0;
-
- out_fuse_unregister:
-       subsystem_unregister(&fuse_subsys);
- out_err:
-#ifndef HAVE_FS_SUBSYS
-       subsystem_unregister(&fs_subsys);
-#endif
-       return err;
-}
-
-static void fuse_sysfs_cleanup(void)
-{
-       subsystem_unregister(&connections_subsys);
-       subsystem_unregister(&fuse_subsys);
-#ifndef HAVE_FS_SUBSYS
-       subsystem_unregister(&fs_subsys);
-#endif
-}
-
-static int __init fuse_init(void)
-{
-       int res;
-
-       printk("fuse init (API version %i.%i)\n",
-              FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
-#ifndef FUSE_MAINLINE
-       printk("fuse distribution version: %s\n", FUSE_VERSION);
-#endif
-
-       INIT_LIST_HEAD(&fuse_conn_list);
-       res = fuse_fs_init();
-       if (res)
-               goto err;
-
-       res = fuse_dev_init();
-       if (res)
-               goto err_fs_cleanup;
-
-       res = fuse_sysfs_init();
-       if (res)
-               goto err_dev_cleanup;
-
-       res = fuse_ctl_init();
-       if (res)
-               goto err_sysfs_cleanup;
-
-       return 0;
-
- err_sysfs_cleanup:
-       fuse_sysfs_cleanup();
- err_dev_cleanup:
-       fuse_dev_cleanup();
- err_fs_cleanup:
-       fuse_fs_cleanup();
- err:
-       return res;
-}
-
-static void __exit fuse_exit(void)
-{
-       printk(KERN_DEBUG "fuse exit\n");
-
-       fuse_ctl_cleanup();
-       fuse_sysfs_cleanup();
-       fuse_fs_cleanup();
-       fuse_dev_cleanup();
-}
-
-module_init(fuse_init);
-module_exit(fuse_exit);
index 179cd68cb2bd5e3c22e81e54efc2d2b24d66ea79..6678bdd90389fc2e90815207325112c8ba1f609c 100755 (executable)
@@ -40,8 +40,6 @@ else
        autoconf
     )
 fi
-echo Linking kernel header file...
-ln -sf ../kernel/fuse_kernel.h `dirname $0`/include
 
 rm -f config.cache config.status
 echo "To compile run './configure', and then 'make'."