Commit 45323fb7 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds
Browse files

[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: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 04730fef
Loading
Loading
Loading
Loading
+0 −26
Original line number Diff line number Diff line
@@ -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.
+8 −10
Original line number Diff line number Diff line
@@ -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;
}
}
+0 −6
Original line number Diff line number Diff line
@@ -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 {
+0 −16
Original line number Diff line number Diff line
@@ -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;
+10 −1
Original line number Diff line number Diff line
@@ -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 */