aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <mszeredi@suse.cz>2014-07-15 17:11:08 +0200
committerGravatar Miklos Szeredi <mszeredi@suse.cz>2014-07-15 17:36:43 +0200
commit57a93b3dacbf9259178dacff5d2fbb25427f3b86 (patch)
tree09b3436bcec7b391ccc810c3d905b9b3a0158983
parent52f46cfa682e284835807bcd60086a71b4365e91 (diff)
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).
-rw-r--r--ChangeLog4
-rw-r--r--include/fuse_common.h10
-rw-r--r--include/fuse_kernel.h9
-rwxr-xr-xlib/fuse_lowlevel.c13
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 <miklos@szeredi.hu>
* 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"
);
}