diff options
author | Ashish Pandey <aspandey@redhat.com> | 2019-07-11 16:52:49 +0530 |
---|---|---|
committer | hari gowtham <hari.gowtham005@gmail.com> | 2020-02-28 06:06:57 +0000 |
commit | bd37f5350ac9b85c18353069c36a6ae4e489d100 (patch) | |
tree | 93538b423aa0f7b887919edaa4f40f9fb42ecdb4 | |
parent | 559fd060c59edec69ba66be7e0a447c8e0408d51 (diff) |
cluster/ec: Change handling of heal failure to avoid crash
Problem:
ec_getxattr_heal_cbk was called with NULL as second argument
in case heal was failing.
This function was dereferencing "cookie" argument which caused crash.
Solution:
Cookie is changed to carry the value that was supposed to be
stored in fop->data, so even in the case when fop is NULL in error
case, there won't be any NULL dereference.
Thanks to Xavi for the suggestion about the fix.
Change-Id: I0798000d5cadb17c3c2fbfa1baf77033ffc2bb8c
fixes: bz#1806836
-rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 23 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-read.c | 3 |
2 files changed, 13 insertions, 13 deletions
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index 9b716b8c209..9d1723e54dc 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -1951,7 +1951,7 @@ ec_manager_heal_block(ec_fop_data_t *fop, int32_t state) case EC_STATE_REPORT: if (fop->cbks.heal) { - fop->cbks.heal(fop->req_frame, fop, fop->xl, 0, 0, + fop->cbks.heal(fop->req_frame, fop->data, fop->xl, 0, 0, (heal->good | heal->bad), heal->good, heal->bad, NULL); } @@ -1959,8 +1959,8 @@ ec_manager_heal_block(ec_fop_data_t *fop, int32_t state) return EC_STATE_END; case -EC_STATE_REPORT: if (fop->cbks.heal) { - fop->cbks.heal(fop->req_frame, fop, fop->xl, -1, fop->error, 0, - 0, 0, NULL); + fop->cbks.heal(fop->req_frame, fop->data, fop->xl, -1, + fop->error, 0, 0, 0, NULL); } return EC_STATE_END; @@ -1997,7 +1997,7 @@ out: if (fop != NULL) { ec_manager(fop, error); } else { - func(frame, NULL, this, -1, error, 0, 0, 0, NULL); + func(frame, heal, this, -1, error, 0, 0, 0, NULL); } } @@ -2006,10 +2006,11 @@ ec_heal_block_done(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good, uintptr_t bad, dict_t *xdata) { - ec_fop_data_t *fop = cookie; - ec_heal_t *heal = fop->data; + ec_heal_t *heal = cookie; - fop->heal = NULL; + if (heal->fop) { + heal->fop->heal = NULL; + } heal->fop = NULL; heal->error = op_ret < 0 ? op_errno : 0; syncbarrier_wake(heal->data); @@ -2586,7 +2587,7 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial) out: ec_reset_entry_healing(fop); if (fop->cbks.heal) { - fop->cbks.heal(fop->req_frame, fop, fop->xl, op_ret, op_errno, + fop->cbks.heal(fop->req_frame, fop->data, fop->xl, op_ret, op_errno, ec_char_array_to_mask(participants, ec->nodes), mgood & good, mbad & bad, NULL); } @@ -2638,8 +2639,8 @@ void ec_heal_fail(ec_t *ec, ec_fop_data_t *fop) { if (fop->cbks.heal) { - fop->cbks.heal(fop->req_frame, NULL, ec->xl, -1, fop->error, 0, 0, 0, - NULL); + fop->cbks.heal(fop->req_frame, fop->data, ec->xl, -1, fop->error, 0, 0, + 0, NULL); } ec_fop_data_release(fop); } @@ -2808,7 +2809,7 @@ fail: if (fop) ec_fop_data_release(fop); if (func) - func(frame, NULL, this, -1, err, 0, 0, 0, NULL); + func(frame, data, this, -1, err, 0, 0, 0, NULL); } int diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index ce30012e940..e9298a556b3 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -395,8 +395,7 @@ ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl, int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good, uintptr_t bad, dict_t *xdata) { - ec_fop_data_t *fop = cookie; - fop_getxattr_cbk_t func = fop->data; + fop_getxattr_cbk_t func = cookie; ec_t *ec = xl->private; dict_t *dict = NULL; char *str; |