diff options
-rw-r--r-- | xlators/cluster/ec/src/ec-common.h | 4 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 41 |
2 files changed, 41 insertions, 4 deletions
diff --git a/xlators/cluster/ec/src/ec-common.h b/xlators/cluster/ec/src/ec-common.h index e3fc3cef075..c532e0e03b0 100644 --- a/xlators/cluster/ec/src/ec-common.h +++ b/xlators/cluster/ec/src/ec-common.h @@ -119,6 +119,10 @@ gf_boolean_t ec_is_recoverable_error (int32_t op_errno); void ec_handle_healers_done (ec_fop_data_t *fop); int32_t +ec_heal_inspect (call_frame_t *frame, ec_t *ec, + inode_t *inode, unsigned char *locked_on, + gf_boolean_t *need_heal); +int32_t ec_get_heal_info (xlator_t *this, loc_t *loc, dict_t **dict); #endif /* __EC_COMMON_H__ */ diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index 1859d73d12b..548649b9a35 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -2332,6 +2332,8 @@ ec_heal_do (xlator_t *this, void *data, loc_t *loc, int32_t partial) intptr_t bad = 0; ec_fop_data_t *fop = data; gf_boolean_t blocking = _gf_false; + gf_boolean_t need_heal = _gf_false; + unsigned char *up_subvols = NULL; ec = this->private; @@ -2353,6 +2355,19 @@ ec_heal_do (xlator_t *this, void *data, loc_t *loc, int32_t partial) frame->root->pid = GF_CLIENT_PID_SELF_HEALD; participants = alloca0(ec->nodes); ec_mask_to_char_array (ec->xl_up, participants, ec->nodes); + + up_subvols = alloca0(ec->nodes); + ec_mask_to_char_array (ec->xl_up, up_subvols, ec->nodes); + + ec_heal_inspect (frame, ec, loc->inode, up_subvols, + &need_heal); + if (!need_heal) { + gf_msg (ec->xl->name, GF_LOG_DEBUG, 0, + EC_MSG_HEAL_FAIL, "Heal is not required for : %s ", + uuid_utoa(loc->gfid)); + goto out; + } + if (loc->name && strlen (loc->name)) { ret = ec_heal_name (frame, ec, loc->parent, (char *)loc->name, participants); @@ -2401,7 +2416,7 @@ ec_heal_do (xlator_t *this, void *data, loc_t *loc, int32_t partial) op_errno = -ret; } - +out: if (fop->cbks.heal) { fop->cbks.heal (fop->req_frame, fop, fop->xl, op_ret, op_errno, ec_char_array_to_mask (participants, @@ -2665,7 +2680,8 @@ out: } int32_t -ec_need_heal (ec_t *ec, default_args_cbk_t *replies, gf_boolean_t *need_heal) +ec_need_heal (ec_t *ec, default_args_cbk_t *replies, + gf_boolean_t *need_heal, int32_t lock_count) { uint64_t *dirty = NULL; unsigned char *sources = NULL; @@ -2691,7 +2707,9 @@ ec_need_heal (ec_t *ec, default_args_cbk_t *replies, gf_boolean_t *need_heal) goto out; } source_count = EC_COUNT (sources, ec->nodes); - if (source_count != ec->nodes) { + if (source_count == ec->nodes && lock_count > 0) { + *need_heal = _gf_false; + } else { *need_heal = _gf_true; } ret = source_count; @@ -2705,12 +2723,14 @@ ec_heal_inspect (call_frame_t *frame, ec_t *ec, gf_boolean_t *need_heal) { loc_t loc = {0}; + int i = 0; int ret = 0; dict_t *xdata = NULL; uint64_t zero_array[2] = {0}; uint64_t zero_value = 0; unsigned char *output = NULL; default_args_cbk_t *replies = NULL; + int32_t lock_count = 0; EC_REPLIES_ALLOC (replies, ec->nodes); output = alloca0 (ec->nodes); @@ -2720,6 +2740,8 @@ ec_heal_inspect (call_frame_t *frame, ec_t *ec, xdata = dict_new (); if (!xdata || + dict_set_str(xdata, GLUSTERFS_INODELK_DOM_COUNT, + ec->xl->name) || dict_set_static_bin (xdata, EC_XATTR_VERSION, zero_array, sizeof (zero_array)) || dict_set_static_bin (xdata, EC_XATTR_DIRTY, zero_array, @@ -2731,12 +2753,23 @@ ec_heal_inspect (call_frame_t *frame, ec_t *ec, } ret = cluster_lookup (ec->xl_list, locked_on, ec->nodes, replies, output, frame, ec->xl, &loc, xdata); + if (ret != ec->nodes) { ret = ec->nodes; *need_heal = _gf_true; goto out; } - ret = ec_need_heal (ec, replies, need_heal); + + for (i = 0; i < ec->nodes; i++) { + if (!output[i] || !replies[i].xdata) { + continue; + } + if ((dict_get_int32 (replies[i].xdata, GLUSTERFS_INODELK_COUNT, + &lock_count) == 0) && lock_count > 0) { + break; + } + } + ret = ec_need_heal (ec, replies, need_heal, lock_count); out: cluster_replies_wipe (replies, ec->nodes); |