diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2014-09-18 18:26:08 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-09-23 09:50:22 -0700 |
commit | 6fffc4eaf408cb9b0b2891404ee54f4ab1dd5e2e (patch) | |
tree | 745cda86c0af027fba27f1d8d2650deeeec85a24 /xlators/cluster/afr | |
parent | 1b27b8231e2d69c3bfd4710ab3f631cd3604e362 (diff) |
cluster/afr: Do not reset pending xattrs on gfid or type mismatch in entry-sh
Backport of: http://review.gluster.org/8816
Change-Id: I8463a579f542a2336b02edba8f5fbfea0edbbffe
BUG: 1136829
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/8823
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 97 |
1 files changed, 79 insertions, 18 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 45ce881e123..63c86d8904e 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -195,6 +195,58 @@ __afr_selfheal_heal_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, return ret; } +static int +afr_selfheal_detect_gfid_and_type_mismatch (xlator_t *this, + struct afr_reply *replies, + uuid_t pargfid, char *bname, + int src_idx) +{ + int i = 0; + char g1[64] = {0,}; + char g2[64] = {0,}; + afr_private_t *priv = NULL; + + priv = this->private; + + for (i = 0; i < priv->child_count; i++) { + if (i == src_idx) + continue; + + if (!replies[i].valid) + continue; + + if (replies[i].op_ret != 0) + continue; + + if (uuid_compare (replies[src_idx].poststat.ia_gfid, + replies[i].poststat.ia_gfid)) { + gf_log (this->name, GF_LOG_ERROR, "Gfid mismatch " + "detected for <%s/%s>, %s on %s and %s on %s. " + "Skipping conservative merge on the file.", + uuid_utoa (pargfid), bname, + uuid_utoa_r (replies[i].poststat.ia_gfid, g1), + priv->children[i]->name, + uuid_utoa_r (replies[src_idx].poststat.ia_gfid, + g2), priv->children[src_idx]->name); + return -1; + } + + if ((replies[src_idx].poststat.ia_type) != + (replies[i].poststat.ia_type)) { + gf_log (this->name, GF_LOG_ERROR, "Type mismatch " + "detected for <%s/%s>, %d on %s and %d on %s. " + "Skipping conservative merge on the file.", + uuid_utoa (pargfid), bname, + replies[i].poststat.ia_type, + priv->children[i]->name, + replies[src_idx].poststat.ia_type, + priv->children[src_idx]->name); + return -1; + } + } + + return 0; +} static int __afr_selfheal_merge_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, @@ -202,11 +254,11 @@ __afr_selfheal_merge_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *healed_sinks, unsigned char *locked_on, struct afr_reply *replies) { - int ret = 0; - afr_private_t *priv = NULL; - int i = 0; - int source = -1; - unsigned char *newentry = NULL; + int ret = 0; + int i = 0; + int source = -1; + unsigned char *newentry = NULL; + afr_private_t *priv = NULL; priv = this->private; @@ -224,6 +276,14 @@ __afr_selfheal_merge_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, return 0; } + /* In case of a gfid or type mismatch on the entry, return -1.*/ + ret = afr_selfheal_detect_gfid_and_type_mismatch (this, replies, + fd->inode->gfid, + name, source); + + if (ret < 0) + return ret; + for (i = 0; i < priv->child_count; i++) { if (i == source || !healed_sinks[i]) continue; @@ -245,9 +305,10 @@ __afr_selfheal_merge_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, static int __afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this, fd_t *fd, - char *name, inode_t *inode, int source, - unsigned char *sources, unsigned char *healed_sinks, - unsigned char *locked_on, struct afr_reply *replies) + char *name, inode_t *inode, int source, + unsigned char *sources, unsigned char *healed_sinks, + unsigned char *locked_on, + struct afr_reply *replies) { int ret = -1; @@ -470,14 +531,14 @@ static int __afr_selfheal_entry (call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *locked_on) { - afr_private_t *priv = NULL; - int ret = -1; - unsigned char *sources = NULL; - unsigned char *sinks = NULL; - unsigned char *data_lock = NULL; - unsigned char *healed_sinks = NULL; - struct afr_reply *locked_replies = NULL; - int source = -1; + int ret = -1; + int source = -1; + unsigned char *sources = NULL; + unsigned char *sinks = NULL; + unsigned char *data_lock = NULL; + unsigned char *healed_sinks = NULL; + struct afr_reply *locked_replies = NULL; + afr_private_t *priv = NULL; priv = this->private; @@ -507,13 +568,13 @@ unlock: goto out; ret = afr_selfheal_entry_do (frame, this, fd, source, sources, - healed_sinks); + healed_sinks); if (ret) goto out; ret = afr_selfheal_undo_pending (frame, this, fd->inode, sources, sinks, healed_sinks, AFR_ENTRY_TRANSACTION, - locked_replies, data_lock); + locked_replies, data_lock); out: if (locked_replies) afr_replies_wipe (locked_replies, priv->child_count); |