Commit 45323fb76465a9576220c7427dbac7b1e7ad3caf

Authored by Miklos Szeredi
Committed by Linus Torvalds
1 parent 04730fef1f

[PATCH] fuse: more flexible caching

Make data caching behavior selectable on a per-open basis instead of
per-mount.  Compatibility for the old mount options 'kernel_cache' and
'direct_io' is retained in the userspace library (version 2.4.0-pre1 or
later).

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 5 changed files with 18 additions and 59 deletions Side-by-side Diff

Documentation/filesystems/fuse.txt
... ... @@ -80,32 +80,6 @@
80 80 allowed to root, but this restriction can be removed with a
81 81 (userspace) configuration option.
82 82  
83   -'kernel_cache'
84   -
85   - This option disables flushing the cache of the file contents on
86   - every open(). This should only be enabled on filesystems, where the
87   - file data is never changed externally (not through the mounted FUSE
88   - filesystem). Thus it is not suitable for network filesystems and
89   - other "intermediate" filesystems.
90   -
91   - NOTE: if this option is not specified (and neither 'direct_io') data
92   - is still cached after the open(), so a read() system call will not
93   - always initiate a read operation.
94   -
95   -'direct_io'
96   -
97   - This option disables the use of page cache (file content cache) in
98   - the kernel for this filesystem. This has several affects:
99   -
100   - - Each read() or write() system call will initiate one or more
101   - read or write operations, data will not be cached in the
102   - kernel.
103   -
104   - - The return value of the read() and write() system calls will
105   - correspond to the return values of the read and write
106   - operations. This is useful for example if the file size is not
107   - known in advance (before reading it).
108   -
109 83 'max_read=N'
110 84  
111 85 With this option the maximum size of read operations can be set.
... ... @@ -12,6 +12,8 @@
12 12 #include <linux/slab.h>
13 13 #include <linux/kernel.h>
14 14  
  15 +static struct file_operations fuse_direct_io_file_operations;
  16 +
15 17 int fuse_open_common(struct inode *inode, struct file *file, int isdir)
16 18 {
17 19 struct fuse_conn *fc = get_fuse_conn(inode);
18 20  
... ... @@ -70,12 +72,14 @@
70 72 else
71 73 request_send(fc, req);
72 74 err = req->out.h.error;
73   - if (!err && !(fc->flags & FUSE_KERNEL_CACHE))
74   - invalidate_inode_pages(inode->i_mapping);
75 75 if (err) {
76 76 fuse_request_free(ff->release_req);
77 77 kfree(ff);
78 78 } else {
  79 + if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
  80 + file->f_op = &fuse_direct_io_file_operations;
  81 + if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
  82 + invalidate_inode_pages(inode->i_mapping);
79 83 ff->fh = outarg.fh;
80 84 file->private_data = ff;
81 85 }
... ... @@ -544,13 +548,7 @@
544 548  
545 549 void fuse_init_file_inode(struct inode *inode)
546 550 {
547   - struct fuse_conn *fc = get_fuse_conn(inode);
548   -
549   - if (fc->flags & FUSE_DIRECT_IO)
550   - inode->i_fop = &fuse_direct_io_file_operations;
551   - else {
552   - inode->i_fop = &fuse_file_operations;
553   - inode->i_data.a_ops = &fuse_file_aops;
554   - }
  551 + inode->i_fop = &fuse_file_operations;
  552 + inode->i_data.a_ops = &fuse_file_aops;
555 553 }
... ... @@ -30,12 +30,6 @@
30 30 doing the mount will be allowed to access the filesystem */
31 31 #define FUSE_ALLOW_OTHER (1 << 1)
32 32  
33   -/** If the FUSE_KERNEL_CACHE flag is given, then cached data will not
34   - be flushed on open */
35   -#define FUSE_KERNEL_CACHE (1 << 2)
36   -
37   -/** Bypass the page cache for read and write operations */
38   -#define FUSE_DIRECT_IO (1 << 3)
39 33  
40 34 /** FUSE inode */
41 35 struct fuse_inode {
... ... @@ -257,8 +257,6 @@
257 257 OPT_GROUP_ID,
258 258 OPT_DEFAULT_PERMISSIONS,
259 259 OPT_ALLOW_OTHER,
260   - OPT_KERNEL_CACHE,
261   - OPT_DIRECT_IO,
262 260 OPT_MAX_READ,
263 261 OPT_ERR
264 262 };
... ... @@ -270,8 +268,6 @@
270 268 {OPT_GROUP_ID, "group_id=%u"},
271 269 {OPT_DEFAULT_PERMISSIONS, "default_permissions"},
272 270 {OPT_ALLOW_OTHER, "allow_other"},
273   - {OPT_KERNEL_CACHE, "kernel_cache"},
274   - {OPT_DIRECT_IO, "direct_io"},
275 271 {OPT_MAX_READ, "max_read=%u"},
276 272 {OPT_ERR, NULL}
277 273 };
... ... @@ -327,14 +323,6 @@
327 323 d->flags |= FUSE_ALLOW_OTHER;
328 324 break;
329 325  
330   - case OPT_KERNEL_CACHE:
331   - d->flags |= FUSE_KERNEL_CACHE;
332   - break;
333   -
334   - case OPT_DIRECT_IO:
335   - d->flags |= FUSE_DIRECT_IO;
336   - break;
337   -
338 326 case OPT_MAX_READ:
339 327 if (match_int(&args[0], &value))
340 328 return 0;
... ... @@ -363,10 +351,6 @@
363 351 seq_puts(m, ",default_permissions");
364 352 if (fc->flags & FUSE_ALLOW_OTHER)
365 353 seq_puts(m, ",allow_other");
366   - if (fc->flags & FUSE_KERNEL_CACHE)
367   - seq_puts(m, ",kernel_cache");
368   - if (fc->flags & FUSE_DIRECT_IO)
369   - seq_puts(m, ",direct_io");
370 354 if (fc->max_read != ~0)
371 355 seq_printf(m, ",max_read=%u", fc->max_read);
372 356 return 0;
include/linux/fuse.h
... ... @@ -14,7 +14,7 @@
14 14 #define FUSE_KERNEL_VERSION 7
15 15  
16 16 /** Minor version number of this interface */
17   -#define FUSE_KERNEL_MINOR_VERSION 1
  17 +#define FUSE_KERNEL_MINOR_VERSION 2
18 18  
19 19 /** The node ID of the root inode */
20 20 #define FUSE_ROOT_ID 1
... ... @@ -62,6 +62,15 @@
62 62 #define FATTR_ATIME (1 << 4)
63 63 #define FATTR_MTIME (1 << 5)
64 64 #define FATTR_CTIME (1 << 6)
  65 +
  66 +/**
  67 + * Flags returned by the OPEN request
  68 + *
  69 + * FOPEN_DIRECT_IO: bypass page cache for this open file
  70 + * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
  71 + */
  72 +#define FOPEN_DIRECT_IO (1 << 0)
  73 +#define FOPEN_KEEP_CACHE (1 << 1)
65 74  
66 75 enum fuse_opcode {
67 76 FUSE_LOOKUP = 1,