diff options
author | Poornima G <pgurusid@redhat.com> | 2017-05-26 15:45:57 +0530 |
---|---|---|
committer | Atin Mukherjee <amukherj@redhat.com> | 2017-06-13 05:01:17 +0000 |
commit | 7674584fa53944a4e982e217798f31a3d1ef313b (patch) | |
tree | e3729576373927b49409bcd6520f78aa579d46d5 /xlators/performance/nl-cache/src/nl-cache.c | |
parent | 05b2fbd077cadc409994762e346ef94f4904545b (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.c | 21 |
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; } |