libfuse: Add '[no_]auto_inval_data' mount option
authorFeng Shuo <steve.shuo.feng@gmail.com>
Fri, 4 Jan 2013 08:23:30 +0000 (16:23 +0800)
committerMiklos Szeredi <mszeredi@suse.cz>
Wed, 6 Feb 2013 16:27:28 +0000 (17:27 +0100)
Several caching logic changes have been made on the kernel side
to better support network-based fuse filesystems. These include
kernel side mtime checking and read path cache revalidation. The
new caching logic is enabled through the FUSE_AUTO_INVAL_DATA
init flag. Export this to the user via the '[no_]auto_inval_data'
mount option.

Signed-off-by: Feng Shuo <steve.shuo.feng@gmail.com>
include/fuse_common.h
include/fuse_kernel.h
lib/fuse_i.h
lib/fuse_lowlevel.c

index 0ae33a9c47b22fadf0847b822b1805ddad7936c0..58458ab610882e9861f6eeeff69ab1d9a10a2140 100644 (file)
@@ -100,17 +100,18 @@ struct fuse_file_info {
  * FUSE_CAP_SPLICE_READ: ability to use splice() to read from the fuse device
  * FUSE_CAP_IOCTL_DIR: ioctl support on directories
  */
-#define FUSE_CAP_ASYNC_READ    (1 << 0)
-#define FUSE_CAP_POSIX_LOCKS   (1 << 1)
-#define FUSE_CAP_ATOMIC_O_TRUNC        (1 << 3)
-#define FUSE_CAP_EXPORT_SUPPORT        (1 << 4)
-#define FUSE_CAP_BIG_WRITES    (1 << 5)
-#define FUSE_CAP_DONT_MASK     (1 << 6)
-#define FUSE_CAP_SPLICE_WRITE  (1 << 7)
-#define FUSE_CAP_SPLICE_MOVE   (1 << 8)
-#define FUSE_CAP_SPLICE_READ   (1 << 9)
-#define FUSE_CAP_FLOCK_LOCKS   (1 << 10)
-#define FUSE_CAP_IOCTL_DIR     (1 << 11)
+#define FUSE_CAP_ASYNC_READ            (1 << 0)
+#define FUSE_CAP_POSIX_LOCKS           (1 << 1)
+#define FUSE_CAP_ATOMIC_O_TRUNC                (1 << 3)
+#define FUSE_CAP_EXPORT_SUPPORT                (1 << 4)
+#define FUSE_CAP_BIG_WRITES            (1 << 5)
+#define FUSE_CAP_DONT_MASK             (1 << 6)
+#define FUSE_CAP_SPLICE_WRITE          (1 << 7)
+#define FUSE_CAP_SPLICE_MOVE           (1 << 8)
+#define FUSE_CAP_SPLICE_READ           (1 << 9)
+#define FUSE_CAP_FLOCK_LOCKS           (1 << 10)
+#define FUSE_CAP_IOCTL_DIR             (1 << 11)
+#define FUSE_CAP_AUTO_INVAL_DATA       (1 << 12)
 
 /**
  * Ioctl flags
index 0f24494960e1019fe9d400de1957b431ec512931..501450cce54033b7414d86a7d23aabf5f3be9c66 100644 (file)
@@ -83,6 +83,9 @@
  *
  * 7.19
  *  - add FUSE_FALLOCATE
+ *
+ * 7.20
+ *  - add FUSE_AUTO_INVAL_DATA
  */
 
 #ifndef _LINUX_FUSE_H
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 19
+#define FUSE_KERNEL_MINOR_VERSION 20
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -206,6 +209,7 @@ struct fuse_file_lock {
  * FUSE_SPLICE_READ: kernel supports splice read on the device
  * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
  * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
+ * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
  */
 #define FUSE_ASYNC_READ                (1 << 0)
 #define FUSE_POSIX_LOCKS       (1 << 1)
@@ -219,6 +223,7 @@ struct fuse_file_lock {
 #define FUSE_SPLICE_READ       (1 << 9)
 #define FUSE_FLOCK_LOCKS       (1 << 10)
 #define FUSE_HAS_IOCTL_DIR     (1 << 11)
+#define FUSE_AUTO_INVAL_DATA   (1 << 12)
 
 /**
  * CUSE INIT request/reply flags
index 1f1787e873dbf4cf391777d585202f1fc15efa6d..225ff7de606f1e6ff557fd8ae9a019614f042e95 100644 (file)
@@ -71,6 +71,8 @@ struct fuse_ll {
        int no_splice_write;
        int no_splice_move;
        int no_splice_read;
+       int auto_inval_data;
+       int no_auto_inval_data;
        struct fuse_lowlevel_ops op;
        int got_init;
        struct cuse_data *cuse_data;
index e28cce3d352fbb9eeb23feca6f694bed97c8e852..568cf472f034f33810ae7a6a3bbc3a42afcd3457 100644 (file)
@@ -1804,6 +1804,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                        f->conn.capable |= FUSE_CAP_DONT_MASK;
                if (arg->flags & FUSE_FLOCK_LOCKS)
                        f->conn.capable |= FUSE_CAP_FLOCK_LOCKS;
+               if (arg->flags & FUSE_AUTO_INVAL_DATA)
+                       f->conn.capable |= FUSE_CAP_AUTO_INVAL_DATA;
        } else {
                f->conn.async_read = 0;
                f->conn.max_readahead = 0;
@@ -1834,6 +1836,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                f->conn.want |= FUSE_CAP_FLOCK_LOCKS;
        if (f->big_writes)
                f->conn.want |= FUSE_CAP_BIG_WRITES;
+       if (f->auto_inval_data)
+               f->conn.want |= FUSE_CAP_AUTO_INVAL_DATA;
 
        if (bufsize < FUSE_MIN_READ_BUFFER) {
                fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
@@ -1855,6 +1859,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                f->conn.want &= ~FUSE_CAP_SPLICE_WRITE;
        if (f->no_splice_move)
                f->conn.want &= ~FUSE_CAP_SPLICE_MOVE;
+       if (f->no_auto_inval_data)
+               f->conn.want &= ~FUSE_CAP_AUTO_INVAL_DATA;
 
        if (f->conn.async_read || (f->conn.want & FUSE_CAP_ASYNC_READ))
                outarg.flags |= FUSE_ASYNC_READ;
@@ -1870,6 +1876,8 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
                outarg.flags |= FUSE_DONT_MASK;
        if (f->conn.want & FUSE_CAP_FLOCK_LOCKS)
                outarg.flags |= FUSE_FLOCK_LOCKS;
+       if (f->conn.want & FUSE_CAP_AUTO_INVAL_DATA)
+               outarg.flags |= FUSE_AUTO_INVAL_DATA;
        outarg.max_readahead = f->conn.max_readahead;
        outarg.max_write = f->conn.max_write;
        if (f->conn.proto_minor >= 13) {
@@ -2491,6 +2499,8 @@ static const struct fuse_opt fuse_ll_opts[] = {
        { "no_splice_move", offsetof(struct fuse_ll, no_splice_move), 1},
        { "splice_read", offsetof(struct fuse_ll, splice_read), 1},
        { "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},
        FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
        FUSE_OPT_KEY("-h", KEY_HELP),
        FUSE_OPT_KEY("--help", KEY_HELP),
@@ -2522,6 +2532,7 @@ static void fuse_ll_help(void)
 "    -o [no_]splice_write   use splice to write to the fuse device\n"
 "    -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"
 );
 }