diff options
| author | Venkatesh Somyajulu <vsomyaju@redhat.com> | 2014-06-12 14:18:05 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2014-06-14 10:55:41 -0700 | 
| commit | 72c7afcd091605e06a02e7c5de0eff18f0690a82 (patch) | |
| tree | f439fea9c1bfb4b3a117fb4f01ef587fd6a1bd56 /xlators/cluster/dht/src | |
| parent | ced0dcd817d02ce7ea2b69bff94dad26a96efe71 (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: 1104653
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>
Diffstat (limited to 'xlators/cluster/dht/src')
| -rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 18 | 
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 d2afbc788db..49241d17657 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -1486,6 +1486,7 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,          dict_t                  *dict           = NULL;          off_t                    offset         = 0;          struct iatt              iatt           = {0,}; +        inode_t                 *linked_inode   = NULL, *inode = NULL;          ret = syncop_lookup (this, loc, NULL, &iatt, NULL, NULL);          if (ret) { @@ -1551,6 +1552,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) { @@ -1566,9 +1568,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->parent, +                                                   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,  | 
