Add fs subtype support to libfuse and fusermount
authorMiklos Szeredi <miklos@szeredi.hu>
Wed, 20 Jun 2007 21:37:58 +0000 (21:37 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Wed, 20 Jun 2007 21:37:58 +0000 (21:37 +0000)
ChangeLog
include/fuse_common.h
lib/fuse_versionscript
lib/helper.c
lib/mount.c
lib/mount_util.c
lib/mount_util.h
util/fusermount.c

index 59653aa43c330a0e39d5bd58532b9e0af2c6c982..9b397dbd6e519853d0b81c3cabd281bea0aa2f79 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2007-06-20  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Add fs subtype support to libfuse and fusermount
+
 2007-06-19  Miklos Szeredi <miklos@szeredi.hu>
 
        * kernel: sync with mainline (2.6.22)
index 26e99673c83e65d8f772f3a79be2ba106a22a782..384bd00146a20e085f890e8440ef926afee8c255 100644 (file)
@@ -160,9 +160,21 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
 int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
                        int *multithreaded, int *foreground);
 
-
+/**
+ * Go into the background
+ *
+ * @param foreground if true, stay in the foreground
+ * @return 0 on success, -1 on failure
+ */
 int fuse_daemonize(int foreground);
 
+/**
+ * Get the version of the library
+ *
+ * @return the version
+ */
+int fuse_version(void);
+
 /* ----------------------------------------------------------- *
  * Signal handling                                             *
  * ----------------------------------------------------------- */
index cbce074bc79b4c3e9290a4bcf9af983e26b392c7..6125f20ecfcc31b505852e58c4ae76c31a6ea66b 100644 (file)
@@ -150,6 +150,7 @@ FUSE_2.7 {
                fuse_fs_utimens;
                fuse_fs_write;
                fuse_register_module;
+               fuse_version;
 
        local:
                *;
index 1de088f99dd76eac7c26b6c88aea56f00e2b2004..d7cc9b7717e14c830f1b07557be2be7f7ab32d02 100644 (file)
@@ -29,7 +29,7 @@ enum  {
 struct helper_opts {
     int singlethread;
     int foreground;
-    int fsname;
+    int nodefault_subtype;
     char *mountpoint;
 };
 
@@ -40,7 +40,8 @@ static const struct fuse_opt fuse_helper_opts[] = {
     FUSE_HELPER_OPT("debug",       foreground),
     FUSE_HELPER_OPT("-f",          foreground),
     FUSE_HELPER_OPT("-s",          singlethread),
-    FUSE_HELPER_OPT("fsname=",     fsname),
+    FUSE_HELPER_OPT("fsname=",     nodefault_subtype),
+    FUSE_HELPER_OPT("subtype=",    nodefault_subtype),
 
     FUSE_OPT_KEY("-h",          KEY_HELP),
     FUSE_OPT_KEY("--help",      KEY_HELP),
@@ -50,6 +51,7 @@ static const struct fuse_opt fuse_helper_opts[] = {
     FUSE_OPT_KEY("-d",          FUSE_OPT_KEY_KEEP),
     FUSE_OPT_KEY("debug",       FUSE_OPT_KEY_KEEP),
     FUSE_OPT_KEY("fsname=",     FUSE_OPT_KEY_KEEP),
+    FUSE_OPT_KEY("subtype=",    FUSE_OPT_KEY_KEEP),
     FUSE_OPT_END
 };
 
@@ -117,24 +119,24 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
     }
 }
 
-static int add_default_fsname(const char *progname, struct fuse_args *args)
+static int add_default_subtype(const char *progname, struct fuse_args *args)
 {
     int res;
-    char *fsname_opt;
+    char *subtype_opt;
     const char *basename = strrchr(progname, '/');
     if (basename == NULL)
         basename = progname;
     else if (basename[1] != '\0')
         basename++;
 
-    fsname_opt = (char *) malloc(strlen(basename) + 64);
-    if (fsname_opt == NULL) {
+    subtype_opt = (char *) malloc(strlen(basename) + 64);
+    if (subtype_opt == NULL) {
         fprintf(stderr, "fuse: memory allocation failed\n");
         return -1;
     }
-    sprintf(fsname_opt, "-ofsname=%s", basename);
-    res = fuse_opt_add_arg(args, fsname_opt);
-    free(fsname_opt);
+    sprintf(subtype_opt, "-osubtype=%s", basename);
+    res = fuse_opt_add_arg(args, subtype_opt);
+    free(subtype_opt);
     return res;
 }
 
@@ -149,8 +151,8 @@ int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
     if (res == -1)
         return -1;
 
-    if (!hopts.fsname) {
-        res = add_default_fsname(args->argv[0], args);
+    if (!hopts.nodefault_subtype) {
+        res = add_default_subtype(args->argv[0], args);
         if (res == -1)
             goto err;
     }
@@ -331,6 +333,11 @@ int fuse_main(void)
     return -1;
 }
 
+int fuse_version(void)
+{
+    return FUSE_VERSION;
+}
+
 #include "fuse_compat.h"
 
 #ifndef __FreeBSD__
index 24bcf8c6a7802b24e7e5538bba28d6ab7ddc54b4..aa0c0cb6d5d801931d36999144032987b203c0a1 100644 (file)
@@ -39,6 +39,7 @@ enum {
     KEY_KERN_FLAG,
     KEY_KERN_OPT,
     KEY_FUSERMOUNT_OPT,
+    KEY_SUBTYPE_OPT,
     KEY_MTAB_OPT,
     KEY_ALLOW_ROOT,
     KEY_RO,
@@ -54,6 +55,8 @@ struct mount_opts {
     int nonempty;
     int blkdev;
     char *fsname;
+    char *subtype;
+    char *subtype_opt;
     char *mtab_opts;
     char *fusermount_opts;
     char *kernel_opts;
@@ -67,11 +70,13 @@ static const struct fuse_opt fuse_mount_opts[] = {
     FUSE_MOUNT_OPT("nonempty",          nonempty),
     FUSE_MOUNT_OPT("blkdev",            blkdev),
     FUSE_MOUNT_OPT("fsname=%s",         fsname),
+    FUSE_MOUNT_OPT("subtype=%s",        subtype),
     FUSE_OPT_KEY("allow_other",         KEY_KERN_OPT),
     FUSE_OPT_KEY("allow_root",          KEY_ALLOW_ROOT),
     FUSE_OPT_KEY("nonempty",            KEY_FUSERMOUNT_OPT),
     FUSE_OPT_KEY("blkdev",              KEY_FUSERMOUNT_OPT),
     FUSE_OPT_KEY("fsname=",             KEY_FUSERMOUNT_OPT),
+    FUSE_OPT_KEY("subtype=",            KEY_SUBTYPE_OPT),
     FUSE_OPT_KEY("large_read",          KEY_KERN_OPT),
     FUSE_OPT_KEY("blksize=",            KEY_KERN_OPT),
     FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
@@ -107,6 +112,7 @@ static void mount_help(void)
             "    -o nonempty            allow mounts over non-empty file/dir\n"
             "    -o default_permissions enable permission checking by kernel\n"
             "    -o fsname=NAME         set filesystem name\n"
+            "    -o subtype=NAME        set filesystem type\n"
             "    -o large_read          issue large read requests (2.4 only)\n"
             "    -o max_read=N          set maximum size of read requests\n"
             "\n"
@@ -196,6 +202,9 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
     case KEY_FUSERMOUNT_OPT:
         return fuse_opt_add_opt(&mo->fusermount_opts, arg);
 
+    case KEY_SUBTYPE_OPT:
+        return fuse_opt_add_opt(&mo->subtype_opt, arg);
+
     case KEY_MTAB_OPT:
         return fuse_opt_add_opt(&mo->mtab_opts, arg);
 
@@ -304,7 +313,8 @@ void fuse_unmount_compat22(const char *mountpoint)
     fuse_kern_unmount(mountpoint, -1);
 }
 
-int fuse_mount_compat22(const char *mountpoint, const char *opts)
+static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
+                                 int quiet)
 {
     int fds[2], pid;
     int res;
@@ -334,6 +344,12 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts)
         const char *argv[32];
         int a = 0;
 
+        if (quiet) {
+            int fd = open("/dev/null", O_RDONLY);
+            dup2(fd, 1);
+            dup2(fd, 2);
+        }
+
         argv[a++] = FUSERMOUNT_PROG;
         if (opts) {
             argv[a++] = "-o";
@@ -360,13 +376,18 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts)
     return rv;
 }
 
+int fuse_mount_compat22(const char *mountpoint, const char *opts)
+{
+    return fuse_mount_fusermount(mountpoint, opts, 0);
+}
 
 static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
                           const char *mnt_opts)
 {
-    const char *type = mo->blkdev ? "fuseblk" : "fuse";
     char tmp[128];
     const char *devname = "/dev/fuse";
+    char *source = NULL;
+    char *type = NULL;
     struct stat stbuf;
     int fd;
     int res;
@@ -395,9 +416,6 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
         return -1;
     }
 
-    if (mo->fsname)
-        devname = mo->fsname;
-
     snprintf(tmp, sizeof(tmp),  "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
              stbuf.st_mode & S_IFMT, getuid(), getgid());
 
@@ -405,16 +423,52 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
     if (res == -1)
         goto out_close;
 
-    res = mount(devname, mnt, type, mo->flags, mo->kernel_opts);
+    source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
+                    (mo->subtype ? strlen(mo->subtype) : 0) +
+                    strlen(devname) + 32);
+
+    type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
+    if (!type || !source) {
+        fprintf(stderr, "fuse: failed to allocate memory\n");
+        goto out_close;
+    }
+
+    strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+    if (mo->subtype) {
+        strcat(type, ".");
+        strcat(type, mo->subtype);
+    }
+    strcpy(source,
+           mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
+
+    res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+    if (res == -1 && errno == ENODEV && mo->subtype) {
+        /* Probably missing subtype support */
+        strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+        if (mo->fsname) {
+            if (!mo->blkdev)
+                sprintf(source, "%s#%s", mo->subtype, mo->fsname);
+        } else {
+            strcpy(source, type);
+        }
+        res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+    }
     if (res == -1) {
         /*
          * Maybe kernel doesn't support unprivileged mounts, in this
          * case try falling back to fusermount
          */
-        if (errno == EPERM)
+        if (errno == EPERM) {
             res = -2;
-        else
-            perror("fuse: mount failed");
+        } else {
+            int errno_save = errno;
+            if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
+                fprintf(stderr, "fuse: 'fuseblk' support missing\n");
+            else
+                fprintf(stderr, "fuse: mount failed: %s\n",
+                        strerror(errno_save));
+        }
+
         goto out_close;
     }
 
@@ -424,7 +478,7 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
         if (!newmnt)
             goto out_umount;
 
-        res = fuse_mnt_add_mount("fuse", devname, newmnt, type, mnt_opts);
+        res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts);
         free(newmnt);
         if (res == -1)
             goto out_umount;
@@ -435,6 +489,8 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
  out_umount:
     umount2(mnt, 2); /* lazy umount */
  out_close:
+    free(type);
+    free(source);
     close(fd);
     return res;
 }
@@ -460,6 +516,11 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
     int res = -1;
     char *mnt_opts = NULL;
 
+    if (!mountpoint) {
+        fprintf(stderr, "fuse: missing mountpoint\n");
+        return -1;
+    }
+
     memset(&mo, 0, sizeof(mo));
     mo.flags = MS_NOSUID | MS_NODEV;
 
@@ -489,12 +550,30 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
             fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
             goto out;
 
-        res = fuse_mount_compat22(mountpoint, mnt_opts);
+        if (mo.subtype) {
+            char *tmp_opts = NULL;
+
+            res = -1;
+            if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
+                fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
+                free(tmp_opts);
+                goto out;
+            }
+
+            res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
+            free(tmp_opts);
+            if (res == -1)
+                res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+        } else {
+            res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+        }
     }
  out:
     free(mnt_opts);
     free(mo.fsname);
+    free(mo.subtype);
     free(mo.fusermount_opts);
+    free(mo.subtype_opt);
     free(mo.kernel_opts);
     free(mo.mtab_opts);
     return res;
index 02b2731fc32ff96199cd104ad2e0b7a6bb7c7260..dccecdf53812921e8fbece28ee40160467a822e4 100644 (file)
@@ -193,3 +193,20 @@ int fuse_mnt_check_empty(const char *progname, const char *mnt,
     }
     return 0;
 }
+
+int fuse_mnt_check_fuseblk(void)
+{
+    char buf[256];
+    FILE *f = fopen("/proc/filesystems", "r");
+    if (!f)
+        return 1;
+
+    while (fgets(buf, sizeof(buf), f))
+        if (strstr(buf, "fuseblk\n")) {
+            fclose(f);
+            return 1;
+        }
+
+    fclose(f);
+    return 0;
+}
index 106a6f8f224930c2d6899cc4ee928aedfc75b36a..f9f6cbee41d2ca62a3a4e1231fb47efd9498cddc 100644 (file)
@@ -14,3 +14,4 @@ int fuse_mnt_umount(const char *progname, const char *mnt, int lazy);
 char *fuse_mnt_resolve_path(const char *progname, const char *orig);
 int fuse_mnt_check_empty(const char *progname, const char *mnt,
                          mode_t rootmode, off_t rootsize);
+int fuse_mnt_check_fuseblk(void);
index 8f69599e88f77df9a34cb1f7dbede31dd94c1868..716caffac5abcf089896bb3e408814ab7b1d549d 100644 (file)
@@ -74,10 +74,10 @@ static void restore_privs(void)
 }
 
 #ifndef IGNORE_MTAB
-static int add_mount(const char *fsname, const char *mnt, const char *type,
+static int add_mount(const char *source, const char *mnt, const char *type,
                      const char *opts)
 {
-    return fuse_mnt_add_mount(progname, fsname, mnt, type, opts);
+    return fuse_mnt_add_mount(progname, source, mnt, type, opts);
 }
 
 static int unmount_fuse(const char *mnt, int quiet, int lazy)
@@ -108,7 +108,9 @@ static int unmount_fuse(const char *mnt, int quiet, int lazy)
         while ((entp = getmntent(fp)) != NULL) {
             if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
                 (strcmp(entp->mnt_type, "fuse") == 0 ||
-                 strcmp(entp->mnt_type, "fuseblk") == 0)) {
+                 strcmp(entp->mnt_type, "fuseblk") == 0 ||
+                 strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
+                 strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
                 char *p = strstr(entp->mnt_opts, "user=");
                 if (p && (p == entp->mnt_opts || *(p-1) == ',') &&
                     strcmp(p + 5, user) == 0) {
@@ -150,7 +152,8 @@ static int count_fuse_fs(void)
         return -1;
     }
     while ((entp = getmntent(fp)) != NULL) {
-        if (strcmp(entp->mnt_type, "fuse") == 0)
+        if (strcmp(entp->mnt_type, "fuse") == 0 ||
+            strncmp(entp->mnt_type, "fuse.", 5) == 0)
             count ++;
     }
     endmntent(fp);
@@ -164,10 +167,10 @@ static int count_fuse_fs()
     return 0;
 }
 
-static int add_mount(const char *fsname, const char *mnt, const char *type,
+static int add_mount(const char *source, const char *mnt, const char *type,
                      const char *opts)
 {
-    (void) fsname;
+    (void) source;
     (void) mnt;
     (void) type;
     (void) opts;
@@ -345,25 +348,26 @@ static int opt_eq(const char *s, unsigned len, const char *opt)
         return 0;
 }
 
-static int has_fuseblk(void)
+static int get_string_opt(const char *s, unsigned len, const char *opt,
+                          char **val)
 {
-    char buf[256];
-    FILE *f = fopen("/proc/filesystems", "r");
-    if (!f)
-        return 1;
+    unsigned opt_len = strlen(opt);
 
-    while (fgets(buf, sizeof(buf), f))
-        if (strstr(buf, "fuseblk\n")) {
-            fclose(f);
-            return 1;
-        }
+    if (*val)
+        free(*val);
+    *val = (char *) malloc(len - opt_len + 1);
+    if (!*val) {
+        fprintf(stderr, "%s: failed to allocate memory\n", progname);
+        return 0;
+    }
 
-    fclose(f);
-    return 0;
+    memcpy(*val, s + opt_len, len - opt_len);
+    (*val)[len - opt_len] = '\0';
+    return 1;
 }
 
-static int do_mount(const char *mnt, const char **type, mode_t rootmode,
-                    int fd, const char *opts, const char *dev, char **fsnamep,
+static int do_mount(const char *mnt, char **typep, mode_t rootmode,
+                    int fd, const char *opts, const char *dev, char **sourcep,
                     char **mnt_optsp, off_t rootsize)
 {
     int res;
@@ -373,6 +377,9 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
     const char *s;
     char *d;
     char *fsname = NULL;
+    char *subtype = NULL;
+    char *source = NULL;
+    char *type = NULL;
     int check_empty = 1;
     int blkdev = 0;
 
@@ -385,18 +392,14 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
     for (s = opts, d = optbuf; *s;) {
         unsigned len;
         const char *fsname_str = "fsname=";
+        const char *subtype_str = "subtype=";
         for (len = 0; s[len] && s[len] != ','; len++);
         if (begins_with(s, fsname_str)) {
-            unsigned fsname_str_len = strlen(fsname_str);
-            if (fsname)
-                free(fsname);
-            fsname = (char *) malloc(len - fsname_str_len + 1);
-            if (!fsname) {
-                fprintf(stderr, "%s: failed to allocate memory\n", progname);
+            if (!get_string_opt(s, len, fsname_str, &fsname))
+                goto err;
+        } else if (begins_with(s, subtype_str)) {
+            if (!get_string_opt(s, len, subtype_str, &subtype))
                 goto err;
-            }
-            memcpy(fsname, s + fsname_str_len, len - fsname_str_len);
-            fsname[len - fsname_str_len] = '\0';
         } else if (opt_eq(s, len, "blkdev")) {
             if (getuid() != 0) {
                 fprintf(stderr, "%s: option blkdev is privileged\n", progname);
@@ -453,35 +456,58 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
 
     sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
             fd, rootmode, getuid(), getgid());
-    if (fsname == NULL) {
-        fsname = strdup(dev);
-        if (!fsname) {
-            fprintf(stderr, "%s: failed to allocate memory\n", progname);
-            goto err;
-        }
-    }
 
     if (check_empty &&
         fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
         goto err;
 
-    if (blkdev)
-        *type = "fuseblk";
-    res = mount(fsname, mnt, *type, flags, optbuf);
+    source = malloc((fsname ? strlen(fsname) : 0) +
+                    (subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
+
+    type = malloc((subtype ? strlen(subtype) : 0) + 32);
+    if (!type || !source) {
+        fprintf(stderr, "%s: failed to allocate memory\n", progname);
+        goto err;
+    }
+
+    if (subtype)
+        sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
+    else
+        strcpy(type, blkdev ? "fuseblk" : "fuse");
+
+    if (fsname)
+        strcpy(source, fsname);
+    else
+        strcpy(source, subtype ? subtype : dev);
+
+    res = mount(source, mnt, type, flags, optbuf);
+    if (res == -1 && errno == ENODEV && subtype) {
+        /* Probably missing subtype support */
+        strcpy(type, blkdev ? "fuseblk" : "fuse");
+        if (fsname) {
+            if (!blkdev)
+                sprintf(source, "%s#%s", subtype, fsname);
+        } else {
+            strcpy(source, type);
+        }
+
+        res = mount(source, mnt, type, flags, optbuf);
+    }
     if (res == -1 && errno == EINVAL) {
         /* It could be an old version not supporting group_id */
         sprintf(d, "fd=%i,rootmode=%o,user_id=%i", fd, rootmode, getuid());
-        res = mount(fsname, mnt, *type, flags, optbuf);
+        res = mount(source, mnt, type, flags, optbuf);
     }
     if (res == -1) {
         int errno_save = errno;
-        if (blkdev && errno == ENODEV && !has_fuseblk())
-            fprintf(stderr, "%s: 'fuseblk' support missing; try the kernel module from fuse-2.6.0 or later\n", progname);
+        if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
+            fprintf(stderr, "%s: 'fuseblk' support missing\n", progname);
         else
             fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save));
         goto err;
     } else {
-        *fsnamep = fsname;
+        *sourcep = source;
+        *typep = type;
         *mnt_optsp = mnt_opts;
     }
     free(optbuf);
@@ -490,6 +516,9 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
 
  err:
     free(fsname);
+    free(subtype);
+    free(source);
+    free(type);
     free(mnt_opts);
     free(optbuf);
     return -1;
@@ -666,9 +695,9 @@ static int mount_fuse(const char *mnt, const char *opts)
     int res;
     int fd;
     char *dev;
-    const char *type = "fuse";
     struct stat stbuf;
-    char *fsname = NULL;
+    char *type = NULL;
+    char *source = NULL;
     char *mnt_opts = NULL;
     const char *real_mnt = mnt;
     int currdir_fd = -1;
@@ -696,7 +725,7 @@ static int mount_fuse(const char *mnt, const char *opts)
         restore_privs();
         if (res != -1)
             res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT, fd, opts,
-                           dev, &fsname, &mnt_opts, stbuf.st_size);
+                           dev, &source, &mnt_opts, stbuf.st_size);
     } else
         restore_privs();
 
@@ -713,7 +742,7 @@ static int mount_fuse(const char *mnt, const char *opts)
     }
 
     if (geteuid() == 0) {
-        res = add_mount(fsname, mnt, type, mnt_opts);
+        res = add_mount(source, mnt, type, mnt_opts);
         if (res == -1) {
             umount2(mnt, 2); /* lazy umount */
             close(fd);
@@ -721,7 +750,8 @@ static int mount_fuse(const char *mnt, const char *opts)
         }
     }
 
-    free(fsname);
+    free(source);
+    free(type);
     free(mnt_opts);
     free(dev);