diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2019-04-01 11:53:57 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2019-04-02 12:18:33 +0000 |
commit | 0a827c1da96302661202e46ea43b6e2526a7ac87 (patch) | |
tree | fafae8844d92831c7b5c691bc0b22b8667f876a4 /xlators/cluster | |
parent | d0d3e10d44366c68fc153e48b229e72a4aa26e61 (diff) |
cluster/afr: Send inodelk/entrylk with non-zero lk-owner
Found missing assignment of lk-owner for an inodelk/entrylk before winding
the fops. locks xlator at the moment allows this operation. This leads to
multiple threads in the same client being able to get locks on the inode
because lk-owner is same and transport is same. So isolation with locks can't
be achieved. To fix it, we need locks xlator change which will disallow
null-lk-owner based inodelk/entrylk/lk. To achieve that we need to first
fix all the places which do this mistake.
updates bz#1624701
Change-Id: Ic3431da3f451a1414f1f4fdcfc4cf41e555f69dd
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 17 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.c | 43 |
2 files changed, 48 insertions, 12 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 002f97276f9..8c8cc0cb242 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -6463,6 +6463,8 @@ afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc) int op_errno = 0; dict_t *dict = NULL; afr_local_t *local = NULL; + afr_local_t *heal_local = NULL; + call_frame_t *heal_frame = NULL; local = frame->local; dict = dict_new(); @@ -6472,7 +6474,16 @@ afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc) goto out; } - ret = afr_selfheal_do(frame, this, loc->gfid); + heal_frame = afr_frame_create(this, &op_errno); + if (!heal_frame) { + ret = -1; + goto out; + } + heal_local = heal_frame->local; + heal_frame->local = frame->local; + /*Initiate heal with heal_frame with lk-owner set so that inodelk/entrylk + * work correctly*/ + ret = afr_selfheal_do(heal_frame, this, loc->gfid); if (ret == 1 || ret == 2) { ret = dict_set_sizen_str_sizen(dict, "sh-fail-msg", @@ -6494,6 +6505,10 @@ afr_heal_splitbrain_file(call_frame_t *frame, xlator_t *this, loc_t *loc) } out: + if (heal_frame) { + heal_frame->local = heal_local; + AFR_STACK_DESTROY(heal_frame); + } if (local->op == GF_FOP_GETXATTR) AFR_STACK_UNWIND(getxattr, frame, ret, op_errno, dict, NULL); else if (local->op == GF_FOP_SETXATTR) diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 7fcc9d48ada..7b16c5b0afb 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -1214,6 +1214,7 @@ _afr_handle_empty_brick(void *opaque) char *op_type = NULL; int op_type_len = 0; afr_empty_brick_args_t *data = NULL; + call_frame_t *op_frame = NULL; data = opaque; frame = data->frame; @@ -1221,12 +1222,20 @@ _afr_handle_empty_brick(void *opaque) if (!data->op_type) goto out; + op_frame = copy_frame(frame); + if (!op_frame) { + ret = -1; + op_errno = ENOMEM; + goto out; + } + op_type = data->op_type; op_type_len = strlen(op_type); - this = frame->this; + this = op_frame->this; priv = this->private; - local = AFR_FRAME_INIT(frame, op_errno); + afr_set_lk_owner(op_frame, this, op_frame->root); + local = AFR_FRAME_INIT(op_frame, op_errno); if (!local) goto out; @@ -1235,7 +1244,7 @@ _afr_handle_empty_brick(void *opaque) gf_msg(this->name, GF_LOG_INFO, 0, 0, "New brick is : %s", priv->children[empty_index]->name); - ret = _afr_handle_empty_brick_type(this, frame, &local->loc, empty_index, + ret = _afr_handle_empty_brick_type(this, op_frame, &local->loc, empty_index, AFR_METADATA_TRANSACTION, op_type, op_type_len); if (ret) { @@ -1251,7 +1260,7 @@ _afr_handle_empty_brick(void *opaque) local->xattr_req = NULL; local->xdata_req = NULL; - ret = _afr_handle_empty_brick_type(this, frame, &local->loc, empty_index, + ret = _afr_handle_empty_brick_type(this, op_frame, &local->loc, empty_index, AFR_ENTRY_TRANSACTION, op_type, op_type_len); if (ret) { @@ -1261,6 +1270,9 @@ _afr_handle_empty_brick(void *opaque) } ret = 0; out: + if (op_frame) { + AFR_STACK_DESTROY(op_frame); + } AFR_STACK_UNWIND(setxattr, frame, ret, op_errno, NULL); return 0; } @@ -1365,7 +1377,8 @@ int afr_handle_split_brain_commands(xlator_t *this, call_frame_t *frame, loc_t *loc, dict_t *dict) { - void *value = NULL; + void *choice_value = NULL; + void *resolve_value = NULL; afr_private_t *priv = NULL; afr_local_t *local = NULL; afr_spbc_timeout_t *data = NULL; @@ -1376,6 +1389,14 @@ afr_handle_split_brain_commands(xlator_t *this, call_frame_t *frame, loc_t *loc, priv = this->private; + ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_CHOICE, &choice_value, &len); + ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_RESOLVE, &resolve_value, + &len); + if (!choice_value && !resolve_value) { + ret = -1; + goto out; + } + local = AFR_FRAME_INIT(frame, op_errno); if (!local) { ret = 1; @@ -1384,9 +1405,9 @@ afr_handle_split_brain_commands(xlator_t *this, call_frame_t *frame, loc_t *loc, local->op = GF_FOP_SETXATTR; - ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_CHOICE, &value, &len); - if (value) { - spb_child_index = afr_get_split_brain_child_index(this, value, len); + if (choice_value) { + spb_child_index = afr_get_split_brain_child_index(this, choice_value, + len); if (spb_child_index < 0) { /* Case where value was "none" */ if (spb_child_index == -2) @@ -1424,9 +1445,9 @@ afr_handle_split_brain_commands(xlator_t *this, call_frame_t *frame, loc_t *loc, goto out; } - ret = dict_get_ptr_and_len(dict, GF_AFR_SBRAIN_RESOLVE, &value, &len); - if (value) { - spb_child_index = afr_get_split_brain_child_index(this, value, len); + if (resolve_value) { + spb_child_index = afr_get_split_brain_child_index(this, resolve_value, + len); if (spb_child_index < 0) { ret = 1; goto out; |