diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2015-01-20 14:58:34 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2015-01-23 21:43:13 -0800 |
commit | 6c10f6db7c53e96881b29ca70dfc08b1ffb231b3 (patch) | |
tree | 1463a3bc78c5a7427602f569c4adf788b74a91e9 | |
parent | 304cfeea0106ee7a9e1786637bab403f72c96155 (diff) |
cluster/dht: In MKDIR(), aggregate iatts from non-hashed subvols too
PROBLEM:
Gathering iatts from ONLY the hashed subvol during MKDIR and unwinding
them can cause md-cache to cache and serve these values for a while to
the application.
And then, at a later point of time, when a LOOKUP on either the dir or
its parent gathers attributes from all subvolumes of dht and things are
evened out as part of DHT_UPDATE_TIME, the application could be getting
a different set of [cm]times (i.e., one of the non-hashed subvolumes'
times could be selected by virtue of having the highest values),
causing it to think the directory underwent modification even when it
might not have.
The effect of this bug becomes apparent in programs like tar, which rely
on the ctime of the files before and after archiving a file to
ascertain that the file remained unchanged during this time.
FIX:
Aggregate iatts from ALL sub-volumes of DHT during MKDIR.
Change-Id: I04c4ca3e3b9552772e2b089be680f8afeb72089e
BUG: 1179169
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/9465
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
Tested-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index b41186215bf..0b3aa93e43b 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -4816,6 +4816,7 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int this_call_cnt = 0; int ret = -1; gf_boolean_t subvol_filled = _gf_false; + gf_boolean_t dir_exists = _gf_false; call_frame_t *prev = NULL; dht_layout_t *layout = NULL; @@ -4831,7 +4832,7 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, ret = dht_layout_merge (this, layout, prev->this, -1, ENOSPC, NULL); } else { - if (op_ret == -1 && op_errno == EEXIST) + if (op_ret == -1 && op_errno == EEXIST) { /* Very likely just a race between mkdir and self-heal (from lookup of a concurrent mkdir attempt). @@ -4840,6 +4841,8 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, pre-existing different directory. */ op_ret = 0; + dir_exists = _gf_true; + } ret = dht_layout_merge (this, layout, prev->this, op_ret, op_errno, NULL); } @@ -4853,6 +4856,14 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->op_errno = op_errno; goto unlock; } + + if (dir_exists) + goto unlock; + + dht_iatt_merge (this, &local->stbuf, stbuf, prev->this); + dht_iatt_merge (this, &local->preparent, preparent, prev->this); + dht_iatt_merge (this, &local->postparent, postparent, + prev->this); } unlock: UNLOCK (&frame->lock); |