From: Csaba Henk Date: Wed, 1 Mar 2006 09:40:35 +0000 (+0000) Subject: pass device file descriptor to fuse_unmount X-Git-Tag: fuse_2_6_0_pre2~9 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=ee588c01dca3991807aea456a66246ff8ad0c332;p=qemu-gpiodev%2Flibfuse.git pass device file descriptor to fuse_unmount --- diff --git a/ChangeLog b/ChangeLog index 43a0e7d..c08d4c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-03-01 Csaba Henk + + * libfuse: pass device file descriptor to fuse_unmount(), rewrite + FreeBSD implementation so that it uses libc (sysctl backed) instead + of an embdedded script (kmem backed). Adjust the control flow of + hello_ll so that device doesn't get closed before unmount attempt. + 2006-02-25 Miklos Szeredi * Lowlevel lib: return all-zero statvfs data if filesystem doesn't diff --git a/example/hello_ll.c b/example/hello_ll.c index 2213285..531d1c9 100644 --- a/example/hello_ll.c +++ b/example/hello_ll.c @@ -151,7 +151,7 @@ int main(int argc, char *argv[]) struct fuse_args args = FUSE_ARGS_INIT(argc, argv); char *mountpoint; int err = -1; - int fd; + int fd = -1; if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && (fd = fuse_mount(mountpoint, &args)) != -1) { @@ -168,11 +168,14 @@ int main(int argc, char *argv[]) } fuse_remove_signal_handlers(se); } + fuse_unmount(mountpoint, fd); fuse_session_destroy(se); + goto out; } close(fd); } - fuse_unmount(mountpoint); + fuse_unmount(mountpoint, fd); +out: fuse_opt_free_args(&args); return err ? 1 : 0; diff --git a/include/fuse.h b/include/fuse.h index b6ecaef..6c0bb72 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -562,6 +562,7 @@ void fuse_set_getcontext_func(struct fuse_context *(*func)(void)); # define fuse_operations fuse_operations_compat22 # define fuse_file_info fuse_file_info_compat22 # define fuse_mount fuse_mount_compat22 +# define fuse_unmount fuse_unmount_compat22 # else # define fuse_dirfil_t fuse_dirfil_t_compat # define __fuse_read_cmd fuse_read_cmd diff --git a/include/fuse_common.h b/include/fuse_common.h index 191b6f9..f05d237 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -91,8 +91,9 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args); * Umount a FUSE mountpoint * * @param mountpoint the mount point path + * @param the control file descriptor */ -void fuse_unmount(const char *mountpoint); +void fuse_unmount(const char *mountpoint, int fd); /** * Parse common options diff --git a/include/fuse_compat.h b/include/fuse_compat.h index 97f7b12..ef7ff67 100644 --- a/include/fuse_compat.h +++ b/include/fuse_compat.h @@ -62,6 +62,8 @@ struct fuse *fuse_setup_compat25(int argc, char *argv[], size_t op_size, char **mountpoint, int *multithreaded, int *fd); +void fuse_unmount_compat22(const char *mountpoint); + #ifndef __FreeBSD__ #include diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index b6e6e18..02ac176 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -20,7 +20,6 @@ FUSE_2.2 { fuse_set_getcontext_func; fuse_setup_compat2; fuse_teardown; - fuse_unmount; }; FUSE_2.4 { @@ -95,6 +94,8 @@ FUSE_2.6 { fuse_opt_insert_arg; fuse_setup; fuse_setup_compat25; + fuse_unmount; + fuse_unmount_compat22; local: *; diff --git a/lib/helper.c b/lib/helper.c index f937366..a5935de 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -225,7 +225,7 @@ static struct fuse *fuse_setup_common(int argc, char *argv[], err_destroy: fuse_destroy(fuse); err_unmount: - fuse_unmount(*mountpoint); + fuse_unmount(*mountpoint, *fd); err_free: free(*mountpoint); return NULL; @@ -242,10 +242,8 @@ struct fuse *fuse_setup(int argc, char *argv[], void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) { - (void) fd; - fuse_remove_signal_handlers(fuse_get_session(fuse)); - fuse_unmount(mountpoint); + fuse_unmount(mountpoint, fd); fuse_destroy(fuse); free(mountpoint); } diff --git a/lib/mount.c b/lib/mount.c index 0a14df3..a1875f0 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -166,11 +166,18 @@ static int receive_fd(int fd) return *(int*)CMSG_DATA(cmsg); } -void fuse_unmount(const char *mountpoint) +void fuse_unmount_compat22(const char *mountpoint) +{ + fuse_unmount(mountpoint, -1); +} + +void fuse_unmount(const char *mountpoint, int fd) { const char *mountprog = FUSERMOUNT_PROG; int pid; + (void) fd; + if (!mountpoint) return; @@ -293,3 +300,4 @@ int fuse_mount_compat1(const char *mountpoint, const char *args[]) } __asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2"); +__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index cb1b2b9..c5661d2 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -9,14 +9,16 @@ #include "fuse.h" #include "fuse_opt.h" +#include +#include #include #include #include #include #include #include -#include #include +#include #define FUSERMOUNT_PROG "mount_fusefs" #define FUSE_DEV_TRUNK "/dev/fuse" @@ -154,7 +156,7 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key, return 1; } -void fuse_unmount(const char *mountpoint) +void fuse_unmount_compat22(const char *mountpoint) { char dev[128]; char *ssc, *umount_cmd; @@ -171,6 +173,14 @@ void fuse_unmount(const char *mountpoint) (void) mountpoint; + /* + * If we don't know the fd, we have to resort to the scripted solution -- + * iterating over the fd-s is unpractical, as we don't know how many of + * open files we have. (This could be looked up in procfs -- however, + * that's optional on FBSD; or read out from the kmem -- however, that's + * bound to privileges (in fact, that's what happens when we call the + * setgid kmem fstat(1) utility). + */ asprintf(&ssc, seekscript, getpid()); errno = 0; @@ -187,6 +197,29 @@ void fuse_unmount(const char *mountpoint) system(umount_cmd); } +void fuse_unmount(const char *mountpoint, int fd) +{ + char *ep, *umount_cmd, dev[128]; + struct stat sbuf; + + (void)mountpoint; + + if (fstat(fd, &sbuf) == -1) + return; + + devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); + + if (strncmp(dev, "fuse", 4)) + return; + + strtol(dev + 4, &ep, 10); + if (*ep != '\0') + return; + + asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev); + system(umount_cmd); +} + static int fuse_mount_core(const char *mountpoint, const char *opts) { const char *mountprog = FUSERMOUNT_PROG; @@ -299,3 +332,5 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args) free(mo.kernel_opts); return res; } + +__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");