summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2015-01-20 14:58:34 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-01-23 21:43:13 -0800
commit6c10f6db7c53e96881b29ca70dfc08b1ffb231b3 (patch)
tree1463a3bc78c5a7427602f569c4adf788b74a91e9
parent304cfeea0106ee7a9e1786637bab403f72c96155 (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.c13
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);