aboutsummaryrefslogtreecommitdiff
path: root/lib/mount.c
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2007-12-12 14:25:40 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2007-12-12 14:25:40 +0000
commitcdb8b79bad5fea81b74931a9027f1d5ca344af8e (patch)
tree11ab550f265dc3eb546b7c26f3745e6d139b1fcc /lib/mount.c
parent918f0ad95b73e506d20488cb8ddd35d1a2524c7c (diff)
change indenting
Diffstat (limited to 'lib/mount.c')
-rw-r--r--lib/mount.c966
1 files changed, 485 insertions, 481 deletions
diff --git a/lib/mount.c b/lib/mount.c
index 8a5c5ab..14fbfb5 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "config.h"
@@ -25,8 +25,8 @@
#include <sys/wait.h>
#include <sys/mount.h>
-#define FUSERMOUNT_PROG "fusermount"
-#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+#define FUSERMOUNT_PROG "fusermount"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#ifndef HAVE_FORK
#define fork() vfork()
@@ -37,551 +37,555 @@
#endif
enum {
- KEY_KERN_FLAG,
- KEY_KERN_OPT,
- KEY_FUSERMOUNT_OPT,
- KEY_SUBTYPE_OPT,
- KEY_MTAB_OPT,
- KEY_ALLOW_ROOT,
- KEY_RO,
- KEY_HELP,
- KEY_VERSION,
+ KEY_KERN_FLAG,
+ KEY_KERN_OPT,
+ KEY_FUSERMOUNT_OPT,
+ KEY_SUBTYPE_OPT,
+ KEY_MTAB_OPT,
+ KEY_ALLOW_ROOT,
+ KEY_RO,
+ KEY_HELP,
+ KEY_VERSION,
};
struct mount_opts {
- int allow_other;
- int allow_root;
- int ishelp;
- int flags;
- int nonempty;
- int blkdev;
- char *fsname;
- char *subtype;
- char *subtype_opt;
- char *mtab_opts;
- char *fusermount_opts;
- char *kernel_opts;
+ int allow_other;
+ int allow_root;
+ int ishelp;
+ int flags;
+ int nonempty;
+ int blkdev;
+ char *fsname;
+ char *subtype;
+ char *subtype_opt;
+ char *mtab_opts;
+ char *fusermount_opts;
+ char *kernel_opts;
};
#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
static const struct fuse_opt fuse_mount_opts[] = {
- FUSE_MOUNT_OPT("allow_other", allow_other),
- FUSE_MOUNT_OPT("allow_root", allow_root),
- 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),
- 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("-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("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
+ FUSE_MOUNT_OPT("allow_other", allow_other),
+ FUSE_MOUNT_OPT("allow_root", allow_root),
+ 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),
+ 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("-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("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_END
};
static void mount_help(void)
{
- fprintf(stderr,
- " -o allow_other allow access to other users\n"
- " -o allow_root allow access to root\n"
- " -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"
- );
+ fprintf(stderr,
+" -o allow_other allow access to other users\n"
+" -o allow_root allow access to root\n"
+" -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");
}
static void exec_fusermount(const char *argv[])
{
- execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
- execvp(FUSERMOUNT_PROG, (char **) argv);
+ execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
+ execvp(FUSERMOUNT_PROG, (char **) argv);
}
static void mount_version(void)
{
- int pid = fork();
- if (!pid) {
- const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
- exec_fusermount(argv);
- _exit(1);
- } else if (pid != -1)
- waitpid(pid, NULL, 0);
+ int pid = fork();
+ if (!pid) {
+ const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
+ exec_fusermount(argv);
+ _exit(1);
+ } else if (pid != -1)
+ waitpid(pid, NULL, 0);
}
struct mount_flags {
- const char *opt;
- unsigned long flag;
- int on;
+ const char *opt;
+ unsigned long flag;
+ int on;
};
static 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},
- {"dirsync", MS_DIRSYNC, 1},
- {NULL, 0, 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},
+ {"dirsync", MS_DIRSYNC, 1},
+ {NULL, 0, 0}
};
static void set_mount_flag(const char *s, int *flags)
{
- int i;
-
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- const char *opt = mount_flags[i].opt;
- if (strcmp(opt, s) == 0) {
- if (mount_flags[i].on)
- *flags |= mount_flags[i].flag;
- else
- *flags &= ~mount_flags[i].flag;
- return;
- }
- }
- fprintf(stderr, "fuse: internal error, can't find mount flag\n");
- abort();
+ int i;
+
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ const char *opt = mount_flags[i].opt;
+ if (strcmp(opt, s) == 0) {
+ if (mount_flags[i].on)
+ *flags |= mount_flags[i].flag;
+ else
+ *flags &= ~mount_flags[i].flag;
+ return;
+ }
+ }
+ fprintf(stderr, "fuse: internal error, can't find mount flag\n");
+ abort();
}
static int fuse_mount_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct mount_opts *mo = data;
-
- switch (key) {
- case KEY_ALLOW_ROOT:
- if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
- fuse_opt_add_arg(outargs, "-oallow_root") == -1)
- return -1;
- return 0;
-
- case KEY_RO:
- arg = "ro";
- /* fall through */
- case KEY_KERN_FLAG:
- set_mount_flag(arg, &mo->flags);
- return 0;
-
- case KEY_KERN_OPT:
- return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- 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);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
- }
- return 1;
+ struct mount_opts *mo = data;
+
+ switch (key) {
+ case KEY_ALLOW_ROOT:
+ if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
+ fuse_opt_add_arg(outargs, "-oallow_root") == -1)
+ return -1;
+ return 0;
+
+ case KEY_RO:
+ arg = "ro";
+ /* fall through */
+ case KEY_KERN_FLAG:
+ set_mount_flag(arg, &mo->flags);
+ return 0;
+
+ case KEY_KERN_OPT:
+ return fuse_opt_add_opt(&mo->kernel_opts, arg);
+
+ 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);
+
+ case KEY_HELP:
+ mount_help();
+ mo->ishelp = 1;
+ break;
+
+ case KEY_VERSION:
+ mount_version();
+ mo->ishelp = 1;
+ break;
+ }
+ return 1;
}
/* return value:
- * >= 0 => fd
- * -1 => error
+ * >= 0 => fd
+ * -1 => error
*/
static int receive_fd(int fd)
{
- struct msghdr msg;
- struct iovec iov;
- char buf[1];
- int rv;
- size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
- struct cmsghdr *cmsg;
-
- iov.iov_base = buf;
- iov.iov_len = 1;
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- /* old BSD implementations should use msg_accrights instead of
- * msg_control; the interface is different. */
- 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;
- }
-
- cmsg = CMSG_FIRSTHDR(&msg);
- if (!cmsg->cmsg_type == SCM_RIGHTS) {
- fprintf(stderr, "got control message of unknown type %d\n",
- cmsg->cmsg_type);
- return -1;
- }
- return *(int*)CMSG_DATA(cmsg);
+ struct msghdr msg;
+ struct iovec iov;
+ char buf[1];
+ int rv;
+ size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ /* old BSD implementations should use msg_accrights instead of
+ * msg_control; the interface is different. */
+ 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;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr, "got control message of unknown type %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ return *(int*)CMSG_DATA(cmsg);
}
void fuse_kern_unmount(const char *mountpoint, int fd)
{
- int res;
- int pid;
-
- if (!mountpoint)
- return;
-
- if (fd != -1) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = 0;
- res = poll(&pfd, 1, 0);
- /* If file poll returns POLLERR on the device file descriptor,
- then the filesystem is already unmounted */
- if (res == 1 && (pfd.revents & POLLERR))
- return;
-
- /* Need to close file descriptor, otherwise synchronous umount
- would recurse into filesystem, and deadlock */
- close(fd);
- }
-
- if (geteuid() == 0) {
- fuse_mnt_umount("fuse", mountpoint, 1);
- return;
- }
-
- res = umount2(mountpoint, 2);
- if (res == 0)
- return;
-
- pid = fork();
- if(pid == -1)
- return;
-
- if(pid == 0) {
- const char *argv[] =
- { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL };
-
- exec_fusermount(argv);
- _exit(1);
- }
- waitpid(pid, NULL, 0);
+ int res;
+ int pid;
+
+ if (!mountpoint)
+ return;
+
+ if (fd != -1) {
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = 0;
+ res = poll(&pfd, 1, 0);
+ /* If file poll returns POLLERR on the device file descriptor,
+ then the filesystem is already unmounted */
+ if (res == 1 && (pfd.revents & POLLERR))
+ return;
+
+ /* Need to close file descriptor, otherwise synchronous umount
+ would recurse into filesystem, and deadlock */
+ close(fd);
+ }
+
+ if (geteuid() == 0) {
+ fuse_mnt_umount("fuse", mountpoint, 1);
+ return;
+ }
+
+ res = umount2(mountpoint, 2);
+ if (res == 0)
+ return;
+
+ pid = fork();
+ if(pid == -1)
+ return;
+
+ if(pid == 0) {
+ const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
+ "--", mountpoint, NULL };
+
+ exec_fusermount(argv);
+ _exit(1);
+ }
+ waitpid(pid, NULL, 0);
}
void fuse_unmount_compat22(const char *mountpoint)
{
- fuse_kern_unmount(mountpoint, -1);
+ fuse_kern_unmount(mountpoint, -1);
}
static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
- int quiet)
+ int quiet)
{
- int fds[2], pid;
- int res;
- int rv;
-
- if (!mountpoint) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
- if(res == -1) {
- perror("fuse: socketpair() failed");
- return -1;
- }
-
- pid = fork();
- if(pid == -1) {
- perror("fuse: 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);
- 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("fuse: failed to exec fusermount");
- _exit(1);
- }
-
- close(fds[0]);
- rv = receive_fd(fds[1]);
- close(fds[1]);
- waitpid(pid, NULL, 0); /* bury zombie */
-
- return rv;
+ int fds[2], pid;
+ int res;
+ int rv;
+
+ if (!mountpoint) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+ if(res == -1) {
+ perror("fuse: socketpair() failed");
+ return -1;
+ }
+
+ pid = fork();
+ if(pid == -1) {
+ perror("fuse: 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);
+ 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("fuse: failed to exec fusermount");
+ _exit(1);
+ }
+
+ close(fds[0]);
+ rv = receive_fd(fds[1]);
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+
+ return rv;
}
int fuse_mount_compat22(const char *mountpoint, const char *opts)
{
- return fuse_mount_fusermount(mountpoint, opts, 0);
+ 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 *mnt_opts)
{
- char tmp[128];
- const char *devname = "/dev/fuse";
- char *source = NULL;
- char *type = NULL;
- struct stat stbuf;
- int fd;
- int res;
-
- if (!mnt) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = lstat(mnt, &stbuf);
- if (res == -1) {
- fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
- mnt, strerror(errno));
- return -1;
- }
-
- if (!mo->nonempty) {
- res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size);
- if (res == -1)
- return -1;
- }
-
- fd = open(devname, O_RDWR);
- if (fd == -1) {
- if (errno == ENODEV || errno == ENOENT)
- fprintf(stderr,
- "fuse: device not found, try 'modprobe fuse' first\n");
- else
- fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
- strerror(errno));
- return -1;
- }
-
- snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
- stbuf.st_mode & S_IFMT, getuid(), getgid());
-
- res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
- if (res == -1)
- goto out_close;
-
- 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) {
- res = -2;
- } 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;
- }
-
- 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, newmnt, type, mnt_opts);
- free(newmnt);
- if (res == -1)
- goto out_umount;
- }
-
- return fd;
-
- out_umount:
- umount2(mnt, 2); /* lazy umount */
- out_close:
- free(type);
- free(source);
- close(fd);
- return res;
+ char tmp[128];
+ const char *devname = "/dev/fuse";
+ char *source = NULL;
+ char *type = NULL;
+ struct stat stbuf;
+ int fd;
+ int res;
+
+ if (!mnt) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = lstat(mnt, &stbuf);
+ if (res == -1) {
+ fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
+ mnt, strerror(errno));
+ return -1;
+ }
+
+ if (!mo->nonempty) {
+ res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode,
+ stbuf.st_size);
+ if (res == -1)
+ return -1;
+ }
+
+ fd = open(devname, O_RDWR);
+ if (fd == -1) {
+ if (errno == ENODEV || errno == ENOENT)
+ fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n");
+ else
+ fprintf(stderr, "fuse: failed to open %s: %s\n",
+ devname, strerror(errno));
+ return -1;
+ }
+
+ snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ fd, stbuf.st_mode & S_IFMT, getuid(), getgid());
+
+ res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
+ if (res == -1)
+ goto out_close;
+
+ 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) {
+ res = -2;
+ } 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;
+ }
+
+ 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, newmnt, type,
+ mnt_opts);
+ free(newmnt);
+ if (res == -1)
+ goto out_umount;
+ }
+
+ return fd;
+
+out_umount:
+ umount2(mnt, 2); /* lazy umount */
+out_close:
+ free(type);
+ free(source);
+ close(fd);
+ return res;
}
static int get_mnt_flag_opts(char **mnt_optsp, int flags)
{
- int i;
+ int i;
- if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
- return -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;
- }
- return 0;
+ 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)
{
- struct mount_opts mo;
- int res = -1;
- char *mnt_opts = NULL;
-
- 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)
- return -1;
-
- if (mo.allow_other && mo.allow_root) {
- fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
- }
- res = 0;
- if (mo.ishelp)
- goto out;
-
- res = -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)
- goto out;
- 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);
- 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;
+ struct mount_opts mo;
+ int res = -1;
+ char *mnt_opts = NULL;
+
+ 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)
+ return -1;
+
+ if (mo.allow_other && mo.allow_root) {
+ fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
+ goto out;
+ }
+ res = 0;
+ if (mo.ishelp)
+ goto out;
+
+ res = -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)
+ goto out;
+ 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);
+ 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;
}
FUSE_SYMVER(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");