diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2018-08-27 12:40:16 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2018-09-04 01:52:02 +0000 |
commit | f29689783d970cba804505d7c778c905b2ba1992 (patch) | |
tree | 14be40bab39b877e69a7a2583a7c32efbc9e44d8 /xlators/cluster/afr/src/afr-self-heal-name.c | |
parent | af0d5a9b5375a5cd87ac10b429e2b9934718ce5b (diff) |
cluster/afr: Delegate name-heal when possible
Problem:
When name-self-heal is triggered on the mount, it blocks
lookup until name-self-heal completes. But that can lead
to hangs when lot of clients are accessing a directory which
needs name heal and all of them trigger heals waiting
for other clients to complete heal.
Fix:
When a name-heal is needed but quorum number of names have the
file and pending xattrs exist on the parent, then better to
delegate the heal to SHD which will be completed as part of
entry-heal of the parent directory. We could also do the same
for quorum-number of names not present but we don't have
any known use-case where this is a frequent occurrence so
not changing that part at the moment. When there is a gfid
mismatch or missing gfid it is important to complete the heal
so that next rename doesn't assume everything is fine and
perform a rename etc
fixes bz#1622821
Change-Id: I8b002c85dffc6eb6f2833e742684a233daefeb2c
Signed-off-by: Pranith Kumar K <pkarampu@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.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c index bcd0e60c947..0a5be29d5ee 100644 --- a/xlators/cluster/afr/src/afr-self-heal-name.c +++ b/xlators/cluster/afr/src/afr-self-heal-name.c @@ -634,20 +634,26 @@ afr_selfheal_name_unlocked_inspect (call_frame_t *frame, xlator_t *this, continue; if ((replies[i].op_ret == -1) && - (replies[i].op_errno == ENODATA)) + (replies[i].op_errno == ENODATA)) { *need_heal = _gf_true; + break; + } if (first_idx == -1) { first_idx = i; continue; } - if (replies[i].op_ret != replies[first_idx].op_ret) + if (replies[i].op_ret != replies[first_idx].op_ret) { *need_heal = _gf_true; + break; + } if (gf_uuid_compare (replies[i].poststat.ia_gfid, - replies[first_idx].poststat.ia_gfid)) + replies[first_idx].poststat.ia_gfid)) { *need_heal = _gf_true; + break; + } } if (inode) |