summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkatesh Somyajulu <vsomyaju@redhat.com>2014-06-12 14:18:05 +0530
committerKaleb KEITHLEY <kkeithle@redhat.com>2014-10-20 07:27:36 -0700
commit67ccd153a889d81d4cd89534dbce792c111ad1c6 (patch)
tree4060ee1663e007e225698776f6b81fbb844f7541
parentf8b5bfd5f329ce06dcd208beaf5c50c3a35f0a53 (diff)
dht/rebalance: Do not allow rebalance when gfid mismatch found
Due to race condition, it may so happen that, gfid obtained in readdirp and gfid found by lookup are different for a given name. in that case do no allow the rebalance. Readdirp of an entry will bring the gfid, which will be stored in the inode through inode_link, and when lookup is done and gfid brought by lookup is different from the one stored in the inode, client3_3_lookup_cbk will return ESATLE and error will be captured by rebalance process. Change-Id: Iad839177ef9b80c1dd0e87f3406bcf4cb018e6fa BUG: 1139984 Signed-off-by: Venkatesh Somyajulu <vsomyaju@redhat.com> Reviewed-on: http://review.gluster.org/7973 Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Reviewed-on: http://review.gluster.org/8670 Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index 23efa8d57b3..d6e34f92036 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -1329,6 +1329,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
off_t offset = 0;
struct iatt iatt = {0,};
int readdirp_errno = 0;
+ inode_t *linked_inode = NULL, *inode = NULL;
ret = syncop_lookup (this, loc, NULL, &iatt, NULL, NULL);
if (ret) {
@@ -1396,6 +1397,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
continue;
loc_wipe (&entry_loc);
+
ret =dht_build_child_loc (this, &entry_loc, loc,
entry->d_name);
if (ret) {
@@ -1411,9 +1413,23 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
continue;
}
- entry_loc.inode->ia_type = entry->d_stat.ia_type;
uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid);
+
+ /*In case the gfid stored in the inode by inode_link
+ * and the gfid obtained in the lookup differs, then
+ * client3_3_lookup_cbk will return ESTALE and proper
+ * error will be captured
+ */
+
+ linked_inode = inode_link (entry_loc.inode, loc->inode,
+ entry->d_name,
+ &entry->d_stat);
+
+ inode = entry_loc.inode;
+ entry_loc.inode = linked_inode;
+ inode_unref (inode);
+
if (uuid_is_null (loc->gfid)) {
gf_log (this->name, GF_LOG_ERROR, "%s/%s"
"gfid not present", loc->path,