path: root/xlators/cluster/afr/src/afr-common.c
diff options
authorkarthik-us <>2019-06-26 12:19:07 +0530
committerRavishankar N <>2019-07-12 11:16:48 +0000
commit3ef02e82f84e20edaa8ad4cbe921108319ec8ba2 (patch)
tree081e84ad3524f39933ddb8d22572aa773c33da89 /xlators/cluster/afr/src/afr-common.c
parent1a38a6f4853f87ac4e45240579581292290f4f27 (diff)
cluster/ta: Notify the clients only if there are pending heals
Problem: In case of thin arbiter, before index healer starts crawling the indices at every heal-timeout interval, even if there is nothing to be healed it will send an upcall notification to all the clients to release any AFR_TA_DOM_NOTIFY locks that they hold. SHD will wait for the upcall to return before proceeding with the heal even though there is nothing to be healed. This will also invalidates the cached information about the bricks states on the clients which leads to extra calls on TA from clients for the next reads & writes if needed. This will impact the IO performance. Fix: - Before sending the upcall to the clients, check for any pending heals on TA without taking any locks. - If there is nothing marked bad on TA, then continue with the index crawl to heal any dirty markings present on the files due to any post-op failure. - If there is a brick marked as bad on TA, then take the AFR_TA_DOM_NOTIFY lock on TA from SHD, get the state on TA and continue with the current healing process. Change-Id: Ieb477bc6cb18bbdfd4e7a0453c5ed79b574ec9d6 fixes: bz#1724184 Signed-off-by: karthik-us <>
Diffstat (limited to 'xlators/cluster/afr/src/afr-common.c')
1 files changed, 21 insertions, 0 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 6863bd0..bce0af5 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -7121,3 +7121,24 @@ afr_handle_replies_quorum(call_frame_t *frame, xlator_t *this)
local->op_ret = -1;
+afr_ta_dict_contains_pending_xattr(dict_t *dict, afr_private_t *priv, int child)
+ int *pending = NULL;
+ int ret = 0;
+ int i = 0;
+ ret = dict_get_ptr(dict, priv->pending_key[child], (void *)&pending);
+ if (ret == 0) {
+ for (i = 0; i < AFR_NUM_CHANGE_LOGS; i++) {
+ /* Not doing a ntoh32(pending) as we just want to check
+ * if it is non-zero or not. */
+ if (pending[i]) {
+ return _gf_true;
+ }
+ }
+ }
+ return _gf_false;