[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>
This commit is contained in:
Miklos Szeredi 2005-09-09 13:10:37 -07:00 committed by Linus Torvalds
parent 04730fef1f
commit 45323fb764
5 changed files with 18 additions and 59 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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 {

View file

@ -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;

View file

@ -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 */