Commit 45323fb76465a9576220c7427dbac7b1e7ad3caf
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. |
fs/fuse/file.c
... | ... | @@ -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 | } |
fs/fuse/fuse_i.h
... | ... | @@ -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 { |
fs/fuse/inode.c
... | ... | @@ -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, |