fix
diff --git a/kernel/cleanup.sh b/kernel/cleanup.sh
index 9d7b92b..7c2f309 100755
--- a/kernel/cleanup.sh
+++ b/kernel/cleanup.sh
@@ -16,6 +16,6 @@
 
 
 for f in dev.c dir.c file.c inode.c util.c fuse_i.h; do
-    unifdef -DKERNEL_2_6 -DKERNEL_2_6_6_PLUS -DKERNEL_2_6_10_PLUS -DHAVE_KERNEL_XATTR -DFS_SAFE -DMAX_LFS_FILESIZE -DFUSE_MAINLINE -DBUG_ON -DHAVE_FS_SUBSYS -D__user -DMODULE_LICENSE $f > $destdir/fs/fuse/$f
+    unifdef -DKERNEL_2_6 -DKERNEL_2_6_6_PLUS -DKERNEL_2_6_10_PLUS -DHAVE_KERNEL_XATTR -DFS_SAFE -DMAX_LFS_FILESIZE -DFUSE_MAINLINE -DBUG_ON -D__user -DMODULE_LICENSE $f > $destdir/fs/fuse/$f
 done
 cp fuse_kernel.h $destdir/include/linux/fuse.h
diff --git a/kernel/configure.ac b/kernel/configure.ac
index e6bf669..20a54fc 100644
--- a/kernel/configure.ac
+++ b/kernel/configure.ac
@@ -49,14 +49,6 @@
 	CFLAGS="$old_cflags"
 fi
 
-AC_MSG_CHECKING([whether fs_subsys is declared])
-if grep -q fs_subsys $kernelsrc/include/linux/fs.h; then
-	AC_DEFINE(HAVE_FS_SUBSYS, 1, [Kernel defines fs_subsys])
-	AC_MSG_RESULT([yes])
-else
-	AC_MSG_RESULT([no])
-fi
-
 AC_MSG_CHECKING([if kernel has extended attribute support])
 if test -f $kernelsrc/include/linux/xattr.h; then
 	AC_DEFINE(HAVE_KERNEL_XATTR, 1, [Kernel has xattr support])
diff --git a/kernel/dev.c b/kernel/dev.c
index bfd2bd7..a2a44e4 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -12,11 +12,6 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/uio.h>
-#ifdef KERNEL_2_6
-#include <linux/kobject.h>
-#else
-#include <linux/proc_fs.h>
-#endif
 #include <linux/miscdevice.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
@@ -128,7 +123,7 @@
 {
 	if (down_interruptible(&fc->outstanding_sem))
 		return NULL;
-	return  do_get_request(fc);
+	return do_get_request(fc);
 }
 
 struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
@@ -180,6 +175,13 @@
 			fput(req->file);
 	}
 	wake_up(&req->waitq);
+	if (req->in.h.opcode == FUSE_INIT) {
+		int i;
+		/* up() one less than FUSE_MAX_OUTSTANDING, because
+		   fuse_putback_request() will also do an up() */
+		for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
+			up(&fc->outstanding_sem);
+	}
 	if (putback)
 		fuse_putback_request(fc, req);
 }
@@ -332,6 +334,24 @@
 	request_send_nowait(fc, req);
 }
 
+void fuse_send_init(struct fuse_conn *fc)
+{
+	/* This is called from fuse_read_super() so there's guaranteed
+	   to be a request available */
+	struct fuse_req *req = do_get_request(fc);
+	struct fuse_init_in_out *arg = &req->misc.init_in_out;
+	arg->major = FUSE_KERNEL_VERSION;
+	arg->minor = FUSE_KERNEL_MINOR_VERSION;
+	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;
+	req->out.args[0].size = sizeof(*arg);
+	req->out.args[0].value = arg;
+	request_send_background(fc, req);
+}
+
 static inline int lock_request(struct fuse_req *req)
 {
 	int err = 0;
@@ -798,85 +818,6 @@
 	.release	= fuse_dev_release,
 };
 
-#ifdef KERNEL_2_6
-#ifndef HAVE_FS_SUBSYS
-static decl_subsys(fs, NULL, NULL);
-#endif
-static decl_subsys(fuse, NULL, NULL);
-
-static ssize_t version_show(struct subsystem *subsys, char *buf)
-{
-	return sprintf(buf, "%i.%i\n", FUSE_KERNEL_VERSION,
-		       FUSE_KERNEL_MINOR_VERSION);
-}
-static struct subsys_attribute fuse_attr_version = __ATTR_RO(version);
-
-static int __init fuse_version_init(void)
-{
-	int err;
-
-#ifndef HAVE_FS_SUBSYS
-	subsystem_register(&fs_subsys);
-#endif
-	kset_set_kset_s(&fuse_subsys, fs_subsys);
-	err = subsystem_register(&fuse_subsys);
-	if (err)
-		return err;
-	err = subsys_create_file(&fuse_subsys, &fuse_attr_version);
-	if (err) {
-		subsystem_unregister(&fuse_subsys);
-#ifndef HAVE_FS_SUBSYS
-		subsystem_unregister(&fs_subsys);
-#endif
-		return err;
-	}
-	return 0;
-}
-
-static void fuse_version_clean(void)
-{
-	subsys_remove_file(&fuse_subsys, &fuse_attr_version);
-	subsystem_unregister(&fuse_subsys);
-#ifndef HAVE_FS_SUBSYS
-	subsystem_unregister(&fs_subsys);
-#endif
-}
-#else
-static struct proc_dir_entry *proc_fs_fuse;
-
-static int read_version(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
-{
-	char *s = page;
-	s += sprintf(s, "%i.%i\n", FUSE_KERNEL_VERSION,
-		     FUSE_KERNEL_MINOR_VERSION);
-	return s - page;
-}
-
-static int fuse_version_init(void)
-{
-	proc_fs_fuse = proc_mkdir("fuse", proc_root_fs);
-	if (proc_fs_fuse) {
-		struct proc_dir_entry *de;
-
-		de = create_proc_entry("version", S_IFREG | 0444, proc_fs_fuse);
-		if (de) {
-			de->owner = THIS_MODULE;
-			de->read_proc = read_version;
-		}
-	}
-	return 0;
-}
-
-static void fuse_version_clean(void)
-{
-	if (proc_fs_fuse) {
-		remove_proc_entry("version", proc_fs_fuse);
-		remove_proc_entry("fuse", proc_root_fs);
-	}
-}
-#endif
-
 static struct miscdevice fuse_miscdevice = {
 	.minor = FUSE_MINOR,
 	.name  = "fuse",
@@ -885,17 +826,12 @@
 
 int __init fuse_dev_init(void)
 {
-	int err;
-	err = fuse_version_init();
-	if (err)
-		goto out;
-
-	err = -ENOMEM;
+	int err = -ENOMEM;
 	fuse_req_cachep = kmem_cache_create("fuser_request",
 					    sizeof(struct fuse_req),
 					    0, 0, NULL, NULL);
 	if (!fuse_req_cachep)
-		goto out_version_clean;
+		goto out;
 
 	err = misc_register(&fuse_miscdevice);
 	if (err)
@@ -905,8 +841,6 @@
 
  out_cache_clean:
 	kmem_cache_destroy(fuse_req_cachep);
- out_version_clean:
-	fuse_version_clean();
  out:
 	return err;
 }
@@ -915,5 +849,4 @@
 {
 	misc_deregister(&fuse_miscdevice);
 	kmem_cache_destroy(fuse_req_cachep);
-	fuse_version_clean();
 }
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index fa0c497..48211bc 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -216,6 +216,7 @@
 	union {
 		struct fuse_forget_in forget_in;
 		struct fuse_release_in release_in;
+		struct fuse_init_in_out init_in_out;
 	} misc;
 
 	/** page vector */
@@ -482,3 +483,8 @@
  * Invalidate inode attributes
  */
 void fuse_invalidate_attr(struct inode *inode);
+
+/**
+ * Send the INIT message
+ */
+void fuse_send_init(struct fuse_conn *fc);
diff --git a/kernel/fuse_kernel.h b/kernel/fuse_kernel.h
index bad4546..d76b5d1 100644
--- a/kernel/fuse_kernel.h
+++ b/kernel/fuse_kernel.h
@@ -79,13 +79,13 @@
 	FUSE_WRITE	   = 16,
 	FUSE_STATFS	   = 17,
 	FUSE_RELEASE       = 18,
-	/*FUSE_INVALIDATE    = 19,*/
 	FUSE_FSYNC         = 20,
 	FUSE_SETXATTR      = 21,
 	FUSE_GETXATTR      = 22,
 	FUSE_LISTXATTR     = 23,
 	FUSE_REMOVEXATTR   = 24,
 	FUSE_FLUSH         = 25,
+	FUSE_INIT          = 26
 };
 
 /* Conservative buffer size for the client */
@@ -201,6 +201,11 @@
 	__u32	size;
 };
 
+struct fuse_init_in_out {
+	__u32	major;
+	__u32	minor;
+};
+
 struct fuse_in_header {
 	__u32	len;
 	__u32	opcode;
diff --git a/kernel/inode.c b/kernel/inode.c
index eb40b7b..8227be8 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -478,14 +478,13 @@
 		INIT_LIST_HEAD(&fc->pending);
 		INIT_LIST_HEAD(&fc->processing);
 		INIT_LIST_HEAD(&fc->unused_list);
-		sema_init(&fc->outstanding_sem, FUSE_MAX_OUTSTANDING);
+		sema_init(&fc->outstanding_sem, 0);
 		for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
 			struct fuse_req *req = fuse_request_alloc();
 			if (!req) {
 				free_conn(fc);
 				return NULL;
 			}
-			req->preallocated = 1;
 			list_add(&req->list, &fc->unused_list);
 		}
 #ifdef KERNEL_2_6
@@ -668,7 +667,7 @@
 		iput(root);
 		goto err;
 	}
-
+	fuse_send_init(fc);
 	return 0;
 
  err: