9p: Add fscache support to 9p
This patch adds a persistent, read-only caching facility for 9p clients using the FS-Cache caching backend. When the fscache facility is enabled, each inode is associated with a corresponding vcookie which is an index into the FS-Cache indexing tree. The FS-Cache indexing tree is indexed at 3 levels: - session object associated with each mount. - inode/vcookie - actual data (pages) A cache tag is chosen randomly for each session. These tags can be read off /sys/fs/9p/caches and can be passed as a mount-time parameter to re-attach to the specified caching session. Signed-off-by: Abhishek Kulkarni <adkulkar@umail.iu.edu> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:
committed by
Eric Van Hensbergen
parent
637d020a02
commit
60e78d2c99
@@ -40,6 +40,7 @@
|
||||
#include "v9fs.h"
|
||||
#include "v9fs_vfs.h"
|
||||
#include "fid.h"
|
||||
#include "cache.h"
|
||||
|
||||
static const struct inode_operations v9fs_dir_inode_operations;
|
||||
static const struct inode_operations v9fs_dir_inode_operations_ext;
|
||||
@@ -197,6 +198,39 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
|
||||
wstat->extension = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
/**
|
||||
* v9fs_alloc_inode - helper function to allocate an inode
|
||||
* This callback is executed before setting up the inode so that we
|
||||
* can associate a vcookie with each inode.
|
||||
*
|
||||
*/
|
||||
|
||||
struct inode *v9fs_alloc_inode(struct super_block *sb)
|
||||
{
|
||||
struct v9fs_cookie *vcookie;
|
||||
vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache,
|
||||
GFP_KERNEL);
|
||||
if (!vcookie)
|
||||
return NULL;
|
||||
|
||||
vcookie->fscache = NULL;
|
||||
vcookie->qid = NULL;
|
||||
spin_lock_init(&vcookie->lock);
|
||||
return &vcookie->inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_destroy_inode - destroy an inode
|
||||
*
|
||||
*/
|
||||
|
||||
void v9fs_destroy_inode(struct inode *inode)
|
||||
{
|
||||
kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* v9fs_get_inode - helper function to setup an inode
|
||||
* @sb: superblock
|
||||
@@ -326,6 +360,21 @@ error:
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* v9fs_clear_inode - release an inode
|
||||
* @inode: inode to release
|
||||
*
|
||||
*/
|
||||
void v9fs_clear_inode(struct inode *inode)
|
||||
{
|
||||
filemap_fdatawrite(inode->i_mapping);
|
||||
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
v9fs_cache_inode_put_cookie(inode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_inode_from_fid - populate an inode by issuing a attribute request
|
||||
* @v9ses: session information
|
||||
@@ -356,8 +405,14 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||
|
||||
v9fs_stat2inode(st, ret, sb);
|
||||
ret->i_ino = v9fs_qid2ino(&st->qid);
|
||||
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
v9fs_vcookie_set_qid(ret, &st->qid);
|
||||
v9fs_cache_inode_get_cookie(ret);
|
||||
#endif
|
||||
p9stat_free(st);
|
||||
kfree(st);
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
@@ -751,7 +806,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
|
||||
err = -EPERM;
|
||||
v9ses = v9fs_inode2v9ses(dentry->d_inode);
|
||||
if (v9ses->cache == CACHE_LOOSE)
|
||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
|
||||
return simple_getattr(mnt, dentry, stat);
|
||||
|
||||
fid = v9fs_fid_lookup(dentry);
|
||||
|
Reference in New Issue
Block a user