aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--kernel/dev.c15
-rw-r--r--kernel/dir.c2
-rw-r--r--kernel/fuse_i.h30
-rw-r--r--kernel/inode.c17
-rw-r--r--kernel/linux/fuse.h6
-rw-r--r--lib/fuse.c29
-rw-r--r--lib/mount.c4
-rw-r--r--util/fusermount.c330
9 files changed, 289 insertions, 159 deletions
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 @@ static ssize_t fuse_dev_read(struct file *file, char __user *buf,
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 @@ static ssize_t fuse_dev_read(struct file *file, char __user *buf,
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 @@ static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
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 @@ static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
process_getdir(req);
}
req->finished = 1;
- req->locked = 0;
/* Unlocks fuse_lock: */
request_end(fc, req);
@@ -565,7 +559,6 @@ struct file_operations fuse_dev_operations = {
};
#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 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
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 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
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 @@ struct fuse_req {
/** 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 @@ struct fuse_conn {
/** 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 @@ struct fuse_getdir_out_i {
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 @@ int fuse_fs_init(void);
*/
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 @@ enum {
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 @@ static match_table_t tokens = {
{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 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
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 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
}
#endif
break;
-
+#endif
case OPT_DIRECT_IO:
d->flags |= FUSE_DIRECT_IO;
break;
@@ -351,6 +356,10 @@ static struct fuse_conn *new_conn(void)
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 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
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 @@ static int check_version(struct fuse *f)
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 @@ struct fuse *fuse_new(int fd, const char *opts, const struct fuse_operations *op
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 @@ int fuse_mount(const char *mountpoint, const char *opts)
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,66 +54,7 @@ static const char *get_user_name()
}
}
-/* use a lock file so that multiple fusermount processes don't try and
- modify the mtab file at once! */
-static int lock_mtab()
-{
- const char *mtab_lock = _PATH_MOUNTED ".fuselock";
- int mtablock;
- int res;
-
- mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
- if (mtablock >= 0) {
- res = lockf(mtablock, F_LOCK, 0);
- if (res < 0)
- perror("error getting lock");
- } else
- fprintf(stderr, "unable to open fuse lock file, continuing anyway\n");
-
- return mtablock;
-}
-
-static void unlock_mtab(int mtablock)
-{
- if (mtablock >= 0) {
- lockf(mtablock, F_ULOCK, 0);
- close(mtablock);
- }
-}
-
-static int add_mount(const char *fsname, const char *mnt, const char *type,
- const char *opts)
-{
- int res;
- const char *mtab = _PATH_MOUNTED;
- struct mntent ent;
- FILE *fp;
-
- fp = setmntent(mtab, "a");
- if (fp == NULL) {
- fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
- strerror(errno));
- return -1;
- }
-
- ent.mnt_fsname = (char *) fsname;
- ent.mnt_dir = (char *) mnt;
- ent.mnt_type = (char *) type;
- ent.mnt_opts = (char *) opts;
- ent.mnt_freq = 0;
- ent.mnt_passno = 0;
- res = addmntent(fp, &ent);
- if (res != 0) {
- fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname,
- mtab, strerror(errno));
- return -1;
- }
-
- endmntent(fp);
- return 0;
-}
-
-
+#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
@@ -140,7 +81,7 @@ static uid_t oldfsuid;
static gid_t oldfsgid;
static struct __user_cap_data_struct oldcaps;
-static int drop_privs()
+static int drop_privs(void)
{
int res;
struct __user_cap_header_struct head;
@@ -174,7 +115,7 @@ static int drop_privs()
return 0;
}
-static void restore_privs()
+static void restore_privs(void)
{
struct __user_cap_header_struct head;
int res;
@@ -189,12 +130,81 @@ static void restore_privs()
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()
+{
+ const char *mtab_lock = _PATH_MOUNTED ".fuselock";
+ int mtablock;
+ int res;
+
+ mtablock = open(mtab_lock, O_RDWR | O_CREAT, 0600);
+ if (mtablock >= 0) {
+ res = lockf(mtablock, F_LOCK, 0);
+ if (res < 0)
+ perror("error getting lock");
+ } else
+ fprintf(stderr, "unable to open fuse lock file, continuing anyway\n");
+
+ return mtablock;
+}
+
+static void unlock_mtab(int mtablock)
+{
+ if (mtablock >= 0) {
+ lockf(mtablock, F_ULOCK, 0);
+ close(mtablock);
+ }
+}
-static int remove_mount(const char *mnt, int quiet, int lazy)
+static int add_mount(const char *fsname, const char *mnt, const char *type,
+ const char *opts)
{
int res;
const char *mtab = _PATH_MOUNTED;
- const char *mtab_new = _PATH_MOUNTED "~fuse~";
+ struct mntent ent;
+ FILE *fp;
+
+ fp = setmntent(mtab, "a");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
+ strerror(errno));
+ return -1;
+ }
+
+ ent.mnt_fsname = (char *) fsname;
+ ent.mnt_dir = (char *) mnt;
+ ent.mnt_type = (char *) type;
+ ent.mnt_opts = (char *) opts;
+ ent.mnt_freq = 0;
+ ent.mnt_passno = 0;
+ res = addmntent(fp, &ent);
+ if (res != 0) {
+ fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname,
+ mtab, strerror(errno));
+ return -1;
+ }
+
+ endmntent(fp);
+ return 0;
+}
+
+static int remove_mount(const char *mnt, int quiet, const char *mtab,
+ const char *mtab_new)
+{
+ int res;
struct mntent *entp;
FILE *fp;
FILE *newfp;
@@ -248,46 +258,67 @@ static int remove_mount(const char *mnt, int quiet, int lazy)
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) {
+ if (!quiet)
+ fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
+ mnt, mtab);
+ unlink(mtab_new);
+ return -1;
}
- 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 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;
- }
}
- else {
- if (!found && !quiet)
- fprintf(stderr, "%s: entry for %s not found in %s\n", progname,
- mnt, mtab);
- unlink(mtab_new);
+ 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 @@ static int do_mount(const char *mnt, const char *type, mode_t rootmode,
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 @@ static int try_open_new_temp(unsigned devnum, char **devp)
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 @@ static int try_open_new(char **devp)
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 @@ static int try_open_new(char **devp)
}
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 @@ static int open_fuse_device(char **devp)
{
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,16 +740,15 @@ static int open_fuse_device(char **devp)
}
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 @@ static int mount_fuse(const char *mnt, const char *opts)
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 @@ static int mount_fuse(const char *mnt, const char *opts)
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 @@ static int mount_fuse(const char *mnt, const char *opts)
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 @@ static int mount_fuse(const char *mnt, const char *opts)
return -1;
}
}
+#endif
+
free(fsname);
free(mnt_opts);
free(dev);
@@ -928,11 +995,14 @@ int main(int argc, char *argv[])
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)