Skip to content

Commit

Permalink
9p: implement optional loose read cache
Browse files Browse the repository at this point in the history
While cacheing is generally frowned upon in the 9p world, it has its
place -- particularly in situations where the remote file system is
exclusive and/or read-only.  The vacfs views of venti content addressable
store are a real-world instance of such a situation.  To facilitate higher
performance for these workloads (and eventually use the fscache patches),
we have enabled a "loose" cache mode which does not attempt to maintain
any form of consistency on the page-cache or dcache.  This results in over
two orders of magnitude performance improvement for cacheable block reads
in the Bonnie benchmark.  The more aggressive use of the dcache also seems
to improve metadata operational performance.

Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
  • Loading branch information
Eric Van Hensbergen committed Feb 18, 2007
1 parent 2c0463a commit e03abc0
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 9 deletions.
4 changes: 2 additions & 2 deletions Documentation/filesystems/00-INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Exporting
- explanation of how to make filesystems exportable.
Locking
- info on locking rules as they pertain to Linux VFS.
9p.txt
- 9p (v9fs) is an implementation of the Plan 9 remote fs protocol.
adfs.txt
- info and mount options for the Acorn Advanced Disc Filing System.
afs.txt
Expand Down Expand Up @@ -82,8 +84,6 @@ udf.txt
- info and mount options for the UDF filesystem.
ufs.txt
- info on the ufs filesystem.
v9fs.txt
- v9fs is a Unix implementation of the Plan 9 9p remote fs protocol.
vfat.txt
- info on using the VFAT filesystem used in Windows NT and Windows 95
vfs.txt
Expand Down
4 changes: 4 additions & 0 deletions Documentation/filesystems/9p.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ OPTIONS
aname=name aname specifies the file tree to access when the server is
offering several exported file systems.

cache=mode specifies a cacheing policy. By default, no caches are used.
loose = no attempts are made at consistency,
intended for exclusive, read-only mounts

debug=n specifies debug level. The debug level is a bitmask.
0x01 = display verbose error messages
0x02 = developer debug (DEBUG_CURRENT)
Expand Down
3 changes: 2 additions & 1 deletion fs/9p/fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
}

/**
* v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it
* v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
* release it
* @dentry: dentry to look for fid in
*
* find a fid in the dentry and then clone to a new private fid
Expand Down
9 changes: 8 additions & 1 deletion fs/9p/v9fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ enum {
Opt_uname, Opt_remotename,
/* Options that take no arguments */
Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
/* Cache options */
Opt_cache_loose,
/* Error token */
Opt_err
};
Expand All @@ -76,6 +78,8 @@ static match_table_t tokens = {
{Opt_fd, "fd"},
{Opt_legacy, "noextend"},
{Opt_nodevmap, "nodevmap"},
{Opt_cache_loose, "cache=loose"},
{Opt_cache_loose, "loose"},
{Opt_err, NULL}
};

Expand Down Expand Up @@ -106,6 +110,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
v9ses->debug = 0;
v9ses->rfdno = ~0;
v9ses->wfdno = ~0;
v9ses->cache = 0;

if (!options)
return;
Expand All @@ -121,7 +126,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
"integer field, but no integer?\n");
continue;
}

}
switch (token) {
case Opt_port:
Expand Down Expand Up @@ -169,6 +173,9 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
case Opt_nodevmap:
v9ses->nodev = 1;
break;
case Opt_cache_loose:
v9ses->cache = CACHE_LOOSE;
break;
default:
continue;
}
Expand Down
9 changes: 8 additions & 1 deletion fs/9p/v9fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct v9fs_session_info {
unsigned int afid; /* authentication fid */
unsigned int rfdno; /* read file descriptor number */
unsigned int wfdno; /* write file descriptor number */

unsigned int cache; /* cache mode */

char *name; /* user name to mount as */
char *remotename; /* name of remote hierarchy being mounted */
Expand All @@ -73,6 +73,13 @@ enum {
PROTO_FD,
};

/* possible values of ->cache */
/* eventually support loose, tight, time, session, default always none */
enum {
CACHE_NONE, /* default */
CACHE_LOOSE, /* no consistency */
};

extern struct dentry *v9fs_debugfs_root;

int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
Expand Down
2 changes: 2 additions & 0 deletions fs/9p/v9fs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@
extern struct file_system_type v9fs_fs_type;
extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
extern const struct file_operations v9fs_cached_file_operations;
extern const struct file_operations v9fs_dir_operations;
extern struct dentry_operations v9fs_dentry_operations;
extern struct dentry_operations v9fs_cached_dentry_operations;

struct inode *v9fs_get_inode(struct super_block *sb, int mode);
ino_t v9fs_qid2ino(struct v9fs_qid *qid);
Expand Down
2 changes: 2 additions & 0 deletions fs/9p/vfs_addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
int total = 0;
int result = 0;

dprintk(DEBUG_VFS, "\n");

buffer = kmap(page);
do {
if (count < rsize)
Expand Down
26 changes: 26 additions & 0 deletions fs/9p/vfs_dentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,30 @@
static int v9fs_dentry_delete(struct dentry *dentry)
{
dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);

return 1;
}

/**
* v9fs_cached_dentry_delete - called when dentry refcount equals 0
* @dentry: dentry in question
*
* Only return 1 if our inode is invalid. Only non-synthetic files
* (ones without mtime == 0) should be calling this function.
*
*/

static int v9fs_cached_dentry_delete(struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);

if(!inode)
return 1;

return 0;
}

/**
* v9fs_dentry_release - called when dentry is going to be freed
* @dentry: dentry that is being release
Expand Down Expand Up @@ -87,6 +108,11 @@ void v9fs_dentry_release(struct dentry *dentry)
}
}

struct dentry_operations v9fs_cached_dentry_operations = {
.d_delete = v9fs_cached_dentry_delete,
.d_release = v9fs_dentry_release,
};

struct dentry_operations v9fs_dentry_operations = {
.d_delete = v9fs_dentry_delete,
.d_release = v9fs_dentry_release,
Expand Down
18 changes: 18 additions & 0 deletions fs/9p/vfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ int v9fs_file_open(struct inode *inode, struct file *file)
vfid->filp = file;
kfree(fcall);

if((vfid->qid.version) && (v9ses->cache)) {
dprintk(DEBUG_VFS, "cached");
/* enable cached file options */
if(file->f_op == &v9fs_file_operations)
file->f_op = &v9fs_cached_file_operations;
}

return 0;

Clunk_Fid:
Expand Down Expand Up @@ -238,6 +245,17 @@ v9fs_file_write(struct file *filp, const char __user * data,
return total;
}

const struct file_operations v9fs_cached_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.aio_read = generic_file_aio_read,
.write = v9fs_file_write,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = generic_file_mmap,
};

const struct file_operations v9fs_file_operations = {
.llseek = generic_file_llseek,
.read = v9fs_file_read,
Expand Down
20 changes: 16 additions & 4 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,10 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
goto error;
}

dentry->d_op = &v9fs_dentry_operations;
if(v9ses->cache)
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);

if (nd && nd->flags & LOOKUP_OPEN) {
Expand Down Expand Up @@ -589,7 +592,10 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
goto error;
}

dentry->d_op = &v9fs_dentry_operations;
if(v9ses->cache)
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);
return 0;

Expand Down Expand Up @@ -626,7 +632,6 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,

sb = dir->i_sb;
v9ses = v9fs_inode2v9ses(dir);
dentry->d_op = &v9fs_dentry_operations;
dirfid = v9fs_fid_lookup(dentry->d_parent);

if(IS_ERR(dirfid))
Expand Down Expand Up @@ -697,6 +702,10 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,

fid->qid = fcall->params.rstat.stat.qid;
v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
if((fid->qid.version)&&(v9ses->cache))
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;

d_add(dentry, inode);
kfree(fcall);
Expand Down Expand Up @@ -1184,7 +1193,10 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
goto free_vfid;
}

dentry->d_op = &v9fs_dentry_operations;
if(v9ses->cache)
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;
d_instantiate(dentry, inode);
return 0;

Expand Down

0 comments on commit e03abc0

Please sign in to comment.