diff options
author | Ashish Pandey <aspandey@redhat.com> | 2017-07-28 15:18:29 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2017-07-31 11:55:27 +0000 |
commit | 12906467f0f8df2edc07ea8412c0c6be6fae11b3 (patch) | |
tree | 018761bc10b6dc36294917916647892121e71192 | |
parent | 96b179850d618c99d185ce7bfed5fe96e6cde919 (diff) |
ec/cluster: Update failure of fop on a brick properly
Problem:
In case of truncate, if writev or open fails on a brick,
in some cases it does not mark the failure onlock->good_mask.
This causes the update of size and version on all the bricks
even if it has failed on one of the brick. That ultimately
causes a data corruption.
Solution:
In callback of such writev and open calls, mark fop->good
for parent too.
Thanks Pranith Kumar K <pkarampu@redhat.com> for finding the
root cause.
Change-Id: I8a1da2888bff53b91a0d362b8c44fcdf658e7466
BUG: 1476205
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
Reviewed-on: https://review.gluster.org/17906
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-write.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index 5405d69fe35..68bea1ae55b 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -1025,11 +1025,19 @@ out: } } -/********************************************************************* - * - * File Operation : truncate - * - *********************************************************************/ +int32_t +ec_truncate_writev_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int32_t op_ret, int32_t op_errno, + struct iatt *prebuf, struct iatt *postbuf, + dict_t *xdata) +{ + ec_fop_data_t *fop = cookie; + + fop->parent->good &= fop->good; + ec_trace("TRUNCATE_WRITEV_CBK", cookie, "ret=%d, errno=%d", + op_ret, op_errno); + return 0; +} int32_t ec_truncate_write(ec_fop_data_t * fop, uintptr_t mask) { @@ -1059,8 +1067,8 @@ int32_t ec_truncate_write(ec_fop_data_t * fop, uintptr_t mask) iobuf_unref (iobuf); iobuf = NULL; - ec_writev(fop->frame, fop->xl, mask, fop->minimum, NULL, NULL, fop->fd, - &vector, 1, fop->user_size, 0, iobref, NULL); + ec_writev(fop->frame, fop->xl, mask, fop->minimum, ec_truncate_writev_cbk, + NULL, fop->fd, &vector, 1, fop->user_size, 0, iobref, NULL); err = 0; @@ -1082,6 +1090,7 @@ int32_t ec_truncate_open_cbk(call_frame_t * frame, void * cookie, ec_fop_data_t * fop = cookie; int32_t err; + fop->parent->good &= fop->good; if (op_ret >= 0) { fd_bind (fd); err = ec_truncate_write(fop->parent, fop->answer->mask); |