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 --- xlators/performance/io-cache/src/io-cache.c | 15 +++++++++++++- xlators/performance/md-cache/src/md-cache.c | 32 ++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'xlators/performance') diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 85e876531..bdaf0f1b8 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -313,6 +313,18 @@ ioc_forget (xlator_t *this, inode_t *inode) return 0; } +static int32_t +ioc_invalidate(xlator_t *this, inode_t *inode) +{ + ioc_inode_t *ioc_inode = NULL; + + inode_ctx_get(inode, this, (uint64_t *) &ioc_inode); + + if (ioc_inode) + ioc_inode_flush(ioc_inode); + + return 0; +} /* * ioc_cache_validate_cbk - @@ -1977,7 +1989,8 @@ struct xlator_dumpops dumpops = { struct xlator_cbks cbks = { .forget = ioc_forget, - .release = ioc_release + .release = ioc_release, + .invalidate = ioc_invalidate, }; struct volume_options options[] = { diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c index 9acffba2a..cf1aee9d6 100644 --- a/xlators/performance/md-cache/src/md-cache.c +++ b/xlators/performance/md-cache/src/md-cache.c @@ -378,7 +378,8 @@ mdc_to_iatt (struct md_cache *mdc, struct iatt *iatt) int -mdc_inode_iatt_set (xlator_t *this, inode_t *inode, struct iatt *iatt) +mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf, + struct iatt *iatt) { int ret = -1; struct md_cache *mdc = NULL; @@ -394,6 +395,19 @@ mdc_inode_iatt_set (xlator_t *this, inode_t *inode, struct iatt *iatt) goto unlock; } + /* + * Invalidate the inode if the mtime or ctime has changed + * and the prebuf doesn't match the value we have cached. + * TODO: writev returns with a NULL iatt due to + * performance/write-behind, causing invalidation on writes. + */ + if (IA_ISREG(inode->ia_type) && + ((iatt->ia_mtime != mdc->md_mtime) || + (iatt->ia_ctime != mdc->md_ctime))) + if (!prebuf || (prebuf->ia_ctime != mdc->md_ctime) || + (prebuf->ia_mtime != mdc->md_mtime)) + inode_invalidate(inode); + mdc_from_iatt (mdc, iatt); time (&mdc->ia_time); @@ -405,6 +419,10 @@ out: return ret; } +int mdc_inode_iatt_set(xlator_t *this, inode_t *inode, struct iatt *iatt) +{ + return mdc_inode_iatt_set_validate(this, inode, NULL, iatt); +} int mdc_inode_iatt_get (xlator_t *this, inode_t *inode, struct iatt *iatt) @@ -859,7 +877,7 @@ mdc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->loc.inode, postbuf); + mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf); out: MDC_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf, @@ -901,7 +919,7 @@ mdc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: MDC_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf, postbuf, @@ -1377,7 +1395,7 @@ mdc_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: MDC_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf, @@ -1422,7 +1440,7 @@ mdc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->loc.inode, postbuf); + mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf); out: MDC_STACK_UNWIND (setattr, frame, op_ret, op_errno, prebuf, postbuf, @@ -1464,7 +1482,7 @@ mdc_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: MDC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, prebuf, postbuf, @@ -1506,7 +1524,7 @@ mdc_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!local) goto out; - mdc_inode_iatt_set (this, local->fd->inode, postbuf); + mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf); out: MDC_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf, -- cgit