From 57a93b3dacbf9259178dacff5d2fbb25427f3b86 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 15 Jul 2014 17:11:08 +0200 Subject: [PATCH] libfuse: add "time_gran" option This allows the filesystem to specify the time granularity it supports when the kernel is responsible for updating times ("writeback_cache" option). --- ChangeLog | 4 ++++ include/fuse_common.h | 10 +++++++++- include/fuse_kernel.h | 9 ++++++++- lib/fuse_lowlevel.c | 13 ++++++++++++- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd3acd5..167ca7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ result in EINVAL when mounting the filesystem. This also needs a fix in the kernel. + * libfuse: add "time_gran" option. This allows the filesystem to + specify the time granularity it supports when the kernel is + responsible for updating times ("writeback_cache" option). + 2014-03-26 Miklos Szeredi * Initilaize stat buffer passed to ->getattr() and ->fgetattr() to diff --git a/include/fuse_common.h b/include/fuse_common.h index 22d9591..aec4349 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -190,9 +190,17 @@ struct fuse_conn_info { unsigned congestion_threshold; /** + * Time granularity if kernel is responsible for setting times (in nsec) + * + * Should be power of 10. A zero (default) value is equivalent to + * 1000000000 (1sec). + */ + unsigned time_gran; + + /** * For future use. */ - unsigned reserved[23]; + unsigned reserved[22]; }; struct fuse_session; diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h index 7974721..d1b4e2c 100644 --- a/include/fuse_kernel.h +++ b/include/fuse_kernel.h @@ -96,6 +96,8 @@ * * 7.23 * - add FUSE_WRITEBACK_CACHE + * - add time_gran to fuse_init_out + * - add reserved space to fuse_init_out */ #ifndef _LINUX_FUSE_H @@ -131,7 +133,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 22 +#define FUSE_KERNEL_MINOR_VERSION 23 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -559,6 +561,9 @@ struct fuse_init_in { uint32_t flags; }; +#define FUSE_COMPAT_INIT_OUT_SIZE 8 +#define FUSE_COMPAT_22_INIT_OUT_SIZE 24 + struct fuse_init_out { uint32_t major; uint32_t minor; @@ -567,6 +572,8 @@ struct fuse_init_out { uint16_t max_background; uint16_t congestion_threshold; uint32_t max_write; + uint32_t time_gran; + uint32_t unused[9]; }; #define CUSE_INIT_INFO_MAX 4096 diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 4284535..dc27cb5 100755 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -1844,6 +1844,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) struct fuse_init_out outarg; struct fuse_ll *f = req->f; size_t bufsize = f->bufsize; + size_t outargsize = sizeof(outarg); (void) nodeid; if (f->debug) { @@ -2017,6 +2018,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.max_background = f->conn.max_background; outarg.congestion_threshold = f->conn.congestion_threshold; } + if (f->conn.proto_minor >= 23) + outarg.time_gran = f->conn.time_gran; if (f->debug) { fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor); @@ -2028,9 +2031,15 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.max_background); fprintf(stderr, " congestion_threshold=%i\n", outarg.congestion_threshold); + fprintf(stderr, " time_gran=%u\n", + outarg.time_gran); } + if (arg->minor < 5) + outargsize = FUSE_COMPAT_INIT_OUT_SIZE; + else if (arg->minor < 23) + outargsize = FUSE_COMPAT_22_INIT_OUT_SIZE; - send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg)); + send_reply_ok(req, &outarg, outargsize); } static void do_destroy(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) @@ -2625,6 +2634,7 @@ static const struct fuse_opt fuse_ll_opts[] = { { "no_async_dio", offsetof(struct fuse_ll, no_async_dio), 1}, { "writeback_cache", offsetof(struct fuse_ll, writeback_cache), 1}, { "no_writeback_cache", offsetof(struct fuse_ll, no_writeback_cache), 1}, + { "time_gran=%u", offsetof(struct fuse_ll, conn.time_gran), 0 }, FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("-h", KEY_HELP), FUSE_OPT_KEY("--help", KEY_HELP), @@ -2660,6 +2670,7 @@ static void fuse_ll_help(void) " -o readdirplus=S control readdirplus use (yes|no|auto)\n" " -o [no_]async_dio asynchronous direct I/O\n" " -o [no_]writeback_cache asynchronous, buffered writes\n" +" -o time_gran=N time granularity in nsec\n" ); } -- 2.11.4.GIT