From 49ac61ae11508a16a56534a656d77be47f3fe6b8 Mon Sep 17 00:00:00 2001 From: Ashish Pandey Date: Fri, 28 Jul 2017 15:18:29 +0530 Subject: 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 for finding the root cause. >Change-Id: I8a1da2888bff53b91a0d362b8c44fcdf658e7466 >BUG: 1476205 >Signed-off-by: Ashish Pandey >Reviewed-on: https://review.gluster.org/17906 >Reviewed-by: Pranith Kumar Karampuri >Smoke: Gluster Build System >CentOS-regression: Gluster Build System >Signed-off-by: Ashish Pandey Change-Id: I8a1da2888bff53b91a0d362b8c44fcdf658e7466 BUG: 1476870 Signed-off-by: Ashish Pandey Reviewed-on: https://review.gluster.org/17933 Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri CentOS-regression: Gluster Build System --- xlators/cluster/ec/src/ec-inode-write.c | 23 ++++++++++++++++------- 1 file 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); -- cgit