diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2014-09-18 18:26:08 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2014-09-23 07:25:07 -0700 |
commit | 125e5428d31f5e0b659cbdb9ccdc310991fc1981 (patch) | |
tree | c2ce95cd4e7f27e965d511e7b61039fc77d761e8 | |
parent | e149a051bf226e16c6b7f1a816f998dace85d33d (diff) | |
download | glusterfs-125e5428d31f5e0b659cbdb9ccdc310991fc1981.tar.gz glusterfs-125e5428d31f5e0b659cbdb9ccdc310991fc1981.tar.xz glusterfs-125e5428d31f5e0b659cbdb9ccdc310991fc1981.zip |
cluster/afr: Do not reset pending xattrs on gfid or type mismatch in entry-sh
Change-Id: Ie27219a376382e2455a0fcc094f8b7eb243738ae
BUG: 1140613
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
Reviewed-on: http://review.gluster.org/8816
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
-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 45ce881e12..63c86d8904 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); |