summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/afr/src/afr-self-heal-name.c
diff options
context:
space:
mode:
authorRavishankar N <ravishankar@redhat.com>2018-09-28 17:00:00 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2018-12-03 06:44:19 +0000
commit4d58730c0cd6ab5db39aec8a15276f7bd3371b04 (patch)
tree9991e615677cc9d9db0b13cebf97442fe42e02fd /xlators/cluster/afr/src/afr-self-heal-name.c
parent4364093869f59ed2af3f7d10d5a72df490eac9a9 (diff)
afr: assign gfid during name heal when no 'source' is present.
Problem: If parent dir is in split-brain or has dirty xattrs set, and the file has gfid missing on one of the bricks, then name heal won't assign the gfid. Fix: Use the brick we select the gfid from as the 'source'. Note: Problem was found while trying to debug a split-brain issue on Cynthia Zhou's setup. updates: bz#1637249 Change-Id: Id088d4f0fb017aa35122de426654194e581ed742 Reported-by: Cynthia Zhou <cynthia.zhou@nokia-sbell.com> Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Diffstat (limited to 'xlators/cluster/afr/src/afr-self-heal-name.c')
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-name.c47
1 files changed, 8 insertions, 39 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c
index 39aacee6ecf..aa20ad1b835 100644
--- a/xlators/cluster/afr/src/afr-self-heal-name.c
+++ b/xlators/cluster/afr/src/afr-self-heal-name.c
@@ -18,7 +18,8 @@ __afr_selfheal_assign_gfid(xlator_t *this, inode_t *parent, uuid_t pargfid,
const char *bname, inode_t *inode,
struct afr_reply *replies, void *gfid,
unsigned char *locked_on, int source,
- unsigned char *sources, gf_boolean_t is_gfid_absent)
+ unsigned char *sources, gf_boolean_t is_gfid_absent,
+ int *gfid_idx)
{
int ret = 0;
int up_count = 0;
@@ -46,8 +47,8 @@ __afr_selfheal_assign_gfid(xlator_t *this, inode_t *parent, uuid_t pargfid,
}
}
- afr_lookup_and_heal_gfid(this, parent, bname, inode, replies, source,
- sources, gfid);
+ ret = afr_lookup_and_heal_gfid(this, parent, bname, inode, replies, source,
+ sources, gfid, gfid_idx);
out:
return ret;
@@ -146,35 +147,6 @@ __afr_selfheal_name_expunge(xlator_t *this, inode_t *parent, uuid_t pargfid,
return ret;
}
-/* This function is to be called after ensuring that there is no gfid mismatch
- * for the inode across multiple sources
- */
-static int
-afr_selfheal_gfid_idx_get(xlator_t *this, struct afr_reply *replies,
- unsigned char *sources)
-{
- int i = 0;
- int gfid_idx = -1;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!replies[i].valid || replies[i].op_ret != 0)
- continue;
-
- if (!sources[i])
- continue;
-
- if (gf_uuid_is_null(replies[i].poststat.ia_gfid))
- continue;
-
- gfid_idx = i;
- break;
- }
- return gfid_idx;
-}
-
static gf_boolean_t
afr_selfheal_name_need_heal_check(xlator_t *this, struct afr_reply *replies)
{
@@ -400,21 +372,18 @@ __afr_selfheal_name_do(call_frame_t *frame, xlator_t *this, inode_t *parent,
gfid = gfid_req;
} else {
gfid = &replies[gfid_idx].poststat.ia_gfid;
+ if (source == -1)
+ /* Either entry split-brain or dirty xattrs are present on parent.*/
+ source = gfid_idx;
}
is_gfid_absent = (gfid_idx == -1) ? _gf_true : _gf_false;
ret = __afr_selfheal_assign_gfid(this, parent, pargfid, bname, inode,
replies, gfid, locked_on, source, sources,
- is_gfid_absent);
+ is_gfid_absent, &gfid_idx);
if (ret)
return ret;
- if (gfid_idx == -1) {
- gfid_idx = afr_selfheal_gfid_idx_get(this, replies, sources);
- if (gfid_idx == -1)
- return -1;
- }
-
ret = __afr_selfheal_name_impunge(frame, this, parent, pargfid, bname,
inode, replies, gfid_idx);
if (ret == -EIO)