summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 13:10:37 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 14:03:47 -0700
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 83f96cf5696..6b5741e651a 100644
--- a/Documentation/filesystems/fuse.txt
+++ b/Documentation/filesystems/fuse.txt
@@ -80,32 +80,6 @@ Mount options
allowed to root, but this restriction can be removed with a
(userspace) configuration option.
-'kernel_cache'
-
- This option disables flushing the cache of the file contents on
- every open(). This should only be enabled on filesystems, where the
- file data is never changed externally (not through the mounted FUSE
- filesystem). Thus it is not suitable for network filesystems and
- other "intermediate" filesystems.
-
- NOTE: if this option is not specified (and neither 'direct_io') data
- is still cached after the open(), so a read() system call will not
- always initiate a read operation.
-
-'direct_io'
-
- This option disables the use of page cache (file content cache) in
- the kernel for this filesystem. This has several affects:
-
- - Each read() or write() system call will initiate one or more
- read or write operations, data will not be cached in the
- kernel.
-
- - The return value of the read() and write() system calls will
- correspond to the return values of the read and write
- operations. This is useful for example if the file size is not
- known in advance (before reading it).
-
'max_read=N'
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 224453557cf..a8dc88527fb 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -12,6 +12,8 @@
#include <linux/slab.h>
#include <linux/kernel.h>
+static struct file_operations fuse_direct_io_file_operations;
+
int fuse_open_common(struct inode *inode, struct file *file, int isdir)
{
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -70,12 +72,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
else
request_send(fc, req);
err = req->out.h.error;
- if (!err && !(fc->flags & FUSE_KERNEL_CACHE))
- invalidate_inode_pages(inode->i_mapping);
if (err) {
fuse_request_free(ff->release_req);
kfree(ff);
} else {
+ if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
+ file->f_op = &fuse_direct_io_file_operations;
+ if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
+ invalidate_inode_pages(inode->i_mapping);
ff->fh = outarg.fh;
file->private_data = ff;
}
@@ -544,12 +548,6 @@ static struct address_space_operations fuse_file_aops = {
void fuse_init_file_inode(struct inode *inode)
{
- struct fuse_conn *fc = get_fuse_conn(inode);
-
- if (fc->flags & FUSE_DIRECT_IO)
- inode->i_fop = &fuse_direct_io_file_operations;
- else {
- inode->i_fop = &fuse_file_operations;
- inode->i_data.a_ops = &fuse_file_aops;
- }
+ inode->i_fop = &fuse_file_operations;
+ inode->i_data.a_ops = &fuse_file_aops;
}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 8593d5bae7a..84849601363 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -30,12 +30,6 @@
doing the mount will be allowed to access the filesystem */
#define FUSE_ALLOW_OTHER (1 << 1)
-/** If the FUSE_KERNEL_CACHE flag is given, then cached data will not
- be flushed on open */
-#define FUSE_KERNEL_CACHE (1 << 2)
-
-/** Bypass the page cache for read and write operations */
-#define FUSE_DIRECT_IO (1 << 3)
/** FUSE inode */
struct fuse_inode {
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 652c9d5df97..8dc66760b41 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -257,8 +257,6 @@ enum {
OPT_GROUP_ID,
OPT_DEFAULT_PERMISSIONS,
OPT_ALLOW_OTHER,
- OPT_KERNEL_CACHE,
- OPT_DIRECT_IO,
OPT_MAX_READ,
OPT_ERR
};
@@ -270,8 +268,6 @@ static match_table_t tokens = {
{OPT_GROUP_ID, "group_id=%u"},
{OPT_DEFAULT_PERMISSIONS, "default_permissions"},
{OPT_ALLOW_OTHER, "allow_other"},
- {OPT_KERNEL_CACHE, "kernel_cache"},
- {OPT_DIRECT_IO, "direct_io"},
{OPT_MAX_READ, "max_read=%u"},
{OPT_ERR, NULL}
};
@@ -327,14 +323,6 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
d->flags |= FUSE_ALLOW_OTHER;
break;
- case OPT_KERNEL_CACHE:
- d->flags |= FUSE_KERNEL_CACHE;
- break;
-
- case OPT_DIRECT_IO:
- d->flags |= FUSE_DIRECT_IO;
- break;
-
case OPT_MAX_READ:
if (match_int(&args[0], &value))
return 0;
@@ -363,10 +351,6 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_puts(m, ",default_permissions");
if (fc->flags & FUSE_ALLOW_OTHER)
seq_puts(m, ",allow_other");
- if (fc->flags & FUSE_KERNEL_CACHE)
- seq_puts(m, ",kernel_cache");
- if (fc->flags & FUSE_DIRECT_IO)
- seq_puts(m, ",direct_io");
if (fc->max_read != ~0)
seq_printf(m, ",max_read=%u", fc->max_read);
return 0;
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index cdfaa51b901..c65124a213a 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -14,7 +14,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 1
+#define FUSE_KERNEL_MINOR_VERSION 2
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -63,6 +63,15 @@ struct fuse_kstatfs {
#define FATTR_MTIME (1 << 5)
#define FATTR_CTIME (1 << 6)
+/**
+ * Flags returned by the OPEN request
+ *
+ * FOPEN_DIRECT_IO: bypass page cache for this open file
+ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ */
+#define FOPEN_DIRECT_IO (1 << 0)
+#define FOPEN_KEEP_CACHE (1 << 1)
+
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */