summaryrefslogtreecommitdiffstats
path: root/xlators/performance/nl-cache/src/nl-cache.c
diff options
context:
space:
mode:
authorPoornima G <pgurusid@redhat.com>2017-05-26 15:45:57 +0530
committerAtin Mukherjee <amukherj@redhat.com>2017-06-13 05:01:17 +0000
commit7674584fa53944a4e982e217798f31a3d1ef313b (patch)
treee3729576373927b49409bcd6520f78aa579d46d5 /xlators/performance/nl-cache/src/nl-cache.c
parent05b2fbd077cadc409994762e346ef94f4904545b (diff)
nl-cache: Fix a possible crash and stale cache
Issue1: Consider the followinf sequence of operations: ... nlc_ctx = nlc_ctx_get (inode i1) ....... -> nlc_clear_cache (i1) gets called as a part of nlc_invalidate or any other callers ... GF_FREE (ii nlc_ctx) LOCK (nlc_ctx->lock); -> This will result in crash as the ctx got freed in nlc_clear_cache. Issue2: lookup on dir1/file1 result in ENOENT add cache to dir1 at time T1 .... CHILD_DOWN at T2 lookup on dir1/file2 result in ENOENT add cache to dir1, but the cache time is still T1 lookup on dir1/file2 - should have been served from cache but the cache time is T1 < T2, hence cache is considered as invalid. So, after CHILD_DOWN the right thing would be to clear the cache and restart caching on that inode. Solution: Do not free nlc_ctx in nlc_clear_cache, but only in inode_forget() The fix for both issue1 and 2 is interleaved hence sending it as single patch. Change-Id: I83d8ed36c049a93567c6d7e63d045dc14ccbb397 BUG: 1458539 Signed-off-by: Poornima G <pgurusid@redhat.com> Reviewed-on: https://review.gluster.org/17453 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/performance/nl-cache/src/nl-cache.c')
-rw-r--r--xlators/performance/nl-cache/src/nl-cache.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/xlators/performance/nl-cache/src/nl-cache.c b/xlators/performance/nl-cache/src/nl-cache.c
index a72f03993aa..7dad8d95a53 100644
--- a/xlators/performance/nl-cache/src/nl-cache.c
+++ b/xlators/performance/nl-cache/src/nl-cache.c
@@ -473,12 +473,17 @@ nlc_invalidate (xlator_t *this, void *data)
inode_t *parent2 = NULL;
int ret = 0;
inode_table_t *itable = NULL;
+ nlc_conf_t *conf = NULL;
up_data = (struct gf_upcall *)data;
if (up_data->event_type != GF_UPCALL_CACHE_INVALIDATION)
goto out;
+ conf = this->private;
+ if (!conf)
+ goto out;
+
up_ci = (struct gf_upcall_cache_invalidation *)up_data->data;
/*TODO: Add he inodes found as a member in gf_upcall_cache_invalidation
@@ -520,6 +525,9 @@ nlc_invalidate (xlator_t *this, void *data)
nlc_inode_clear_cache (this, parent1, NLC_NONE);
if (parent2)
nlc_inode_clear_cache (this, parent2, NLC_NONE);
+
+ GF_ATOMIC_INC (conf->nlc_counter.nlc_invals);
+
out:
if (inode)
inode_unref (inode);
@@ -568,12 +576,23 @@ notify (xlator_t *this, int event, void *data, ...)
static int32_t
nlc_forget (xlator_t *this, inode_t *inode)
{
- uint64_t pe_int = 0;
+ uint64_t pe_int = 0;
+ uint64_t nlc_ctx_int = 0;
+ nlc_ctx_t *nlc_ctx = NULL;
+ nlc_conf_t *conf = NULL;
+
+ conf = this->private;
inode_ctx_reset1 (inode, this, &pe_int);
GF_ASSERT (pe_int == 0);
nlc_inode_clear_cache (this, inode, NLC_NONE);
+ inode_ctx_reset0 (inode, this, &nlc_ctx_int);
+ nlc_ctx = (void *) (long) nlc_ctx_int;
+ if (nlc_ctx) {
+ GF_FREE (nlc_ctx);
+ GF_ATOMIC_SUB (conf->current_cache_size, sizeof (*nlc_ctx));
+ }
return 0;
}