diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-17 15:05:40 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2006-03-17 15:05:40 +0000 |
commit | 6f385414b27e929bd14435ea8342cde4bae0ef8d (patch) | |
tree | c5a557fa053ebd9d96331f9d620d96a80a1282bd /lib | |
parent | 9db31dc1cff5ae2e854649f039f319d45eb58cf3 (diff) | |
download | libfuse-6f385414b27e929bd14435ea8342cde4bae0ef8d.tar.gz |
fix
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse.c | 37 | ||||
-rw-r--r-- | lib/fuse_i.h | 12 | ||||
-rw-r--r-- | lib/fuse_session.c | 11 | ||||
-rw-r--r-- | lib/fuse_versionscript | 9 | ||||
-rw-r--r-- | lib/helper.c | 113 | ||||
-rw-r--r-- | lib/mount.c | 45 | ||||
-rw-r--r-- | lib/mount_bsd.c | 12 |
7 files changed, 164 insertions, 75 deletions
@@ -617,6 +617,7 @@ static void fuse_data_init(void *data, struct fuse_conn_info *conn) memset(c, 0, sizeof(*c)); c->fuse = f; + c->private_data = f->user_data; if (f->op.init) f->user_data = f->op.init(conn); @@ -1998,11 +1999,10 @@ int fuse_is_lib_option(const char *opt) fuse_opt_match(fuse_lib_opts, opt); } -struct fuse *fuse_new_common(int fd, struct fuse_args *args, +struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, const struct fuse_operations *op, - size_t op_size, int compat) + size_t op_size, void *user_data, int compat) { - struct fuse_chan *ch; struct fuse *f; struct node *root; @@ -2017,6 +2017,7 @@ struct fuse *fuse_new_common(int fd, struct fuse_args *args, goto out; } + f->user_data = user_data; f->conf.entry_timeout = 1.0; f->conf.attr_timeout = 1.0; f->conf.negative_timeout = 0.0; @@ -2045,10 +2046,6 @@ struct fuse *fuse_new_common(int fd, struct fuse_args *args, if (f->se == NULL) goto out_free; - ch = fuse_kern_chan_new(fd); - if (ch == NULL) - goto out_free_session; - fuse_session_add_chan(f->se, ch); f->ctr = 0; @@ -2109,10 +2106,11 @@ struct fuse *fuse_new_common(int fd, struct fuse_args *args, return NULL; } -struct fuse *fuse_new(int fd, struct fuse_args *args, - const struct fuse_operations *op, size_t op_size) +struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, + const struct fuse_operations *op, size_t op_size, + void *user_data) { - return fuse_new_common(fd, args, op, op_size, 0); + return fuse_new_common(ch, args, op, op_size, user_data, 0); } void fuse_destroy(struct fuse *f) @@ -2149,6 +2147,19 @@ void fuse_destroy(struct fuse *f) #include "fuse_compat.h" +static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args, + const struct fuse_operations *op, + size_t op_size, int compat) +{ + struct fuse *f = NULL; + struct fuse_chan *ch = fuse_kern_chan_new(fd); + + if (ch) + f = fuse_new_common(ch, args, op, op_size, NULL, compat); + + return f; +} + #ifndef __FreeBSD__ static int fuse_do_open(struct fuse *f, char *path, struct fuse_file_info *fi) @@ -2251,7 +2262,7 @@ static struct fuse *fuse_new_common_compat(int fd, const char *opts, fuse_opt_free_args(&args); return NULL; } - f = fuse_new_common(fd, &args, op, op_size, compat); + f = fuse_new_common_compat25(fd, &args, op, op_size, compat); fuse_opt_free_args(&args); return f; @@ -2319,8 +2330,8 @@ struct fuse *fuse_new_compat25(int fd, struct fuse_args *args, const struct fuse_operations_compat25 *op, size_t op_size) { - return fuse_new_common(fd, args, (struct fuse_operations *) op, - op_size, 25); + return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op, + op_size, 25); } __asm__(".symver fuse_new_compat25,fuse_new@FUSE_2.5"); diff --git a/lib/fuse_i.h b/lib/fuse_i.h index e54509e..268bc41 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -18,14 +18,18 @@ struct fuse_cmd { struct fuse_chan *ch; }; -struct fuse_session *fuse_get_session(struct fuse *f); - -struct fuse *fuse_new_common(int fd, struct fuse_args *args, +struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args, const struct fuse_operations *op, - size_t op_size, int compat); + size_t op_size, void *user_data, int compat); int fuse_sync_compat_args(struct fuse_args *args); +struct fuse_chan *fuse_kern_chan_new(int fd); + struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata); + +void fuse_kern_unmount_compat22(const char *mountpoint); +void fuse_kern_unmount(const char *mountpoint, int fd); +int fuse_kern_mount(const char *mountpoint, struct fuse_args *args); diff --git a/lib/fuse_session.c b/lib/fuse_session.c index 8943204..040645b 100644 --- a/lib/fuse_session.c +++ b/lib/fuse_session.c @@ -59,6 +59,16 @@ void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch) ch->se = se; } +void fuse_session_remove_chan(struct fuse_chan *ch) +{ + struct fuse_session *se = ch->se; + if (se) { + assert(se->ch == ch); + se->ch = NULL; + ch->se = NULL; + } +} + struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, struct fuse_chan *ch) { @@ -162,6 +172,7 @@ int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count) void fuse_chan_destroy(struct fuse_chan *ch) { + fuse_session_remove_chan(ch); if (ch->op.destroy) ch->op.destroy(ch); free(ch); diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 2a8067a..467d870 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -19,7 +19,6 @@ FUSE_2.2 { fuse_read_cmd; fuse_set_getcontext_func; fuse_setup_compat2; - fuse_teardown; }; FUSE_2.4 { @@ -62,7 +61,6 @@ FUSE_2.5 { global: fuse_lowlevel_new_compat; fuse_main_real_compat22; - fuse_mount; fuse_mount_compat22; fuse_new_compat22; fuse_opt_parse; @@ -85,15 +83,22 @@ FUSE_2.5 { FUSE_2.6 { global: fuse_add_direntry; + fuse_daemonize; + fuse_get_session; fuse_lowlevel_new; fuse_lowlevel_new_compat25; fuse_main_real; fuse_main_real_compat25; + fuse_mount; + fuse_mount_compat25; fuse_new; fuse_new_compat25; fuse_opt_insert_arg; + fuse_session_remove_chan; fuse_setup; fuse_setup_compat25; + fuse_teardown; + fuse_teardown_compat22; fuse_unmount; fuse_unmount_compat22; fuse_chan_recv; diff --git a/lib/helper.c b/lib/helper.c index a5935de..bcdd60b 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -10,6 +10,7 @@ #include "fuse_i.h" #include "fuse_opt.h" #include "fuse_lowlevel.h" +#include "fuse_common_compat.h" #include <stdio.h> #include <stdlib.h> @@ -163,7 +164,7 @@ int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint, return -1; } -static int fuse_daemonize(int foreground) +int fuse_daemonize(int foreground) { int res; @@ -184,15 +185,49 @@ static int fuse_daemonize(int foreground) return 0; } +static struct fuse_chan *fuse_mount_common(const char *mountpoint, + struct fuse_args *args) +{ + struct fuse_chan *ch; + int fd = fuse_mount_compat25(mountpoint, args); + if (fd == -1) + return NULL; + + ch = fuse_kern_chan_new(fd); + if (!ch) + fuse_unmount(mountpoint, NULL); + + return ch; +} + +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) +{ + return fuse_mount_common(mountpoint, args); +} + +static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch) +{ + int fd = ch ? fuse_chan_fd(ch) : -1; + fuse_kern_unmount(mountpoint, fd); + fuse_chan_destroy(ch); +} + +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) +{ + fuse_unmount_common(mountpoint, ch); +} + static struct fuse *fuse_setup_common(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, char **mountpoint, int *multithreaded, int *fd, + void *user_data, int compat) { struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + struct fuse_chan *ch; struct fuse *fuse; int foreground; int res; @@ -201,13 +236,13 @@ static struct fuse *fuse_setup_common(int argc, char *argv[], if (res == -1) return NULL; - *fd = fuse_mount(*mountpoint, &args); - if (*fd == -1) { + ch = fuse_mount_common(*mountpoint, &args); + if (!ch) { fuse_opt_free_args(&args); goto err_free; } - fuse = fuse_new_common(*fd, &args, op, op_size, compat); + fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat); fuse_opt_free_args(&args); if (fuse == NULL) goto err_unmount; @@ -220,46 +255,54 @@ static struct fuse *fuse_setup_common(int argc, char *argv[], if (res == -1) goto err_destroy; + if (fd) + *fd = fuse_chan_fd(ch); + return fuse; err_destroy: fuse_destroy(fuse); err_unmount: - fuse_unmount(*mountpoint, *fd); + fuse_unmount_common(*mountpoint, ch); err_free: free(*mountpoint); return NULL; } struct fuse *fuse_setup(int argc, char *argv[], - const struct fuse_operations *op, - size_t op_size, char **mountpoint, - int *multithreaded, int *fd) + const struct fuse_operations *op, size_t op_size, + char **mountpoint, int *multithreaded, void *user_data) { return fuse_setup_common(argc, argv, op, op_size, mountpoint, - multithreaded, fd, 0); + multithreaded, NULL, user_data, 0); } -void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) +static void fuse_teardown_common(struct fuse *fuse, char *mountpoint) { - fuse_remove_signal_handlers(fuse_get_session(fuse)); - fuse_unmount(mountpoint, fd); + struct fuse_session *se = fuse_get_session(fuse); + struct fuse_chan *ch = fuse_session_next_chan(se, NULL); + fuse_remove_signal_handlers(se); + fuse_unmount_common(mountpoint, ch); fuse_destroy(fuse); free(mountpoint); } +void fuse_teardown(struct fuse *fuse, char *mountpoint) +{ + fuse_teardown_common(fuse, mountpoint); +} + static int fuse_main_common(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, - int compat) + void *user_data, int compat) { struct fuse *fuse; char *mountpoint; int multithreaded; int res; - int fd; fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint, - &multithreaded, &fd, compat); + &multithreaded, NULL, user_data, compat); if (fuse == NULL) return 1; @@ -268,7 +311,7 @@ static int fuse_main_common(int argc, char *argv[], else res = fuse_loop(fuse); - fuse_teardown(fuse, fd, mountpoint); + fuse_teardown_common(fuse, mountpoint); if (res == -1) return 1; @@ -276,9 +319,9 @@ static int fuse_main_common(int argc, char *argv[], } int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, - size_t op_size) + size_t op_size, void *user_data) { - return fuse_main_common(argc, argv, op, op_size, 0); + return fuse_main_common(argc, argv, op, op_size, user_data, 0); } #undef fuse_main @@ -298,7 +341,7 @@ struct fuse *fuse_setup_compat22(int argc, char *argv[], int *multithreaded, int *fd) { return fuse_setup_common(argc, argv, (struct fuse_operations *) op, - op_size, mountpoint, multithreaded, fd, 22); + op_size, mountpoint, multithreaded, fd, NULL, 22); } struct fuse *fuse_setup_compat2(int argc, char *argv[], @@ -308,7 +351,7 @@ struct fuse *fuse_setup_compat2(int argc, char *argv[], { return fuse_setup_common(argc, argv, (struct fuse_operations *) op, sizeof(struct fuse_operations_compat2), - mountpoint, multithreaded, fd, 21); + mountpoint, multithreaded, fd, NULL, 21); } int fuse_main_real_compat22(int argc, char *argv[], @@ -316,21 +359,28 @@ int fuse_main_real_compat22(int argc, char *argv[], size_t op_size) { return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size, - 22); + NULL, 22); } void fuse_main_compat1(int argc, char *argv[], const struct fuse_operations_compat1 *op) { fuse_main_common(argc, argv, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat1), 11); + sizeof(struct fuse_operations_compat1), NULL, 11); } int fuse_main_compat2(int argc, char *argv[], const struct fuse_operations_compat2 *op) { return fuse_main_common(argc, argv, (struct fuse_operations *) op, - sizeof(struct fuse_operations_compat2), 21); + sizeof(struct fuse_operations_compat2), NULL, 21); +} + +int fuse_mount_compat1(const char *mountpoint, const char *args[]) +{ + /* just ignore mount args for now */ + (void) args; + return fuse_mount_compat22(mountpoint, NULL); } __asm__(".symver fuse_setup_compat2,__fuse_setup@"); @@ -348,7 +398,7 @@ struct fuse *fuse_setup_compat25(int argc, char *argv[], int *multithreaded, int *fd) { return fuse_setup_common(argc, argv, (struct fuse_operations *) op, - op_size, mountpoint, multithreaded, fd, 25); + op_size, mountpoint, multithreaded, fd, NULL, 25); } int fuse_main_real_compat25(int argc, char *argv[], @@ -356,8 +406,21 @@ int fuse_main_real_compat25(int argc, char *argv[], size_t op_size) { return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size, - 25); + NULL, 25); +} + +void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint) +{ + (void) fd; + fuse_teardown_common(fuse, mountpoint); +} + +int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args) +{ + return fuse_kern_mount(mountpoint, args); } __asm__(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5"); +__asm__(".symver fuse_teardown_compat22,fuse_teardown@FUSE_2.2"); __asm__(".symver fuse_main_real_compat25,fuse_main_real@FUSE_2.5"); +__asm__(".symver fuse_mount_compat25,fuse_mount@FUSE_2.5"); diff --git a/lib/mount.c b/lib/mount.c index 5c568e9..045a4a6 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -6,9 +6,8 @@ See the file COPYING.LIB. */ -#include "fuse.h" +#include "fuse_i.h" #include "fuse_opt.h" -#include "fuse_compat.h" #include <stdio.h> #include <stdlib.h> @@ -167,28 +166,26 @@ static int receive_fd(int fd) return *(int*)CMSG_DATA(cmsg); } -void fuse_unmount_compat22(const char *mountpoint) -{ - fuse_unmount(mountpoint, -1); -} - -void fuse_unmount(const char *mountpoint, int fd) +void fuse_kern_unmount(const char *mountpoint, int fd) { const char *mountprog = FUSERMOUNT_PROG; - struct pollfd pfd; - int res; int pid; if (!mountpoint) return; - 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; + if (fd != -1) { + int res; + 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; + } #ifdef HAVE_FORK pid = fork(); @@ -216,6 +213,11 @@ void fuse_unmount(const char *mountpoint, int fd) waitpid(pid, NULL, 0); } +void fuse_unmount_compat22(const char *mountpoint) +{ + fuse_kern_unmount(mountpoint, -1); +} + int fuse_mount_compat22(const char *mountpoint, const char *opts) { const char *mountprog = FUSERMOUNT_PROG; @@ -277,7 +279,7 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts) return rv; } -int fuse_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; @@ -301,12 +303,5 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args) return res; } -int fuse_mount_compat1(const char *mountpoint, const char *args[]) -{ - /* just ignore mount args for now */ - (void) args; - return fuse_mount_compat22(mountpoint, NULL); -} - __asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2"); __asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index c5661d2..8b3a6d1 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -6,7 +6,7 @@ See the file COPYING.LIB. */ -#include "fuse.h" +#include "fuse_i.h" #include "fuse_opt.h" #include <sys/stat.h> @@ -197,21 +197,21 @@ void fuse_unmount_compat22(const char *mountpoint) system(umount_cmd); } -void fuse_unmount(const char *mountpoint, int fd) +void fuse_kern_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; @@ -305,7 +305,7 @@ out: return fd; } -int fuse_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; |