From 32ffb79f18cbaebcbe6bba51599ca234f44675cc Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 13 Jun 2012 12:08:38 -0400 Subject: fuse/md-cache: add support for the 'fopen-keep-cache' mount option fopen-keep-cache disables unconditional page-cache invalidations on file open in fuse (via FOPEN_KEEP_CACHE) and replaces that behavior with detection of remote changes and explicit invalidations from mount/fuse. This option improves local caching through the page cache and native client. This change defines a new 'invalidate' translator callback to identify when an inode's cache mapping has been determined to be invalid. md-cache implements the policy to detect and invoke inode invalidations. fuse-bridge and io-cache implement invalidate handlers to invalidate the respective caches (page cache in the case of fuse). BUG: 833564 Change-Id: I99818da5777eaf06276c1c0b194669f5bab92d48 Signed-off-by: Brian Foster Reviewed-on: http://review.gluster.com/3584 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- libglusterfs/src/glusterfs.h | 1 + libglusterfs/src/inode.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ libglusterfs/src/inode.h | 3 +++ libglusterfs/src/xlator.h | 3 +++ 4 files changed, 55 insertions(+) (limited to 'libglusterfs') diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 780353d29..357284e27 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -285,6 +285,7 @@ struct _cmd_args { int selinux; int worm; int mac_compat; + int fopen_keep_cache; struct list_head xlator_options; /* list of xlator_option_t */ /* fuse options */ diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index e32eddb5d..a0088c03c 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -950,6 +950,54 @@ inode_forget (inode_t *inode, uint64_t nlookup) return 0; } +/* + * Invalidate an inode. This is invoked when a translator decides that an inode's + * cache is no longer valid. Any translator interested in taking action in this + * situation can define the invalidate callback. + */ +int +inode_invalidate(inode_t *inode) +{ + int ret = 0; + xlator_t *xl = NULL; + xlator_t *old_THIS = NULL; + + if (!inode) { + gf_log_callingfn(THIS->name, GF_LOG_WARNING, "inode not found"); + return -1; + } + + /* + * The master xlator is not in the graph but it can define an invalidate + * handler. + */ + xl = inode->table->xl->ctx->master; + if (xl && xl->cbks->invalidate) { + old_THIS = THIS; + THIS = xl; + ret = xl->cbks->invalidate(xl, inode); + THIS = old_THIS; + if (ret) + return ret; + } + + xl = inode->table->xl->graph->first; + while (xl) { + old_THIS = THIS; + THIS = xl; + if (xl->cbks->invalidate) + ret = xl->cbks->invalidate(xl, inode); + THIS = old_THIS; + + if (ret) + break; + + xl = xl->next; + } + + return ret; +} + static void __inode_unlink (inode_t *inode, inode_t *parent, const char *name) diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index 41003df71..20e28f682 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -130,6 +130,9 @@ inode_lookup (inode_t *inode); int inode_forget (inode_t *inode, uint64_t nlookup); +int +inode_invalidate(inode_t *inode); + int inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname, inode_t *newdir, const char *newname, diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2fce7dc47..5162d20e5 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -730,10 +730,13 @@ typedef int32_t (*cbk_forget_t) (xlator_t *this, typedef int32_t (*cbk_release_t) (xlator_t *this, fd_t *fd); +typedef int32_t (*cbk_invalidate_t)(xlator_t *this, inode_t *inode); + struct xlator_cbks { cbk_forget_t forget; cbk_release_t release; cbk_release_t releasedir; + cbk_invalidate_t invalidate; }; typedef int32_t (*dumpop_priv_t) (xlator_t *this); -- cgit