aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 16:10:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:47 -0400
commit45323fb76465a9576220c7427dbac7b1e7ad3caf (patch)
tree5d3e5f9a01cdaf6aaabe38520d5bd5b2d744acd5
parent04730fef1f9c7277e5c730b193e681ac095b0507 (diff)
[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>
-rw-r--r--Documentation/filesystems/fuse.txt26
-rw-r--r--fs/fuse/file.c18
-rw-r--r--fs/fuse/fuse_i.h6
-rw-r--r--fs/fuse/inode.c16
-rw-r--r--include/linux/fuse.h11
5 files changed, 18 insertions, 59 deletions
diff --git a/Documentation/filesystems/fuse.txt b/Documentation/filesystems/fuse.txt
index 83f96cf56960..6b5741e651a2 100644
--- a/Documentation/filesystems/fuse.txt
+++ b/Documentation/filesystems/fuse.txt
@@ -80,32 +80,6 @@ Mount options
80 allowed to root, but this restriction can be removed with a 80 allowed to root, but this restriction can be removed with a
81 (userspace) configuration option. 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'max_read=N' 83'max_read=N'
110 84
111 With this option the maximum size of read operations can be set. 85 With this option the maximum size of read operations can be set.
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 224453557cf6..a8dc88527fbe 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -12,6 +12,8 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14 14
15static struct file_operations fuse_direct_io_file_operations;
16
15int fuse_open_common(struct inode *inode, struct file *file, int isdir) 17int fuse_open_common(struct inode *inode, struct file *file, int isdir)
16{ 18{
17 struct fuse_conn *fc = get_fuse_conn(inode); 19 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -70,12 +72,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
70 else 72 else
71 request_send(fc, req); 73 request_send(fc, req);
72 err = req->out.h.error; 74 err = req->out.h.error;
73 if (!err && !(fc->flags & FUSE_KERNEL_CACHE))
74 invalidate_inode_pages(inode->i_mapping);
75 if (err) { 75 if (err) {
76 fuse_request_free(ff->release_req); 76 fuse_request_free(ff->release_req);
77 kfree(ff); 77 kfree(ff);
78 } else { 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 ff->fh = outarg.fh; 83 ff->fh = outarg.fh;
80 file->private_data = ff; 84 file->private_data = ff;
81 } 85 }
@@ -544,12 +548,6 @@ static struct address_space_operations fuse_file_aops = {
544 548
545void fuse_init_file_inode(struct inode *inode) 549void fuse_init_file_inode(struct inode *inode)
546{ 550{
547 struct fuse_conn *fc = get_fuse_conn(inode); 551 inode->i_fop = &fuse_file_operations;
548 552 inode->i_data.a_ops = &fuse_file_aops;
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 }
555} 553}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 8593d5bae7a6..84849601363e 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -30,12 +30,6 @@
30 doing the mount will be allowed to access the filesystem */ 30 doing the mount will be allowed to access the filesystem */
31#define FUSE_ALLOW_OTHER (1 << 1) 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/** FUSE inode */ 34/** FUSE inode */
41struct fuse_inode { 35struct fuse_inode {
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 652c9d5df973..8dc66760b41a 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -257,8 +257,6 @@ enum {
257 OPT_GROUP_ID, 257 OPT_GROUP_ID,
258 OPT_DEFAULT_PERMISSIONS, 258 OPT_DEFAULT_PERMISSIONS,
259 OPT_ALLOW_OTHER, 259 OPT_ALLOW_OTHER,
260 OPT_KERNEL_CACHE,
261 OPT_DIRECT_IO,
262 OPT_MAX_READ, 260 OPT_MAX_READ,
263 OPT_ERR 261 OPT_ERR
264}; 262};
@@ -270,8 +268,6 @@ static match_table_t tokens = {
270 {OPT_GROUP_ID, "group_id=%u"}, 268 {OPT_GROUP_ID, "group_id=%u"},
271 {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, 269 {OPT_DEFAULT_PERMISSIONS, "default_permissions"},
272 {OPT_ALLOW_OTHER, "allow_other"}, 270 {OPT_ALLOW_OTHER, "allow_other"},
273 {OPT_KERNEL_CACHE, "kernel_cache"},
274 {OPT_DIRECT_IO, "direct_io"},
275 {OPT_MAX_READ, "max_read=%u"}, 271 {OPT_MAX_READ, "max_read=%u"},
276 {OPT_ERR, NULL} 272 {OPT_ERR, NULL}
277}; 273};
@@ -327,14 +323,6 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
327 d->flags |= FUSE_ALLOW_OTHER; 323 d->flags |= FUSE_ALLOW_OTHER;
328 break; 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 case OPT_MAX_READ: 326 case OPT_MAX_READ:
339 if (match_int(&args[0], &value)) 327 if (match_int(&args[0], &value))
340 return 0; 328 return 0;
@@ -363,10 +351,6 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
363 seq_puts(m, ",default_permissions"); 351 seq_puts(m, ",default_permissions");
364 if (fc->flags & FUSE_ALLOW_OTHER) 352 if (fc->flags & FUSE_ALLOW_OTHER)
365 seq_puts(m, ",allow_other"); 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 if (fc->max_read != ~0) 354 if (fc->max_read != ~0)
371 seq_printf(m, ",max_read=%u", fc->max_read); 355 seq_printf(m, ",max_read=%u", fc->max_read);
372 return 0; 356 return 0;
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index cdfaa51b9018..c65124a213a1 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -14,7 +14,7 @@
14#define FUSE_KERNEL_VERSION 7 14#define FUSE_KERNEL_VERSION 7
15 15
16/** Minor version number of this interface */ 16/** Minor version number of this interface */
17#define FUSE_KERNEL_MINOR_VERSION 1 17#define FUSE_KERNEL_MINOR_VERSION 2
18 18
19/** The node ID of the root inode */ 19/** The node ID of the root inode */
20#define FUSE_ROOT_ID 1 20#define FUSE_ROOT_ID 1
@@ -63,6 +63,15 @@ struct fuse_kstatfs {
63#define FATTR_MTIME (1 << 5) 63#define FATTR_MTIME (1 << 5)
64#define FATTR_CTIME (1 << 6) 64#define FATTR_CTIME (1 << 6)
65 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)
74
66enum fuse_opcode { 75enum fuse_opcode {
67 FUSE_LOOKUP = 1, 76 FUSE_LOOKUP = 1,
68 FUSE_FORGET = 2, /* no reply */ 77 FUSE_FORGET = 2, /* no reply */