diff --git a/vendored/libfuse/lib/mount_generic.h b/vendored/libfuse/lib/mount_generic.h index 357f39e9..d38ef40f 100644 --- a/vendored/libfuse/lib/mount_generic.h +++ b/vendored/libfuse/lib/mount_generic.h @@ -11,51 +11,57 @@ #include "fuse_opt.h" #include "mount_util.h" +#include +#include +#include +#include #include #include -#include -#include #include #include -#include -#include -#include +#include #include #include #include #include -#include +#include #ifdef __NetBSD__ #include -#define MS_RDONLY MNT_RDONLY -#define MS_NOSUID MNT_NOSUID -#define MS_NODEV MNT_NODEV -#define MS_NOEXEC MNT_NOEXEC -#define MS_SYNCHRONOUS MNT_SYNCHRONOUS -#define MS_NOATIME MNT_NOATIME +#define MS_RDONLY MNT_RDONLY +#define MS_NOSUID MNT_NOSUID +#define MS_NODEV MNT_NODEV +#define MS_NOEXEC MNT_NOEXEC +#define MS_SYNCHRONOUS MNT_SYNCHRONOUS +#define MS_NOATIME MNT_NOATIME +#ifndef MNT_DETACH +#define MNT_DETACH 2 +#endif -#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) +#define umount2(mnt, flags) unmount(mnt,(flags == MNT_DETACH) ? MNT_FORCE : 0) #endif -#define FUSERMOUNT_PROG "fusermount" -#define FUSE_COMMFD_ENV "_FUSE_COMMFD" +#define FUSERMOUNT_PROG "fusermount" +#define FUSERMOUNT3_PROG "fusermount3" +#define FUSE_COMMFD_ENV "_FUSE_COMMFD" #ifndef MS_DIRSYNC #define MS_DIRSYNC 128 #endif -enum { - KEY_KERN_FLAG, - KEY_KERN_OPT, - KEY_FUSERMOUNT_OPT, - KEY_SUBTYPE_OPT, - KEY_MTAB_OPT, - KEY_RO -}; +enum + { + KEY_KERN_FLAG, + KEY_KERN_OPT, + KEY_FUSERMOUNT_OPT, + KEY_SUBTYPE_OPT, + KEY_MTAB_OPT, + KEY_RO + }; -struct mount_opts { +struct mount_opts +{ int allow_other; int flags; int auto_unmount; @@ -68,101 +74,100 @@ struct mount_opts { char *kernel_opts; }; -#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 } +#define FUSE_MOUNT_OPT(t,p) { t, offsetof(struct mount_opts,p), 1 } -static -const -struct fuse_opt fuse_mount_opts[] = +static const struct fuse_opt fuse_mount_opts[] = { - FUSE_MOUNT_OPT("allow_other", allow_other), - FUSE_MOUNT_OPT("blkdev", blkdev), - FUSE_MOUNT_OPT("auto_unmount", auto_unmount), - FUSE_MOUNT_OPT("fsname=%s", fsname), - FUSE_MOUNT_OPT("subtype=%s", subtype), - FUSE_OPT_KEY("allow_other", KEY_KERN_OPT), - FUSE_OPT_KEY("auto_unmount", 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), - FUSE_OPT_KEY("context=", KEY_KERN_OPT), - FUSE_OPT_KEY("fscontext=", KEY_KERN_OPT), - FUSE_OPT_KEY("defcontext=", KEY_KERN_OPT), - FUSE_OPT_KEY("rootcontext=", KEY_KERN_OPT), - FUSE_OPT_KEY("max_read=", KEY_KERN_OPT), - FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP), - FUSE_OPT_KEY("user=", KEY_MTAB_OPT), - FUSE_OPT_KEY("-n", KEY_MTAB_OPT), - FUSE_OPT_KEY("-r", KEY_RO), - FUSE_OPT_KEY("ro", KEY_KERN_FLAG), - FUSE_OPT_KEY("rw", KEY_KERN_FLAG), - FUSE_OPT_KEY("suid", KEY_KERN_FLAG), - FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG), - FUSE_OPT_KEY("dev", KEY_KERN_FLAG), - FUSE_OPT_KEY("nodev", KEY_KERN_FLAG), - FUSE_OPT_KEY("exec", KEY_KERN_FLAG), - FUSE_OPT_KEY("noexec", KEY_KERN_FLAG), - FUSE_OPT_KEY("async", KEY_KERN_FLAG), - FUSE_OPT_KEY("sync", KEY_KERN_FLAG), - FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG), - FUSE_OPT_KEY("atime", KEY_KERN_FLAG), - FUSE_OPT_KEY("noatime", KEY_KERN_FLAG), - FUSE_OPT_KEY("relatime", KEY_KERN_FLAG), - FUSE_OPT_KEY("norelatime", KEY_KERN_FLAG), - FUSE_OPT_KEY("lazytime", KEY_KERN_FLAG), - FUSE_OPT_KEY("nolazytime", KEY_KERN_FLAG), - FUSE_OPT_KEY("diratime", KEY_KERN_FLAG), - FUSE_OPT_KEY("nodiratime", KEY_KERN_FLAG), - FUSE_OPT_KEY("strictatime", KEY_KERN_FLAG), - FUSE_OPT_KEY("nostrictatime", KEY_KERN_FLAG), + FUSE_MOUNT_OPT("allow_other",allow_other), + FUSE_MOUNT_OPT("blkdev",blkdev), + FUSE_MOUNT_OPT("auto_unmount",auto_unmount), + FUSE_MOUNT_OPT("fsname=%s",fsname), + FUSE_MOUNT_OPT("subtype=%s",subtype), + FUSE_OPT_KEY("allow_other",KEY_KERN_OPT), + FUSE_OPT_KEY("auto_unmount",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), + FUSE_OPT_KEY("context=",KEY_KERN_OPT), + FUSE_OPT_KEY("fscontext=",KEY_KERN_OPT), + FUSE_OPT_KEY("defcontext=",KEY_KERN_OPT), + FUSE_OPT_KEY("rootcontext=",KEY_KERN_OPT), + FUSE_OPT_KEY("max_read=",KEY_KERN_OPT), + FUSE_OPT_KEY("max_read=",FUSE_OPT_KEY_KEEP), + FUSE_OPT_KEY("user=",KEY_MTAB_OPT), + FUSE_OPT_KEY("-n",KEY_MTAB_OPT), + FUSE_OPT_KEY("-r",KEY_RO), + FUSE_OPT_KEY("ro",KEY_KERN_FLAG), + FUSE_OPT_KEY("rw",KEY_KERN_FLAG), + FUSE_OPT_KEY("suid",KEY_KERN_FLAG), + FUSE_OPT_KEY("nosuid",KEY_KERN_FLAG), + FUSE_OPT_KEY("dev",KEY_KERN_FLAG), + FUSE_OPT_KEY("nodev",KEY_KERN_FLAG), + FUSE_OPT_KEY("exec",KEY_KERN_FLAG), + FUSE_OPT_KEY("noexec",KEY_KERN_FLAG), + FUSE_OPT_KEY("async",KEY_KERN_FLAG), + FUSE_OPT_KEY("sync",KEY_KERN_FLAG), + FUSE_OPT_KEY("dirsync",KEY_KERN_FLAG), + FUSE_OPT_KEY("atime",KEY_KERN_FLAG), + FUSE_OPT_KEY("noatime",KEY_KERN_FLAG), + FUSE_OPT_KEY("relatime",KEY_KERN_FLAG), + FUSE_OPT_KEY("norelatime",KEY_KERN_FLAG), + FUSE_OPT_KEY("lazytime",KEY_KERN_FLAG), + FUSE_OPT_KEY("nolazytime",KEY_KERN_FLAG), + FUSE_OPT_KEY("diratime",KEY_KERN_FLAG), + FUSE_OPT_KEY("nodiratime",KEY_KERN_FLAG), + FUSE_OPT_KEY("strictatime",KEY_KERN_FLAG), + FUSE_OPT_KEY("nostrictatime",KEY_KERN_FLAG), FUSE_OPT_END }; -static void exec_fusermount(const char *argv[]) +static void +exec_fusermount(const char *argv[]) { - execv(FUSERMOUNT_DIR "/mergerfs-" FUSERMOUNT_PROG, (char **) argv); - execvp("mergerfs-" FUSERMOUNT_PROG, (char **) argv); - execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv); - execvp(FUSERMOUNT_PROG, (char **) argv); + execv(FUSERMOUNT_DIR "/mergerfs-" FUSERMOUNT_PROG,(char**)argv); + execvp("mergerfs-" FUSERMOUNT_PROG,(char**)argv); + execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG,(char**)argv); + execvp(FUSERMOUNT_PROG,(char**)argv); + execv(FUSERMOUNT_DIR "/" FUSERMOUNT3_PROG,(char**)argv); + execvp(FUSERMOUNT3_PROG,(char**)argv); } -struct mount_flags { +struct mount_flags +{ const char *opt; unsigned long flag; int on; }; -static -const -struct mount_flags -mount_flags[] = +static const struct mount_flags mount_flags[] = { - {"rw", MS_RDONLY, 0}, - {"ro", MS_RDONLY, 1}, - {"suid", MS_NOSUID, 0}, - {"nosuid", MS_NOSUID, 1}, - {"dev", MS_NODEV, 0}, - {"nodev", MS_NODEV, 1}, - {"exec", MS_NOEXEC, 0}, - {"noexec", MS_NOEXEC, 1}, - {"async", MS_SYNCHRONOUS, 0}, - {"sync", MS_SYNCHRONOUS, 1}, - {"atime", MS_NOATIME, 0}, - {"noatime", MS_NOATIME, 1}, - {"relatime", MS_RELATIME, 1}, - {"norelatime", MS_RELATIME, 0}, - {"lazytime", MS_LAZYTIME, 1}, - {"nolazytime", MS_LAZYTIME, 0}, - {"diratime", MS_NODIRATIME, 0}, - {"nodiratime", MS_NODIRATIME, 1}, - {"strictatime", MS_STRICTATIME, 1}, - {"nostrictatime",MS_STRICTATIME, 0}, + { "rw", MS_RDONLY, 0 }, + { "ro", MS_RDONLY, 1 }, + { "suid", MS_NOSUID, 0 }, + { "nosuid", MS_NOSUID, 1 }, + { "dev", MS_NODEV, 0 }, + { "nodev", MS_NODEV, 1 }, + { "exec", MS_NOEXEC, 0 }, + { "noexec", MS_NOEXEC, 1 }, + { "async", MS_SYNCHRONOUS, 0 }, + { "sync", MS_SYNCHRONOUS, 1 }, + { "atime", MS_NOATIME, 0 }, + { "noatime", MS_NOATIME, 1 }, + { "relatime", MS_RELATIME, 1 }, + { "norelatime", MS_RELATIME, 0 }, + { "lazytime", MS_LAZYTIME, 1 }, + { "nolazytime", MS_LAZYTIME, 0 }, + { "diratime", MS_NODIRATIME, 0 }, + { "nodiratime", MS_NODIRATIME, 1 }, + { "strictatime", MS_STRICTATIME, 1 }, + { "nostrictatime", MS_STRICTATIME, 0 }, #ifndef __NetBSD__ - {"dirsync", MS_DIRSYNC, 1}, + { "dirsync", MS_DIRSYNC, 1 }, #endif - {NULL, 0, 0} + { NULL, 0, 0 } }; static @@ -172,7 +177,7 @@ set_mount_flag(const char *s, { int i; - for (i = 0; mount_flags[i].opt != NULL; i++) + for(i = 0; mount_flags[i].opt != NULL; i++) { const char *opt = mount_flags[i].opt; if(strcmp(opt, s) == 0) @@ -189,12 +194,13 @@ set_mount_flag(const char *s, abort(); } -static int fuse_mount_opt_proc(void *data, const char *arg, int key, - struct fuse_args *outargs) +static int +fuse_mount_opt_proc(void *data, const char *arg, int key, + struct fuse_args *outargs) { - struct mount_opts *mo = static_cast(data); + struct mount_opts *mo = static_cast(data); - switch (key) + switch(key) { case KEY_RO: arg = "ro"; @@ -216,8 +222,8 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key, return fuse_opt_add_opt(&mo->mtab_opts, arg); case FUSE_OPT_KEY_OPT: - if(strncmp("x-",arg,2) == 0) - return fuse_opt_add_opt(&mo->mtab_opts,arg); + if(strncmp("x-", arg, 2) == 0) + return fuse_opt_add_opt(&mo->mtab_opts, arg); return 1; } @@ -229,7 +235,9 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key, * >= 0 => fd * -1 => error */ -static int receive_fd(int fd) +static +int +receive_fd(int fd) { struct msghdr msg; struct iovec iov; @@ -251,168 +259,187 @@ static int receive_fd(int fd) msg.msg_control = ccmsg; msg.msg_controllen = sizeof(ccmsg); - while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR); - if (rv == -1) { - perror("recvmsg"); - return -1; - } - if(!rv) { - /* EOF */ - return -1; - } + while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR) + ; + if(rv == -1) + { + perror("recvmsg"); + return -1; + } + if(!rv) + { + /* EOF */ + return -1; + } cmsg = CMSG_FIRSTHDR(&msg); if(!cmsg) { - fprintf(stderr,"no control message received or not enough buf space\n"); + fprintf(stderr, + "no control message received or not enough buf space\n"); return -1; } if(cmsg->cmsg_type != SCM_RIGHTS) { - fprintf(stderr, - "got control message of unknown type %d\n", + fprintf(stderr, "got control message of unknown type %d\n", cmsg->cmsg_type); return -1; } - return *reinterpret_cast(CMSG_DATA(cmsg)); + return *reinterpret_cast(CMSG_DATA(cmsg)); } -void fuse_kern_unmount(const char *mountpoint, int fd) +void +fuse_kern_unmount(const char *mountpoint, + int fd) { int res; int pid; - if (!mountpoint) + if(!mountpoint) return; - if (fd != -1) { - struct pollfd pfd; + if(fd != -1) + { + struct pollfd pfd; - pfd.fd = fd; - pfd.events = 0; - res = poll(&pfd, 1, 0); + pfd.fd = fd; + pfd.events = 0; + res = poll(&pfd, 1, 0); - /* Need to close file descriptor, otherwise synchronous umount - would recurse into filesystem, and deadlock. + /* Need to close file descriptor, otherwise synchronous umount + would recurse into filesystem, and deadlock. - Caller expects fuse_kern_unmount to close the fd, so close it - anyway. */ - close(fd); + Caller expects fuse_kern_unmount to close the fd, so close it + anyway. */ + close(fd); - /* If file poll returns POLLERR on the device file descriptor, - then the filesystem is already unmounted */ - if (res == 1 && (pfd.revents & POLLERR)) - return; - } + /* If file poll returns POLLERR on the device file descriptor, + then the filesystem is already unmounted */ + if(res == 1 &&(pfd.revents & POLLERR)) + return; + } - if (geteuid() == 0) { - fuse_mnt_umount("fuse", mountpoint, mountpoint, 1); - return; - } + if(geteuid() == 0) + { + fuse_mnt_umount("fuse", mountpoint, mountpoint, 1); + return; + } - res = umount2(mountpoint, 2); - if (res == 0) + res = umount2(mountpoint,MNT_DETACH); + if(res == 0) return; pid = fork(); if(pid == -1) return; - if(pid == 0) { - const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z", - "--", mountpoint, NULL }; + if(pid == 0) + { + const char *argv[] = + { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL }; - exec_fusermount(argv); - _exit(1); - } + exec_fusermount(argv); + perror("mergerfs: failed to exec fusermount"); + _exit(1); + } waitpid(pid, NULL, 0); } -static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, - const char *opts, int quiet) +static +int +fuse_mount_fusermount(const char *mountpoint, + struct mount_opts *mo, + const char *opts, + int quiet) { - int fds[2], pid; + int fds[2]; + int pid; int res; int rv; - if (!mountpoint) { - fprintf(stderr, "mergerfs: missing mountpoint parameter\n"); - return -1; - } + if(!mountpoint) + { + fprintf(stderr, "mergerfs: missing mountpoint parameter\n"); + return -1; + } res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds); - if(res == -1) { - perror("mergerfs: socketpair() failed"); - return -1; - } + if(res == -1) + { + perror("mergerfs: socketpair() failed"); + return -1; + } pid = fork(); - if(pid == -1) { - perror("mergerfs: fork() failed"); - close(fds[0]); - close(fds[1]); - return -1; - } - - if(pid == 0) { - char env[10]; - const char *argv[32]; - int a = 0; - - if (quiet) { - int fd = open("/dev/null", O_RDONLY); - if (fd != -1) { - dup2(fd, 1); - dup2(fd, 2); - } + if(pid == -1) + { + perror("mergerfs: fork() failed"); + close(fds[0]); + close(fds[1]); + return -1; } - argv[a++] = FUSERMOUNT_PROG; - if (opts) { - argv[a++] = "-o"; - argv[a++] = opts; + if(pid == 0) + { + char env[10]; + const char *argv[32]; + int a = 0; + + if(quiet) + { + int fd = open("/dev/null", O_RDONLY); + if(fd != -1) + { + dup2(fd, 1); + dup2(fd, 2); + } + } + + argv[a++] = FUSERMOUNT_PROG; + if(opts) + { + argv[a++] = "-o"; + argv[a++] = opts; + } + argv[a++] = "--"; + argv[a++] = mountpoint; + argv[a++] = NULL; + + close(fds[1]); + fcntl(fds[0], F_SETFD, 0); + snprintf(env, sizeof(env), "%i", fds[0]); + setenv(FUSE_COMMFD_ENV, env, 1); + exec_fusermount(argv); + perror("mergerfs: failed to exec fusermount"); + _exit(1); } - argv[a++] = "--"; - argv[a++] = mountpoint; - argv[a++] = NULL; - - close(fds[1]); - fcntl(fds[0], F_SETFD, 0); - snprintf(env, sizeof(env), "%i", fds[0]); - setenv(FUSE_COMMFD_ENV, env, 1); - exec_fusermount(argv); - perror("mergerfs: failed to exec fusermount"); - _exit(1); - } close(fds[0]); rv = receive_fd(fds[1]); - if (!mo->auto_unmount) { - /* with auto_unmount option fusermount will not exit until - this socket is closed */ - close(fds[1]); - waitpid(pid, NULL, 0); /* bury zombie */ - } + if(!mo->auto_unmount) + { + /* with auto_unmount option fusermount will not exit until + this socket is closed */ + close(fds[1]); + waitpid(pid, NULL, 0); /* bury zombie */ + } return rv; } -static -int -fuse_mount_sys(const char *mnt, - struct mount_opts *mo, - const char *mnt_opts) +static int +fuse_mount_sys(const char *mnt, struct mount_opts *mo, const char *mnt_opts) { + int fd; + int res; char tmp[128]; const char *devname = "/dev/fuse"; std::string source; std::string type; struct stat stbuf; - int fd; - int res; if(!mnt) { @@ -432,7 +459,7 @@ fuse_mount_sys(const char *mnt, mnt); res = umount(mnt); if(res == 0) - fprintf(stderr,"mergerfs: umount succeeded"); + fprintf(stderr, "mergerfs: umount succeeded"); break; default: fprintf(stderr, @@ -443,13 +470,13 @@ fuse_mount_sys(const char *mnt, break; } - memset(&stbuf,0,sizeof(stbuf)); + memset(&stbuf, 0, sizeof(stbuf)); res = stat(mnt,&stbuf); if(res == -1) stbuf.st_mode = S_IFDIR; } - if (mo->auto_unmount) + if(mo->auto_unmount) { /* Tell the caller to fallback to fusermount because auto-unmount does not work otherwise. */ @@ -460,10 +487,11 @@ fuse_mount_sys(const char *mnt, if(fd == -1) { if(errno == ENODEV || errno == ENOENT) - fprintf(stderr, "mergerfs: device not found, try 'modprobe fuse' first\n"); + fprintf(stderr, + "mergerfs: device not found, try 'modprobe fuse' first\n"); else - fprintf(stderr, "mergerfs: failed to open %s: %s\n", - devname, strerror(errno)); + fprintf(stderr, "mergerfs: failed to open %s: %s\n", devname, + strerror(errno)); return -1; } @@ -471,100 +499,112 @@ fuse_mount_sys(const char *mnt, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%u,group_id=%u", fd, - stbuf.st_mode & S_IFMT, + (stbuf.st_mode & S_IFMT), getuid(), getgid()); res = fuse_opt_add_opt(&mo->kernel_opts, tmp); - if (res == -1) + if(res == -1) goto out_close; type = mo->blkdev ? "fuseblk" : "fuse"; - if (mo->subtype) + if(mo->subtype) type += "." + std::string(mo->subtype); - source = mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname); - - res = mount(source.c_str(), mnt, type.c_str(), mo->flags, mo->kernel_opts); - if (res == -1 && errno == ENODEV && mo->subtype) { - /* Probably missing subtype support */ - type = mo->blkdev ? "fuseblk" : "fuse"; - if (mo->fsname) { - if (!mo->blkdev) - source = std::string(mo->subtype) + "#" + mo->fsname; - } else { - source = type; - } - res = mount(source.c_str(), mnt, type.c_str(), 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) { - res = -2; - } else { - int errno_save = errno; - if (mo->blkdev && errno == ENODEV && - !fuse_mnt_check_fuseblk()) + source = mo->fsname ? mo->fsname :(mo->subtype ? mo->subtype : devname); + + res = mount(source.c_str(), mnt, type.c_str(), mo->flags, + mo->kernel_opts); + if(res == -1 && errno == ENODEV && mo->subtype) + { + /* Probably missing subtype support */ + type = mo->blkdev ? "fuseblk" : "fuse"; + if(mo->fsname) { - fprintf(stderr, - "mergerfs: 'fuseblk' support missing\n"); + if(!mo->blkdev) + source = std::string(mo->subtype) + "#" + mo->fsname; } else { - fprintf(stderr, - "mergerfs: mount failed: %s\n", - strerror(errno_save)); + source = type; } + res = mount(source.c_str(), mnt, type.c_str(), 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) + { + res = -2; + } + else + { + int errno_save = errno; + if(mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk()) + { + fprintf(stderr,"mergerfs: 'fuseblk' support missing\n"); + } + else + { + fprintf(stderr, + "mergerfs: mount failed: %s\n", + strerror(errno_save)); + } + } - goto out_close; - } + goto out_close; + } #ifndef __NetBSD__ #ifndef IGNORE_MTAB - if (geteuid() == 0) { - char *newmnt = fuse_mnt_resolve_path("fuse", mnt); - res = -1; - if (!newmnt) - goto out_umount; - - res = fuse_mnt_add_mount("fuse", source.c_str(), newmnt, type.c_str(), - mnt_opts); - free(newmnt); - if (res == -1) - goto out_umount; - } + if(geteuid() == 0) + { + char *newmnt = fuse_mnt_resolve_path("fuse", mnt); + res = -1; + if(!newmnt) + goto out_umount; + + res = fuse_mnt_add_mount("fuse", source.c_str(), newmnt, type.c_str(), + mnt_opts); + free(newmnt); + if(res == -1) + goto out_umount; + } #endif /* IGNORE_MTAB */ #endif /* __NetBSD__ */ return fd; out_umount: - umount2(mnt, 2); /* lazy umount */ + umount2(mnt,MNT_DETACH); /* lazy umount */ out_close: close(fd); return res; } -static int get_mnt_flag_opts(char **mnt_optsp, int flags) +static int +get_mnt_flag_opts(char **mnt_optsp, int flags) { int i; - if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1) + if(!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1) return -1; - for (i = 0; mount_flags[i].opt != NULL; i++) { - if (mount_flags[i].on && (flags & mount_flags[i].flag) && - fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1) - return -1; - } + for(i = 0; mount_flags[i].opt != NULL; i++) + { + if(mount_flags[i].on &&(flags & mount_flags[i].flag) + && fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1) + return -1; + } return 0; } -int fuse_kern_mount(const char *mountpoint, struct fuse_args *args) +int +fuse_kern_mount(const char *mountpoint, struct fuse_args *args) { struct mount_opts mo; int res = -1; @@ -573,43 +613,48 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args) memset(&mo, 0, sizeof(mo)); mo.flags = MS_NOSUID | MS_NODEV; - if(args && - fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) + if(args + && fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) + == -1) return -1; res = -1; - if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1) + if(get_mnt_flag_opts(&mnt_opts, mo.flags) == -1) goto out; - if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1) + if(mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1) goto out; - if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1) + if(mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1) goto out; res = fuse_mount_sys(mountpoint, &mo, mnt_opts); - if (res == -2) { - if (mo.fusermount_opts && - fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1) - goto out; - - 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); + if(res == -2) + { + if(mo.fusermount_opts + && fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1) goto out; - } - - res = fuse_mount_fusermount(mountpoint, &mo, tmp_opts, 1); - free(tmp_opts); - if (res == -1) - res = fuse_mount_fusermount(mountpoint, &mo, - mnt_opts, 0); - } else { - res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0); + + 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, &mo, tmp_opts, 1); + free(tmp_opts); + if(res == -1) + res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0); + } + else + { + res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0); + } } - } out: free(mnt_opts); free(mo.fsname);