From 50f5255a44870863e4a9b6bcb7a62b5319fefd62 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath Date: Sun, 2 Oct 2016 10:26:40 -0700 Subject: [PATCH] Introduce separate mount/umount functions for low-level API. --- ChangeLog.rst | 5 +++++ example/fuse_lo-plus.c | 6 +++--- example/hello_ll.c | 4 ++-- include/fuse.h | 26 ++++++++++++++++++++++++++ include/fuse_common.h | 26 -------------------------- include/fuse_lowlevel.h | 27 +++++++++++++++++++++++++++ lib/fuse.c | 10 ++++++++++ lib/fuse_lowlevel.c | 36 ++++++++++++++++++++++++++++++++++++ lib/fuse_versionscript | 2 ++ lib/helper.c | 35 ----------------------------------- 10 files changed, 111 insertions(+), 66 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 28888bf..87ceae9 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,11 @@ Unreleased Changes ================== +* There are now new `fuse_session_unmount` and `fuse_session_mount` + functions that should be used in the low-level API. The + `fuse_mount` and `fuse_unmount` functions should be used with the + high-level API only. + * The ``fuse_lowlevel_notify_*`` functions now all take a `struct fuse_session` parameter instead of a `struct fuse_chan`. diff --git a/example/fuse_lo-plus.c b/example/fuse_lo-plus.c index adbbbee..30ad21e 100644 --- a/example/fuse_lo-plus.c +++ b/example/fuse_lo-plus.c @@ -95,7 +95,7 @@ static struct lo_inode *lo_inode(fuse_req_t req, fuse_ino_t ino) if (ino == FUSE_ROOT_ID) return &lo_data(req)->root; else - return (struct lo_inode *) (uintptr_t) ino; + return (struct lo_inode *) (uintptr_t) ino; } static int lo_fd(fuse_req_t req, fuse_ino_t ino) @@ -469,7 +469,7 @@ int main(int argc, char *argv[]) err(1, "open(\"/\", O_PATH)"); if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && - (ch = fuse_mount(mountpoint, &args)) != NULL) { + (ch = fuse_session_mount(mountpoint, &args)) != NULL) { struct fuse_session *se; se = fuse_lowlevel_new(&args, &lo_oper, sizeof(lo_oper), &lo); if (se != NULL) { @@ -481,7 +481,7 @@ int main(int argc, char *argv[]) } fuse_session_destroy(se); } - fuse_unmount(mountpoint, ch); + fuse_session_unmount(mountpoint, ch); free(mountpoint); } fuse_opt_free_args(&args); diff --git a/example/hello_ll.c b/example/hello_ll.c index 1bf7155..3c87bc6 100755 --- a/example/hello_ll.c +++ b/example/hello_ll.c @@ -191,7 +191,7 @@ int main(int argc, char *argv[]) int err = -1; if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 && - (ch = fuse_mount(mountpoint, &args)) != NULL) { + (ch = fuse_session_mount(mountpoint, &args)) != NULL) { struct fuse_session *se; se = fuse_lowlevel_new(&args, &hello_ll_oper, @@ -208,7 +208,7 @@ int main(int argc, char *argv[]) } fuse_session_destroy(se); } - fuse_unmount(mountpoint, ch); + fuse_session_unmount(mountpoint, ch); } fuse_opt_free_args(&args); diff --git a/include/fuse.h b/include/fuse.h index 5721caa..948442c 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -658,6 +658,32 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *user_data); +/** + * Create a FUSE mountpoint + * + * Returns a control file descriptor suitable for passing to + * fuse_new(). Unknown parameters in `args` are passed through + * unchanged. Known parameters (with the exception of --help and + * --version) are removed from `args`. + * + * If the --help or --version parameters are specified, the function + * prints the requested information to stdout and returns a valid + * pointer. However, it does not actually perform the mount. + * + * @param mountpoint the mount point path + * @param args argument vector + * @return the communication channel on success, NULL on failure + */ +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args); + +/** + * Umount a FUSE mountpoint + * + * @param mountpoint the mount point path + * @param ch the communication channel + */ +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch); + /** * Destroy the FUSE handle. * diff --git a/include/fuse_common.h b/include/fuse_common.h index df92e8e..bab2a5b 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -209,32 +209,6 @@ struct fuse_session; struct fuse_chan; struct fuse_pollhandle; -/** - * Create a FUSE mountpoint - * - * Returns a control file descriptor suitable for passing to - * fuse_new(). Unknown parameters in `args` are passed through - * unchanged. Known parameters (with the exception of --help and - * --version) are removed from `args`. - * - * If the --help or --version parameters are specified, the function - * prints the requested information to stdout and returns a valid - * pointer. However, it does not actually perform the mount. - * - * @param mountpoint the mount point path - * @param args argument vector - * @return the communication channel on success, NULL on failure - */ -struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args); - -/** - * Umount a FUSE mountpoint - * - * @param mountpoint the mount point path - * @param ch the communication channel - */ -void fuse_unmount(const char *mountpoint, struct fuse_chan *ch); - /** * Utility functions for simple file systems to parse common options. * diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index ce39906..e652058 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -1705,6 +1705,33 @@ int fuse_session_loop(struct fuse_session *se); */ int fuse_session_loop_mt(struct fuse_session *se); +/** + * Create a FUSE mountpoint + * + * Returns a control file descriptor suitable for passing to + * fuse_new(). Unknown parameters in `args` are passed through + * unchanged. Known parameters (with the exception of --help and + * --version) are removed from `args`. + * + * If the --help or --version parameters are specified, the function + * prints the requested information to stdout and returns a valid + * pointer. However, it does not actually perform the mount. + * + * @param mountpoint the mount point path + * @param args argument vector + * @return the communication channel on success, NULL on failure + */ +struct fuse_chan *fuse_session_mount(const char *mountpoint, + struct fuse_args *args); + +/** + * Umount a FUSE mountpoint + * + * @param mountpoint the mount point path + * @param ch the communication channel + */ +void fuse_session_unmount(const char *mountpoint, struct fuse_chan *ch); + /* ----------------------------------------------------------- * * Channel interface * * ----------------------------------------------------------- */ diff --git a/lib/fuse.c b/lib/fuse.c index f934747..e17b6b3 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -4836,3 +4836,13 @@ void fuse_destroy(struct fuse *f) free(f); fuse_delete_context_key(); } + +struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) +{ + return fuse_session_mount(mountpoint, args); +} + +void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) +{ + fuse_session_unmount(mountpoint, ch); +} diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 8b08f3a..ad10175 100755 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2938,6 +2938,42 @@ out: return NULL; } +struct fuse_chan *fuse_session_mount(const char *mountpoint, + struct fuse_args *args) +{ + struct fuse_chan *ch; + int fd; + + /* + * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos + * would ensue. + */ + do { + fd = open("/dev/null", O_RDWR); + if (fd > 2) + close(fd); + } while (fd >= 0 && fd <= 2); + + fd = fuse_kern_mount(mountpoint, args); + if (fd == -1) + return NULL; + + ch = fuse_chan_new(fd); + if (!ch) + fuse_kern_unmount(mountpoint, fd); + + return ch; +} + +void fuse_session_unmount(const char *mountpoint, struct fuse_chan *ch) +{ + if (mountpoint) { + int fd = ch ? fuse_chan_clearfd(ch) : -1; + fuse_kern_unmount(mountpoint, fd); + fuse_chan_put(ch); + } +} + #ifdef linux int fuse_req_getgroups(fuse_req_t req, int size, gid_t list[]) { diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 716330f..9c29669 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -42,6 +42,7 @@ FUSE_3.0 { fuse_lowlevel_new; fuse_main_real; fuse_mount; + fuse_session_mount; fuse_new; fuse_opt_insert_arg; fuse_reply_lock; @@ -49,6 +50,7 @@ FUSE_3.0 { fuse_req_interrupted; fuse_session_remove_chan; fuse_unmount; + fuse_session_unmount; fuse_fs_access; fuse_fs_bmap; fuse_fs_chmod; diff --git a/lib/helper.c b/lib/helper.c index 6a55269..cd1a54b 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -227,41 +227,6 @@ int fuse_daemonize(int foreground) return 0; } -struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args) -{ - struct fuse_chan *ch; - int fd; - - /* - * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos - * would ensue. - */ - do { - fd = open("/dev/null", O_RDWR); - if (fd > 2) - close(fd); - } while (fd >= 0 && fd <= 2); - - fd = fuse_kern_mount(mountpoint, args); - if (fd == -1) - return NULL; - - ch = fuse_chan_new(fd); - if (!ch) - fuse_kern_unmount(mountpoint, fd); - - return ch; -} - -void fuse_unmount(const char *mountpoint, struct fuse_chan *ch) -{ - if (mountpoint) { - int fd = ch ? fuse_chan_clearfd(ch) : -1; - fuse_kern_unmount(mountpoint, fd); - fuse_chan_put(ch); - } -} - static struct fuse *fuse_setup(int argc, char *argv[], const struct fuse_operations *op, size_t op_size, char **mountpoint, int *multithreaded, void *user_data) -- 2.30.2