From 00dae0e2ea1260a082af33dac5b06ca6aa68ccc3 Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Mon, 27 Aug 2018 11:46:33 +0530 Subject: cluster/afr: Delegate metadata heal with pending xattrs to SHD Problem: When metadata-self-heal is triggered on the mount, it blocks lookup until metadata-self-heal completes. But that can lead to hangs when lot of clients are accessing a directory which needs metadata heal and all of them trigger heals waiting for other clients to complete heal. Fix: Only when the heal is needed but the pending xattrs are not set, trigger metadata heal that could block lookup. This is the only case where different clients may give different metadata to the clients without heals, which should be avoided. Updates bz#1625575 Change-Id: I6089e9fda0770a83fb287941b229c882711f4e66 Signed-off-by: Pranith Kumar K --- xlators/cluster/afr/src/afr-common.c | 44 ++++++++++++++++++++++++++ xlators/cluster/afr/src/afr-self-heal-common.c | 38 ---------------------- xlators/cluster/afr/src/afr.h | 3 ++ 3 files changed, 47 insertions(+), 38 deletions(-) (limited to 'xlators/cluster/afr/src') diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 1e0c1a7b265..81176c784da 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -2692,6 +2692,42 @@ out: return 0; } +gf_boolean_t +afr_is_pending_set (xlator_t *this, dict_t *xdata, int type) +{ + int idx = -1; + afr_private_t *priv = NULL; + void *pending_raw = NULL; + int *pending_int = NULL; + int i = 0; + + priv = this->private; + idx = afr_index_for_transaction_type (type); + + if (dict_get_ptr (xdata, AFR_DIRTY, &pending_raw) == 0) { + if (pending_raw) { + pending_int = pending_raw; + + if (ntoh32 (pending_int[idx])) + return _gf_true; + } + } + + for (i = 0; i < priv->child_count; i++) { + if (dict_get_ptr (xdata, priv->pending_key[i], + &pending_raw)) + continue; + if (!pending_raw) + continue; + pending_int = pending_raw; + + if (ntoh32 (pending_int[idx])) + return _gf_true; + } + + return _gf_false; +} + static gf_boolean_t afr_can_start_metadata_self_heal(call_frame_t *frame, xlator_t *this) { @@ -2718,6 +2754,14 @@ afr_can_start_metadata_self_heal(call_frame_t *frame, xlator_t *this) continue; } + if (afr_is_pending_set (this, replies[i].xdata, + AFR_METADATA_TRANSACTION)) { + /* Let shd do the heal so that lookup is not blocked + * on getting metadata lock/doing the heal */ + start = _gf_false; + break; + } + if (gf_uuid_compare (stbuf.ia_gfid, replies[i].poststat.ia_gfid)) { start = _gf_false; break; diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 3cb69beabff..a1aad6315ac 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -2180,44 +2180,6 @@ afr_selfheal_unentrylk (call_frame_t *frame, xlator_t *this, inode_t *inode, return 0; } - -gf_boolean_t -afr_is_pending_set (xlator_t *this, dict_t *xdata, int type) -{ - int idx = -1; - afr_private_t *priv = NULL; - void *pending_raw = NULL; - int *pending_int = NULL; - int i = 0; - - priv = this->private; - idx = afr_index_for_transaction_type (type); - - if (dict_get_ptr (xdata, AFR_DIRTY, &pending_raw) == 0) { - if (pending_raw) { - pending_int = pending_raw; - - if (ntoh32 (pending_int[idx])) - return _gf_true; - } - } - - for (i = 0; i < priv->child_count; i++) { - if (dict_get_ptr (xdata, priv->pending_key[i], - &pending_raw)) - continue; - if (!pending_raw) - continue; - pending_int = pending_raw; - - if (ntoh32 (pending_int[idx])) - return _gf_true; - } - - return _gf_false; -} - - gf_boolean_t afr_is_data_set (xlator_t *this, dict_t *xdata) { diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 68087e0ea20..6fc555148c4 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1229,4 +1229,7 @@ afr_write_subvol_reset (call_frame_t *frame, xlator_t *this); int afr_set_inode_local (xlator_t *this, afr_local_t *local, inode_t *inode); + +gf_boolean_t +afr_is_pending_set (xlator_t *this, dict_t *xdata, int type); #endif /* __AFR_H__ */ -- cgit