11#include "fuse_config.h"
18#include "fuse_mount_compat.h"
29#define FUSERMOUNT_PROG "mount_fusefs"
30#define FUSE_DEV_TRUNK "/dev/fuse"
43#define FUSE_DUAL_OPT_KEY(templ, key) \
44 FUSE_OPT_KEY(templ, key), FUSE_OPT_KEY("no" templ, key)
46static const struct fuse_opt fuse_mount_opts[] = {
47 {
"allow_other", offsetof(
struct mount_opts, allow_other), 1 },
48 {
"max_read=%u", offsetof(
struct mount_opts, max_read), 1 },
51 FUSE_DUAL_OPT_KEY(
"dev", KEY_KERN),
52 FUSE_DUAL_OPT_KEY(
"async", KEY_KERN),
53 FUSE_DUAL_OPT_KEY(
"atime", KEY_KERN),
54 FUSE_DUAL_OPT_KEY(
"dev", KEY_KERN),
55 FUSE_DUAL_OPT_KEY(
"exec", KEY_KERN),
56 FUSE_DUAL_OPT_KEY(
"suid", KEY_KERN),
57 FUSE_DUAL_OPT_KEY(
"symfollow", KEY_KERN),
58 FUSE_DUAL_OPT_KEY(
"rdonly", KEY_KERN),
59 FUSE_DUAL_OPT_KEY(
"sync", KEY_KERN),
60 FUSE_DUAL_OPT_KEY(
"union", KEY_KERN),
61 FUSE_DUAL_OPT_KEY(
"userquota", KEY_KERN),
62 FUSE_DUAL_OPT_KEY(
"groupquota", KEY_KERN),
63 FUSE_DUAL_OPT_KEY(
"clusterr", KEY_KERN),
64 FUSE_DUAL_OPT_KEY(
"clusterw", KEY_KERN),
65 FUSE_DUAL_OPT_KEY(
"suiddir", KEY_KERN),
66 FUSE_DUAL_OPT_KEY(
"snapshot", KEY_KERN),
67 FUSE_DUAL_OPT_KEY(
"multilabel", KEY_KERN),
68 FUSE_DUAL_OPT_KEY(
"acls", KEY_KERN),
69 FUSE_DUAL_OPT_KEY(
"force", KEY_KERN),
70 FUSE_DUAL_OPT_KEY(
"update", KEY_KERN),
71 FUSE_DUAL_OPT_KEY(
"ro", KEY_KERN),
72 FUSE_DUAL_OPT_KEY(
"rw", KEY_KERN),
73 FUSE_DUAL_OPT_KEY(
"auto", KEY_KERN),
74 FUSE_DUAL_OPT_KEY(
"automounted", KEY_KERN),
76 FUSE_DUAL_OPT_KEY(
"allow_other", KEY_KERN),
77 FUSE_DUAL_OPT_KEY(
"default_permissions",KEY_KERN),
81 FUSE_DUAL_OPT_KEY(
"private", KEY_KERN),
82 FUSE_DUAL_OPT_KEY(
"neglect_shares", KEY_KERN),
83 FUSE_DUAL_OPT_KEY(
"push_symlinks_in", KEY_KERN),
84#if __FreeBSD_version >= 1200519
85 FUSE_DUAL_OPT_KEY(
"intr", KEY_KERN),
96void fuse_mount_version(
void)
98 system(FUSERMOUNT_PROG
" --version");
101unsigned get_max_read(
struct mount_opts *o)
106static int fuse_mount_opt_proc(
void *data,
const char *arg,
int key,
110 struct mount_opts *mo = data;
125void fuse_kern_unmount(
const char *mountpoint,
int fd)
128 fuse_log(FUSE_LOG_ERR,
"closing FD %d failed: %s", fd, strerror(errno));
129 if (unmount(mountpoint, MNT_FORCE) < 0)
130 fuse_log(FUSE_LOG_ERR,
"unmounting %s failed: %s",
131 mountpoint, strerror(errno));
134static int fuse_mount_core(
const char *mountpoint,
const char *opts)
136 const char *mountprog = FUSERMOUNT_PROG;
143 fdnam = getenv(
"FUSE_DEV_FD");
146 err = libfuse_strtol(fdnam, &fd);
148 fuse_log(FUSE_LOG_ERR,
"invalid value given in FUSE_DEV_FD\n");
155 dev = getenv(
"FUSE_DEV_NAME");
158 dev = (
char *)FUSE_DEV_TRUNK;
160 if ((fd = open(dev, O_RDWR)) < 0) {
161 perror(
"fuse: failed to open fuse device");
166 if (getenv(
"FUSE_NO_MOUNT") || ! mountpoint)
173 perror(
"fuse: fork() failed");
182 perror(
"fuse: fork() failed");
188 const char *argv[32];
194 ret = asprintf(&fdnam,
"%ld", fd);
197 perror(
"fuse: failed to assemble mount arguments");
203 argv[a++] = mountprog;
209 argv[a++] = mountpoint;
211 execvp(mountprog, (
char **) argv);
212 perror(
"fuse: failed to exec mount program");
220 if (waitpid(cpid, &status, 0) == -1 || WEXITSTATUS(status) != 0) {
221 perror(
"fuse: failed to mount file system");
223 perror(
"fuse: closing FD");
231struct mount_opts *parse_mount_opts(
struct fuse_args *args)
233 struct mount_opts *mo;
235 mo = (
struct mount_opts*) malloc(
sizeof(
struct mount_opts));
239 memset(mo, 0,
sizeof(
struct mount_opts));
242 fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
248 destroy_mount_opts(mo);
252void destroy_mount_opts(
struct mount_opts *mo)
254 free(mo->kernel_opts);
258int fuse_kern_mount(
const char *mountpoint,
struct mount_opts *mo)
261 setenv(
"MOUNT_FUSEFS_SAFE",
"1", 1);
263 setenv(
"MOUNT_FUSEFS_CALL_BY_LIB",
"1", 1);
265 return fuse_mount_core(mountpoint, mo->kernel_opts);
void fuse_log(enum fuse_log_level level, const char *fmt,...)
#define FUSE_OPT_KEY(templ, key)
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
int fuse_opt_add_opt(char **opts, const char *opt)