various fixes
diff --git a/ChangeLog b/ChangeLog
index 61d8293..e8d2cac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2004-11-23  Miklos Szeredi <miklos@szeredi.hu>
+
+	* More cleanups in the kernel
+
+	* The 10,229 charater device number has been assigned for FUSE
+
+	* Version file checking fix (reported by Christian Magnusson)
+
+	* fusermount: opening the fuse device now doesn't need /sys.
+
+	* Optimize reading by controlling the maximum readahead based on
+	the 'max_read' mount option
+
+	* fixes for UCLIBC (Christian Magnusson)
+
 2004-11-19  Miklos Szeredi <miklos@szeredi.hu>
 
 	* Cleaned up kernel in preparation for merge into mainline:
diff --git a/kernel/dev.c b/kernel/dev.c
index 7261770..da41e59 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -8,6 +8,7 @@
 
 #include "fuse_i.h"
 
+#include <linux/init.h>
 #include <linux/module.h>
 #include <linux/poll.h>
 #ifdef KERNEL_2_6
@@ -261,7 +262,6 @@
 	else if (!list_empty(&fc->pending)) {
 		req = list_entry(fc->pending.next, struct fuse_req, list);
 		list_del_init(&req->list);
-		req->locked = 1;
 	}
 	spin_unlock(&fuse_lock);
 	if (!fc)
@@ -275,12 +275,9 @@
 		if (ret < 0) {
 			req->out.h.error = -EPROTO;
 			req->finished = 1;
-		} else {
+		} else
 			list_add_tail(&req->list, &fc->processing);
-			req->sent = 1;
-		}
-		req->locked = 0;
-		if (ret < 0 || req->interrupted)
+		if (ret < 0)
 			/* Unlocks fuse_lock: */
 			request_end(fc, req);
 		else
@@ -471,10 +468,8 @@
 
 	spin_lock(&fuse_lock);
 	req = request_find(fc, oh.unique);
-	if (req != NULL) {
+	if (req != NULL)
 		list_del_init(&req->list);
-		req->locked = 1;
-	}
 	spin_unlock(&fuse_lock);
 	if (!req)
 		return -ENOENT;
@@ -491,7 +486,6 @@
 			process_getdir(req);
 	}	
 	req->finished = 1;
-	req->locked = 0;
 	/* Unlocks fuse_lock: */
 	request_end(fc, req);
 
@@ -565,7 +559,6 @@
 };
 
 #ifdef KERNEL_2_6
-#define FUSE_MINOR MISC_DYNAMIC_MINOR
 
 #ifndef FUSE_MAINLINE
 static decl_subsys(fs, NULL, NULL);
diff --git a/kernel/dir.c b/kernel/dir.c
index 124bf86..fe8e803 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -111,6 +111,7 @@
 			int generation, struct fuse_attr *attr, int version)
 {
 	struct inode *inode;
+	struct fuse_conn *fc = SB_FC(sb);
 
 	inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
 	if (!inode)
@@ -118,6 +119,7 @@
 
 	if ((inode->i_state & I_NEW)) {
 		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_generation != generation)
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index e454fd0..c5b8e23 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -42,6 +42,10 @@
 #include <linux/wait.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#ifdef KERNEL_2_6
+#include <linux/mm.h>
+#include <linux/backing-dev.h>
+#endif
 #include <asm/semaphore.h>
 
 #ifndef BUG_ON
@@ -152,15 +156,6 @@
 	/** True if the request has reply */
 	unsigned int isreply:1;
 
-	/** The request is locked */
-	unsigned int locked:1;
-
-	/** The request has been interrupted while it was locked */
-	unsigned int interrupted:1;
-
-	/* The request has been sent to the client */
-	unsigned int sent:1;
-
 	/* The request is preallocated */
 	unsigned int preallocated:1;
 
@@ -264,6 +259,11 @@
 
 	/** Is removexattr not implemented by fs? */
 	unsigned int no_removexattr : 1;
+
+#ifdef KERNEL_2_6
+	/** Backing dev info */
+	struct backing_dev_info bdi;
+#endif
 };
 
 struct fuse_getdir_out_i {
@@ -283,7 +283,16 @@
 extern struct file_operations fuse_dev_operations;
 
 /**
- * The lock to protect fuses structures
+ * This is the single global spinlock which protects FUSE's structures
+ *
+ * The following data is protected by this lock:
+ * 
+ *  - the private_data field of the device file
+ *  - the s_fs_info field of the super block
+ *  - unused_list, pending, processing lists in fuse_conn
+ *  - the unique request ID counter reqctr in fuse_conn
+ *  - the sb (super_block) field in fuse_conn
+ *  - the file (device file) field in fuse_conn
  */
 extern spinlock_t fuse_lock;
 
@@ -336,7 +345,6 @@
  */
 void fuse_fs_cleanup(void);
 
-
 /** 
  * Allocate a request
  */
diff --git a/kernel/inode.c b/kernel/inode.c
index 55a283b..8cae834 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -178,7 +178,9 @@
 	OPT_ALLOW_OTHER,
 	OPT_ALLOW_ROOT,
 	OPT_KERNEL_CACHE,
+#ifndef FUSE_MAINLINE
 	OPT_LARGE_READ,
+#endif
 	OPT_DIRECT_IO,
 	OPT_MAX_READ,
 	OPT_ERR 
@@ -192,7 +194,9 @@
 	{OPT_ALLOW_OTHER,		"allow_other"},
 	{OPT_ALLOW_ROOT,		"allow_root"},
 	{OPT_KERNEL_CACHE,		"kernel_cache"},
+#ifndef FUSE_MAINLINE
 	{OPT_LARGE_READ,		"large_read"},
+#endif
 	{OPT_DIRECT_IO,			"direct_io"},
 	{OPT_MAX_READ,			"max_read=%u"},
 	{OPT_ERR,			NULL}
@@ -247,7 +251,8 @@
 		case OPT_KERNEL_CACHE:
 			d->flags |= FUSE_KERNEL_CACHE;
 			break;
-			
+
+#ifndef FUSE_MAINLINE			
 		case OPT_LARGE_READ:
 #ifndef KERNEL_2_6
 			d->flags |= FUSE_LARGE_READ;
@@ -261,7 +266,7 @@
 			}
 #endif
 			break;
-			
+#endif			
 		case OPT_DIRECT_IO:
 			d->flags |= FUSE_DIRECT_IO;
 			break;
@@ -351,6 +356,10 @@
 			req->preallocated = 1;
 			list_add(&req->list, &fc->unused_list);
 		}
+#ifdef KERNEL_2_6
+		fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
+		fc->bdi.unplug_io_fn = default_unplug_io_fn;
+#endif
 		fc->reqctr = 1;
 	}
 	return fc;
@@ -502,6 +511,10 @@
 	fc->flags = d.flags;
 	fc->uid = d.uid;
 	fc->max_read = d.max_read;
+#ifdef KERNEL_2_6
+	if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
+		fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
+#endif
 	fc->max_write = FUSE_MAX_IN / 2;
 	
 	SB_FC(sb) = fc;
diff --git a/kernel/linux/fuse.h b/kernel/linux/fuse.h
index f5f7405..ea640e9 100644
--- a/kernel/linux/fuse.h
+++ b/kernel/linux/fuse.h
@@ -17,6 +17,12 @@
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
 
+/** The major number of the fuse character device */
+#define FUSE_MAJOR 10
+
+/** The minor number of the fuse character device */
+#define FUSE_MINOR 229
+
 /** Opening this will yield a new control file */
 #define FUSE_DEV "/dev/fuse"
 
diff --git a/lib/fuse.c b/lib/fuse.c
index b29db9d..59f8b45 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -17,6 +17,9 @@
 #include <errno.h>
 #include <sys/param.h>
 
+#define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
+#define FUSE_DEV_OLD "/proc/fs/fuse/dev"
+
 #define FUSE_MAX_PATH 4096
 #define PARAM(inarg) (((char *)(inarg)) + sizeof(*inarg))
 
@@ -1722,12 +1725,18 @@
     const char *version_file = FUSE_VERSION_FILE;
     FILE *vf = fopen(version_file, "r");
     if (vf == NULL) {
-        version_file = "/sys/fs/fuse/version";
+        version_file = FUSE_VERSION_FILE_OLD;
         vf = fopen(version_file, "r");
         if (vf == NULL) {
-            fprintf(stderr, "fuse: kernel interface too old, need >= %i.%i\n",
-                    FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
-            return -1;
+            struct stat tmp;
+            if (stat(FUSE_DEV_OLD, &tmp) != -1) {
+                fprintf(stderr, "fuse: kernel interface too old, need >= %i.%i\n",
+                        FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+                return -1;
+            } else {
+                fprintf(stderr, "fuse: warning: version of kernel interface unknown\n");
+                return 0;
+            }
         }
     }
     res = fscanf(vf, "%i.%i", &f->majorver, &f->minorver);
@@ -1817,7 +1826,17 @@
     if (f->id_table == NULL)
         goto out_free_name_table;
 
-    pthread_mutex_init(&f->lock, NULL);
+#ifndef USE_UCLIBC
+     pthread_mutex_init(&f->lock, NULL);
+#else
+     {
+         pthread_mutexattr_t attr;
+         pthread_mutexattr_init(&attr);
+         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+         pthread_mutex_init(&f->lock, &attr);
+         pthread_mutexattr_destroy(&attr);
+     }
+#endif
     f->numworker = 0;
     f->numavail = 0;
     f->op = *op;
diff --git a/lib/mount.c b/lib/mount.c
index 05dcb59..a84dbee 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -91,7 +91,11 @@
         return -1;
     }
 
+#ifndef USE_UCLIBC
     pid = fork();
+#else
+    pid = vfork();
+#endif
     if(pid == -1) {
         perror("fuse: fork() failed");
         close(fds[0]);
diff --git a/util/fusermount.c b/util/fusermount.c
index 98a705b..a7d26ed 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -38,8 +38,8 @@
 #define FUSE_COMMFD_ENV         "_FUSE_COMMFD"
 
 #define FUSE_DEV_OLD "/proc/fs/fuse/dev"
-#define FUSE_DEV_NEW "/dev/fuse"
 #define FUSE_SYS_DEV "/sys/class/misc/fuse/dev"
+#define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
 
 const char *progname;
 
@@ -54,6 +54,94 @@
     }
 }
 
+#ifndef USE_UCLIBC
+/* Until there is a nice interface for capabilities in _libc_, this will
+remain here.  I don't think it is fair to expect users to compile libcap
+for this program.  And anyway what's all this fuss about versioning the
+kernel interface?  It is quite good as is.  */
+#define _LINUX_CAPABILITY_VERSION  0x19980330
+
+typedef struct __user_cap_header_struct {
+    unsigned int version;
+    int pid;
+} *cap_user_header_t;
+ 
+typedef struct __user_cap_data_struct {
+    unsigned int effective;
+    unsigned int permitted;
+    unsigned int inheritable;
+} *cap_user_data_t;
+  
+int capget(cap_user_header_t header, cap_user_data_t data);
+int capset(cap_user_header_t header, cap_user_data_t data);
+
+#define CAP_SYS_ADMIN        21
+
+static uid_t oldfsuid;
+static gid_t oldfsgid;
+static struct __user_cap_data_struct oldcaps;
+
+static int drop_privs(void)
+{
+    int res;
+    struct __user_cap_header_struct head;
+    struct __user_cap_data_struct newcaps;
+
+    head.version = _LINUX_CAPABILITY_VERSION;
+    head.pid = 0;
+    res = capget(&head, &oldcaps);
+    if (res == -1) {
+        fprintf(stderr, "%s: failed to get capabilities: %s\n", progname,
+                strerror(errno));
+        return -1;
+    }
+
+    oldfsuid = setfsuid(getuid());
+    oldfsgid = setfsgid(getgid());
+    newcaps = oldcaps;
+    /* Keep CAP_SYS_ADMIN for mount */
+    newcaps.effective &= (1 << CAP_SYS_ADMIN);
+
+    head.version = _LINUX_CAPABILITY_VERSION;
+    head.pid = 0;
+    res = capset(&head, &newcaps);
+    if (res == -1) {
+        setfsuid(oldfsuid);
+        setfsgid(oldfsgid);
+        fprintf(stderr, "%s: failed to set capabilities: %s\n", progname,
+                strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+static void restore_privs(void)
+{
+    struct __user_cap_header_struct head;
+    int res;
+
+    head.version = _LINUX_CAPABILITY_VERSION;
+    head.pid = 0;
+    res = capset(&head, &oldcaps);
+    if (res == -1)
+        fprintf(stderr, "%s: failed to restore capabilities: %s\n", progname,
+                strerror(errno));
+    
+    setfsuid(oldfsuid);
+    setfsgid(oldfsgid);
+}
+#else /* USE_UCLIBC */
+static int drop_privs(void)
+{
+    return 0;
+}
+static void restore_privs(void)
+{
+}
+#endif /* USE_UCLIBC */
+
+
+#ifndef USE_UCLIBC
 /* use a lock file so that multiple fusermount processes don't try and
    modify the mtab file at once! */
 static int lock_mtab()
@@ -113,88 +201,10 @@
     return 0;
 }
 
-
-/* Until there is a nice interface for capabilities in _libc_, this will
-remain here.  I don't think it is fair to expect users to compile libcap
-for this program.  And anyway what's all this fuss about versioning the
-kernel interface?  It is quite good as is.  */
-#define _LINUX_CAPABILITY_VERSION  0x19980330
-
-typedef struct __user_cap_header_struct {
-    unsigned int version;
-    int pid;
-} *cap_user_header_t;
- 
-typedef struct __user_cap_data_struct {
-    unsigned int effective;
-    unsigned int permitted;
-    unsigned int inheritable;
-} *cap_user_data_t;
-  
-int capget(cap_user_header_t header, cap_user_data_t data);
-int capset(cap_user_header_t header, cap_user_data_t data);
-
-#define CAP_SYS_ADMIN        21
-
-static uid_t oldfsuid;
-static gid_t oldfsgid;
-static struct __user_cap_data_struct oldcaps;
-
-static int drop_privs()
+static int remove_mount(const char *mnt, int quiet, const char *mtab,
+                        const char *mtab_new)
 {
     int res;
-    struct __user_cap_header_struct head;
-    struct __user_cap_data_struct newcaps;
-
-    head.version = _LINUX_CAPABILITY_VERSION;
-    head.pid = 0;
-    res = capget(&head, &oldcaps);
-    if (res == -1) {
-        fprintf(stderr, "%s: failed to get capabilities: %s\n", progname,
-                strerror(errno));
-        return -1;
-    }
-
-    oldfsuid = setfsuid(getuid());
-    oldfsgid = setfsgid(getgid());
-    newcaps = oldcaps;
-    /* Keep CAP_SYS_ADMIN for mount */
-    newcaps.effective &= (1 << CAP_SYS_ADMIN);
-
-    head.version = _LINUX_CAPABILITY_VERSION;
-    head.pid = 0;
-    res = capset(&head, &newcaps);
-    if (res == -1) {
-        setfsuid(oldfsuid);
-        setfsgid(oldfsgid);
-        fprintf(stderr, "%s: failed to set capabilities: %s\n", progname,
-                strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static void restore_privs()
-{
-    struct __user_cap_header_struct head;
-    int res;
-
-    head.version = _LINUX_CAPABILITY_VERSION;
-    head.pid = 0;
-    res = capset(&head, &oldcaps);
-    if (res == -1)
-        fprintf(stderr, "%s: failed to restore capabilities: %s\n", progname,
-                strerror(errno));
-    
-    setfsuid(oldfsuid);
-    setfsgid(oldfsgid);
-}
-
-static int remove_mount(const char *mnt, int quiet, int lazy)
-{
-    int res;
-    const char *mtab = _PATH_MOUNTED;
-    const char *mtab_new = _PATH_MOUNTED "~fuse~";
     struct mntent *entp;
     FILE *fp;
     FILE *newfp;
@@ -248,37 +258,9 @@
     
     endmntent(fp);
     endmntent(newfp);
-    
-    if (found) {
-        if (getuid() != 0) {
-            res = drop_privs();
-            if (res == -1) {
-                unlink(mtab_new);
-                return -1;
-            }
-        }
 
-        res = umount2(mnt, lazy ? 2 : 0);
-        if (res == -1) {
-            if (!quiet)
-                fprintf(stderr, "%s: failed to unmount %s: %s\n",
-                        progname, mnt,strerror(errno));
-            found = -1;
-        }
-        if (getuid() != 0)
-            restore_privs();
-    }
-
-    if (found == 1) {
-        res = rename(mtab_new, mtab);
-        if (res == -1) {
-            fprintf(stderr, "%s: failed to rename %s to %s: %s\n", progname,
-                    mtab_new, mtab, strerror(errno));
-            return -1;
-        }
-    }
-    else {
-        if (!found && !quiet)
+    if (!found) {
+        if (!quiet)
             fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
                     mnt, mtab);
         unlink(mtab_new);
@@ -288,6 +270,55 @@
     return 0;
 }
 
+
+static int do_unmount(const char *mnt, int quiet, int lazy, const char *mtab,
+                      const char *mtab_new)
+{
+    int res;
+
+    if (getuid() != 0) {
+        res = drop_privs();
+        if (res == -1)
+            return -1;
+    }
+    res = umount2(mnt, lazy ? 2 : 0);
+    if (res == -1) {
+        if (!quiet)
+            fprintf(stderr, "%s: failed to unmount %s: %s\n",
+                    progname, mnt, strerror(errno));
+        return -1;
+    }
+    if (getuid() != 0)
+        restore_privs();
+
+    res = rename(mtab_new, mtab);
+    if (res == -1) {
+        fprintf(stderr, "%s: failed to rename %s to %s: %s\n", progname,
+                mtab_new, mtab, strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+static int unmount_fuse(const char *mnt, int quiet, int lazy)
+{
+    int res;
+    const char *mtab = _PATH_MOUNTED;
+    const char *mtab_new = _PATH_MOUNTED "~fuse~";
+    
+    res = remove_mount(mnt, quiet, mtab, mtab_new);
+    if (res == -1)
+        return -1;
+
+    res = do_unmount(mnt, quiet, lazy, mtab, mtab_new);
+    if (res == -1) {
+        unlink(mtab_new);
+        return -1;
+    }
+    return 0;
+}
+#endif /* USE_UCLIBC */    
+
 static int begins_with(const char *s, const char *beg)
 {
     if (strncmp(s, beg, strlen(beg)) == 0)
@@ -475,20 +506,32 @@
     return res;
 }
 
-static int check_version(void)
+static int check_version(const char *dev)
 {
     int res;
     int majorver;
     int minorver;
-    const char *version_file = FUSE_VERSION_FILE;
-    FILE *vf = fopen(version_file, "r");
+    const char *version_file;
+    int isold = 0;
+    FILE *vf;
+
+    if (strcmp(dev, FUSE_DEV_OLD) == 0)
+        isold = 1;
+
+    if (isold)
+        version_file = FUSE_VERSION_FILE_OLD;
+    else
+        version_file = FUSE_VERSION_FILE;
+
+    vf = fopen(version_file, "r");
     if (vf == NULL) {
-        version_file = "/sys/fs/fuse/version";
-        vf = fopen(version_file, "r");
-        if (vf == NULL) {
+        if (isold) {
             fprintf(stderr, "%s: kernel interface too old\n", progname);
             return -1;
-        }
+        } else
+            /* If /sys/fs/fuse/version doesn't exist, just skip
+               version checking */
+            return 0;
     }
     res = fscanf(vf, "%i.%i", &majorver, &minorver);
     fclose(vf);
@@ -606,7 +649,7 @@
     return fd;
 }
 
-static int try_open_new(char **devp)
+static int try_open_new(char **devp, int final)
 {
     const char *dev;
     unsigned minor;
@@ -616,8 +659,18 @@
     unsigned devnum;
     char buf[256];
     int fd = open(FUSE_SYS_DEV, O_RDONLY);
-    if (fd == -1)
-        return -2;
+    if (fd == -1) {
+        if (!final)
+            return -2;
+        fd = try_open(FUSE_DEV, devp, 0);
+        if (fd != -1)
+            return fd;
+        if (errno == ENODEV)
+            return -2;
+        fprintf(stderr, "%s: failed to open %s: %s\n", progname,
+                FUSE_DEV, strerror(errno));
+        return -1;
+    }
 
     res = read(fd, buf, sizeof(buf)-1);
     close(fd);
@@ -635,10 +688,17 @@
     }
 
     devnum = (major << 8) + (minor & 0xff) + ((minor & 0xff00) << 12);
-    dev = FUSE_DEV_NEW;
+    dev = FUSE_DEV;
     res = stat(dev, &stbuf);
-    if (res == -1)
-        return try_open_new_temp(devnum, devp);
+    if (res == -1) {
+        if (major == FUSE_MAJOR && minor == FUSE_MINOR)
+            return try_open_new_temp(devnum, devp);
+        else {
+            fprintf(stderr, "%s: failed to open %s: %s\n", progname,
+                    dev, strerror(errno));
+            return -1;
+        }
+    }
     
     if ((stbuf.st_mode & S_IFMT) != S_IFCHR || stbuf.st_rdev != devnum) {
         fprintf(stderr, "%s: %s exists but has wrong attributes\n", progname,
@@ -652,21 +712,27 @@
 {
     int fd;
 
-    fd = try_open_new(devp);
-    if (fd != -2)
-        return fd;
-
-    fd = try_open(FUSE_DEV_OLD, devp, 1);
-    if (fd != -1)
-        return fd;
-
     if (1
 #ifndef AUTO_MODPROBE
         && getuid() == 0
 #endif
         ) {
         int status;
-        pid_t pid = fork();
+        pid_t pid;
+
+        fd = try_open(FUSE_DEV_OLD, devp, 1);
+        if (fd != -1)
+            return fd;
+
+        fd = try_open_new(devp, 0);
+        if (fd != -2)
+            return fd;
+
+#ifndef USE_UCLIBC
+        pid = fork();
+#else
+        pid = vfork();
+#endif
         if (pid == 0) {
             setuid(0);
             execl("/sbin/modprobe", "/sbin/modprobe", "fuse", NULL);
@@ -674,17 +740,16 @@
         }
         if (pid != -1)
             waitpid(pid, &status, 0);
-
-        fd = try_open_new(devp);
-        if (fd != -2)
-            return fd;
-
-        fd = try_open(FUSE_DEV_OLD, devp, 1);
-        if (fd != -1)
-            return fd;
-        
     }
 
+    fd = try_open(FUSE_DEV_OLD, devp, 1);
+    if (fd != -1)
+        return fd;
+
+    fd = try_open_new(devp, 1);
+    if (fd != -2)
+        return fd;        
+
     fprintf(stderr, "fuse device not found, try 'modprobe fuse' first\n");
     return -1;
 }
@@ -697,7 +762,6 @@
     char *dev;
     const char *type = "fuse";
     struct stat stbuf;
-    int mtablock;
     char *fsname;
     char *mnt_opts;
     const char *real_mnt = mnt;
@@ -713,7 +777,7 @@
             return -1;
     }
 
-    res = check_version();
+    res = check_version(dev);
     if (res != -1) {
         res = check_perm(&real_mnt, &stbuf, &currdir_fd);
         if (res != -1)
@@ -731,9 +795,10 @@
         fchdir(currdir_fd);
         close(currdir_fd);
     }
-
+    
+#ifndef USE_UCLIBC
     if (geteuid() == 0) {
-        mtablock = lock_mtab();
+        int mtablock = lock_mtab();
         res = add_mount(fsname, mnt, type, mnt_opts);
         unlock_mtab(mtablock);
         if (res == -1) {
@@ -741,6 +806,8 @@
             return -1;
         }
     }
+#endif
+
     free(fsname);
     free(mnt_opts);
     free(dev);
@@ -928,11 +995,14 @@
         restore_privs();
     
     if (unmount) {
+#ifndef USE_UCLIBC
         if (geteuid() == 0) {
             int mtablock = lock_mtab();
-            res = remove_mount(mnt, quiet, lazy);
+            res = unmount_fuse(mnt, quiet, lazy);
             unlock_mtab(mtablock);
-        } else {
+        } else 
+#endif
+        {
             res = umount2(mnt, lazy ? 2 : 0);
             if (res == -1) {
                 if (!quiet)