pass device file descriptor to fuse_unmount
authorCsaba Henk <csaba.henk@creo.hu>
Wed, 1 Mar 2006 09:40:35 +0000 (09:40 +0000)
committerCsaba Henk <csaba.henk@creo.hu>
Wed, 1 Mar 2006 09:40:35 +0000 (09:40 +0000)
ChangeLog
example/hello_ll.c
include/fuse.h
include/fuse_common.h
include/fuse_compat.h
lib/fuse_versionscript
lib/helper.c
lib/mount.c
lib/mount_bsd.c

index 43a0e7de59a53f6fd813d2775bc41915523806f4..c08d4c9f62a20ebe1fb321c1e3f9d99d89421093 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-03-01  Csaba Henk <csaba.henk@creo.hu>
+
+       * 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 <miklos@szeredi.hu>
 
        * Lowlevel lib: return all-zero statvfs data if filesystem doesn't
index 2213285d6dc6c1f515da3d00a77e89a054d96482..531d1c9731fa8cd570d28c6773f6bf45932574fa 100644 (file)
@@ -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;
index b6ecaef0af80f4c53473d16adee3fc88614d3cd3..6c0bb72f6d78ca4801d67f3fa9329d0a7b831b2b 100644 (file)
@@ -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
index 191b6f9b8f9e53f045d03560cca27f15a10931ec..f05d2376b47ba19283109da517dae381c04d594b 100644 (file)
@@ -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
index 97f7b126b171f2b3d8d39a28890f1016a0a7eee0..ef7ff6757f3d2f4bc73075c104ea5a608b6f1567 100644 (file)
@@ -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 <sys/statfs.h>
 
index b6e6e18c43e89cc1751131425e84bf2bd7901bad..02ac1760fdd5098f41be17a34e4e6a451f30345c 100644 (file)
@@ -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:
                 *;
index f93736662b1b3aa1695c88c7ebd29606a75fa943..a5935ded1ebfcca9406abcb113756c90f3453e14 100644 (file)
@@ -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);
 }
index 0a14df3ca16259273ae9a0791aca1d767a214615..a1875f0082d97c52d042d2bfb141db5ee09c7538 100644 (file)
@@ -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");
index cb1b2b9fae19d7bf71095de36c785cb2d5427be1..c5661d2131302b0eaeb8ebb204acb68076f4a6a7 100644 (file)
@@ -9,14 +9,16 @@
 #include "fuse.h"
 #include "fuse_opt.h"
 
+#include <sys/stat.h>
+#include <sys/wait.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stddef.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <sys/wait.h>
 #include <string.h>
+#include <paths.h>
 
 #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");