diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-02-07 02:52:41 +0000 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2013-02-07 14:59:28 +0100 |
commit | c66e7f4e71a10e0a06d903d11acad8cc6b99c16a (patch) | |
tree | 811911c9279e6d55152d0c2e03fd91970e2219a6 /lib | |
parent | 1bea285a3a586c97597b1f690f14051ff63f3f0b (diff) |
libfuse: allow disabling adaptive readdirplus
This switches the -o no_readdirplus option to a tristate
string: -o readdirplus=(yes|no|auto)
Telling the kernel to always use readdirplus is beneficial to
filesystems (e.g. GlusterFS) where the cost to perform readdir
and readdirplus are identical.
The default remains "auto" (if supported).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse_i.h | 1 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 20 |
2 files changed, 17 insertions, 4 deletions
diff --git a/lib/fuse_i.h b/lib/fuse_i.h index 02e7af1..3c46d34 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -74,6 +74,7 @@ struct fuse_ll { int auto_inval_data; int no_auto_inval_data; int no_readdirplus; + int no_readdirplus_auto; struct fuse_lowlevel_ops op; int got_init; struct cuse_data *cuse_data; diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 2ac9aab..4f9cff8 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1843,6 +1843,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA; if (arg->flags & FUSE_DO_READDIRPLUS) f->conn.capable |= FUSE_CAP_READDIRPLUS; + if (arg->flags & FUSE_READDIRPLUS_AUTO) + f->conn.capable |= FUSE_CAP_READDIRPLUS_AUTO; } else { f->conn.async_read = 0; f->conn.max_readahead = 0; @@ -1875,8 +1877,11 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.want |= FUSE_CAP_BIG_WRITES; if (f->auto_inval_data) f->conn.want |= FUSE_CAP_AUTO_INVAL_DATA; - if (f->op.readdirplus && !f->no_readdirplus) + if (f->op.readdirplus && !f->no_readdirplus) { f->conn.want |= FUSE_CAP_READDIRPLUS; + if (!f->no_readdirplus_auto) + f->conn.want |= FUSE_CAP_READDIRPLUS_AUTO; + } if (bufsize < FUSE_MIN_READ_BUFFER) { fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", @@ -1902,7 +1907,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) f->conn.want &= ~FUSE_CAP_AUTO_INVAL_DATA; if (f->no_readdirplus) f->conn.want &= ~FUSE_CAP_READDIRPLUS; - + if (f->no_readdirplus_auto) + f->conn.want &= ~FUSE_CAP_READDIRPLUS_AUTO; if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ)) outarg.flags |= FUSE_ASYNC_READ; if (f->conn.want & FUSE_CAP_POSIX_LOCKS) @@ -1921,6 +1927,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.flags |= FUSE_AUTO_INVAL_DATA; if (f->conn.want & FUSE_CAP_READDIRPLUS) outarg.flags |= FUSE_DO_READDIRPLUS; + if (f->conn.want & FUSE_CAP_READDIRPLUS_AUTO) + outarg.flags |= FUSE_READDIRPLUS_AUTO; outarg.max_readahead = f->conn.max_readahead; outarg.max_write = f->conn.max_write; if (f->conn.proto_minor >= 13) { @@ -2546,7 +2554,11 @@ static const struct fuse_opt fuse_ll_opts[] = { { "no_splice_read", offsetof(struct fuse_ll, no_splice_read), 1}, { "auto_inval_data", offsetof(struct fuse_ll, auto_inval_data), 1}, { "no_auto_inval_data", offsetof(struct fuse_ll, no_auto_inval_data), 1}, - { "no_readdirplus", offsetof(struct fuse_ll, no_readdirplus), 1}, + { "readdirplus=no", offsetof(struct fuse_ll, no_readdirplus), 1}, + { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus), 0}, + { "readdirplus=yes", offsetof(struct fuse_ll, no_readdirplus_auto), 1}, + { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus), 0}, + { "readdirplus=auto", offsetof(struct fuse_ll, no_readdirplus_auto), 0}, FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("-h", KEY_HELP), FUSE_OPT_KEY("--help", KEY_HELP), @@ -2579,7 +2591,7 @@ static void fuse_ll_help(void) " -o [no_]splice_move move data while splicing to the fuse device\n" " -o [no_]splice_read use splice to read from the fuse device\n" " -o [no_]auto_inval_data use automatic kernel cache invalidation logic\n" -" -o [no_]readdirplus use readdirplus if possible.\n" +" -o readdirplus=S control readdirplus use (yes|no|auto)\n" ); } |