aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse_lowlevel.c
diff options
context:
space:
mode:
authorNikolaus Rath <Nikolaus@rath.org>2016-10-02 11:30:43 -0700
committerNikolaus Rath <Nikolaus@rath.org>2016-10-02 13:56:40 -0700
commit5698ee09cf7a8495da70659ffae1eaec9f57db27 (patch)
tree798a58a4f49d7f82e3f948463daad4405173483e /lib/fuse_lowlevel.c
parentf164e9b8ca319dd1279384ff495b5fa91e778d9e (diff)
downloadlibfuse-5698ee09cf7a8495da70659ffae1eaec9f57db27.tar.gz
Turn struct fuse_chan into an implementation detail
The only struct fuse_chan that's accessible to the user application is the "master" channel that is returned by fuse_mount and stored in struct fuse_session. When using the multi-threaded main loop with the "clone_fd" option, each worker thread gets its own struct fuse_chan. However, none of these are available to the user application, nor do they hold references to struct fuse_session (the pointer is always null). Therefore, any presence of struct fuse_chan can be removed without loss of functionality by relying on struct fuse_session instead. This reduces the number of API functions and removes a potential source of confusion (since the new API no longer looks as if it might be possible to add multiple channels to one session, or to share one channel between multiple sessions). Fixes issue #17.
Diffstat (limited to 'lib/fuse_lowlevel.c')
-rwxr-xr-xlib/fuse_lowlevel.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 92265cc..43539da 100755
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -2437,10 +2437,9 @@ static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst,
}
void fuse_session_process_buf(struct fuse_session *se,
- const struct fuse_buf *buf,
- struct fuse_chan *ch)
+ const struct fuse_buf *buf)
{
- fuse_session_process_buf_int(se, buf, ch);
+ fuse_session_process_buf_int(se, buf, se->ch);
}
void fuse_session_process_buf_int(struct fuse_session *se,
@@ -2666,15 +2665,17 @@ static void fuse_ll_help(void)
static int fuse_ll_opt_proc(void *data, const char *arg, int key,
struct fuse_args *outargs)
{
- (void) data; (void) outargs;
+ (void) data; (void) outargs; (void) arg;
switch (key) {
case KEY_HELP:
fuse_ll_help();
+ fuse_mount_help();
break;
case KEY_VERSION:
fuse_ll_version();
+ fuse_mount_version();
break;
default:
@@ -2706,6 +2707,7 @@ void fuse_session_destroy(struct fuse_session *se)
{
fuse_ll_destroy(se->f);
fuse_chan_put(se->ch);
+ destroy_mount_opts(se->mo);
free(se);
}
@@ -2716,10 +2718,9 @@ static void fuse_ll_pipe_destructor(void *data)
fuse_ll_pipe_free(llp);
}
-int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
- struct fuse_chan *ch)
+int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
{
- return fuse_session_receive_buf_int(se, buf, ch);
+ return fuse_session_receive_buf_int(se, buf, se->ch);
}
int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
@@ -2878,6 +2879,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
int err;
struct fuse_ll *f;
struct fuse_session *se;
+ struct mount_opts *mo;
if (sizeof(struct fuse_lowlevel_ops) < op_size) {
fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
@@ -2890,6 +2892,16 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
goto out;
}
+ /* Parse options */
+ mo = parse_mount_opts(args);
+ if (mo == NULL)
+ goto out_free0;
+ if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
+ goto out_free;
+
+ if (f->debug)
+ fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
+
f->conn.async_read = 1;
f->conn.max_write = UINT_MAX;
f->conn.max_readahead = UINT_MAX;
@@ -2910,12 +2922,6 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
goto out_free;
}
- if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
- goto out_key_destroy;
-
- if (f->debug)
- fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
-
memcpy(&f->op, op, op_size);
f->owner = getuid();
f->userdata = userdata;
@@ -2927,19 +2933,21 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
}
memset(se, 0, sizeof(*se));
se->f = f;
+ se->mo = mo;
return se;
out_key_destroy:
pthread_key_delete(f->pipe_key);
out_free:
+ free(mo);
+out_free0:
pthread_mutex_destroy(&f->lock);
free(f);
out:
return NULL;
}
-struct fuse_chan *fuse_session_mount(const char *mountpoint,
- struct fuse_args *args)
+int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
{
struct fuse_chan *ch;
int fd;
@@ -2954,23 +2962,39 @@ struct fuse_chan *fuse_session_mount(const char *mountpoint,
close(fd);
} while (fd >= 0 && fd <= 2);
- fd = fuse_kern_mount(mountpoint, args);
+ /* Open channel */
+ fd = fuse_kern_mount(mountpoint, se->mo);
if (fd == -1)
- return NULL;
+ return -1;
ch = fuse_chan_new(fd);
if (!ch)
- fuse_kern_unmount(mountpoint, fd);
+ goto error_out;
+
+ /* Add channel to session */
+ fuse_session_add_chan(se, ch);
- return ch;
+ /* Save mountpoint */
+ se->mountpoint = strdup(mountpoint);
+ if (se->mountpoint == NULL)
+ goto error_out;
+
+ return 0;
+
+error_out:
+ fuse_kern_unmount(mountpoint, fd);
+ return -1;
}
-void fuse_session_unmount(const char *mountpoint, struct fuse_chan *ch)
+void fuse_session_unmount(struct fuse_session *se)
{
- if (mountpoint) {
- int fd = ch ? fuse_chan_clearfd(ch) : -1;
- fuse_kern_unmount(mountpoint, fd);
- fuse_chan_put(ch);
+ fuse_session_remove_chan(se->ch);
+ if (se->mountpoint) {
+ int fd = se->ch ? fuse_chan_clearfd(se->ch) : -1;
+ fuse_kern_unmount(se->mountpoint, fd);
+ fuse_chan_put(se->ch);
+ free(se->mountpoint);
+ se->mountpoint = NULL;
}
}