From ed3924b81491a79a08503661f55ab90d70b0d578 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Wed, 11 Apr 2018 20:52:27 +0530 Subject: cluster/afr: Fixing the flaws in arbiter becoming source patch Backport of https://review.gluster.org/19045 Problem: Setting the write_subvol value to read_subvol in case of metadata transaction during pre-op (commit 19f9bcff4aada589d4321356c2670ed283f02c03) might lead to the original problem of arbiter becoming source. Scenario: 1) All bricks are up and good 2) 2 writes w1 and w2 are in progress in parallel 3) ctx->read_subvol is good for all the subvolumes 4) w1 succeeds on brick0 and fails on brick1, yet to do post-op on the disk 5) read/lookup comes on the same file and refreshes read_subvols back to all good 6) metadata transaction happens which makes ctx->write_subvol to be assigned with ctx->read_subvol which is all good 7) w2 succeeds on brick1 and fails on brick0 and this will update the brick in reverse order leading to arbiter becoming source Fix: Instead of setting the ctx->write_subvol to ctx->read_subvol in the pre-op statge, if there is a metadata transaction, check in the function __afr_set_in_flight_sb_status() if it is a data/metadata transaction. Use the value of ctx->write_subvol if it is a data transactions and ctx->read_subvol value for other transactions. With this patch we assign the value of ctx->write_subvol in the afr_transaction_perform_fop() with the on disk value, instead of assigning it in the afr_changelog_pre_op() with the in memory value. Change-Id: Id2025a7e965f0578af35b1abaac793b019c43cc4 BUG: 1566131 Signed-off-by: karthik-us Signed-off-by: Ravishankar N --- xlators/cluster/afr/src/afr-inode-write.c | 57 +++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'xlators/cluster/afr/src/afr-inode-write.c') diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 97397f986b5..f0231b71113 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -507,6 +507,7 @@ afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, { afr_local_t *local = NULL; int op_errno = ENOMEM; + int ret = -1; local = AFR_FRAME_INIT (frame, op_errno); if (!local) @@ -529,7 +530,9 @@ afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, goto out; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; if (dict_set_uint32 (local->xdata_req, GLUSTERFS_OPEN_FD_COUNT, 4)) { op_errno = ENOMEM; @@ -654,7 +657,9 @@ afr_truncate (call_frame_t *frame, xlator_t *this, local->transaction.unwind = afr_truncate_unwind; loc_copy (&local->loc, loc); - local->inode = inode_ref (loc->inode); + ret = afr_set_inode_local (this, local, loc->inode); + if (ret) + goto out; local->op = GF_FOP_TRUNCATE; @@ -768,7 +773,9 @@ afr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, goto out; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; local->op = GF_FOP_FTRUNCATE; @@ -886,7 +893,9 @@ afr_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf, local->transaction.unwind = afr_setattr_unwind; loc_copy (&local->loc, loc); - local->inode = inode_ref (loc->inode); + ret = afr_set_inode_local (this, local, loc->inode); + if (ret) + goto out; local->op = GF_FOP_SETATTR; @@ -991,7 +1000,9 @@ afr_fsetattr (call_frame_t *frame, xlator_t *this, local->transaction.unwind = afr_fsetattr_unwind; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; local->op = GF_FOP_FSETATTR; @@ -1633,7 +1644,9 @@ afr_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, local->transaction.unwind = afr_setxattr_unwind; loc_copy (&local->loc, loc); - local->inode = inode_ref (loc->inode); + ret = afr_set_inode_local (this, local, loc->inode); + if (ret) + goto out; local->transaction.main_frame = frame; local->transaction.start = LLONG_MAX - 1; @@ -1745,7 +1758,9 @@ afr_fsetxattr (call_frame_t *frame, xlator_t *this, local->transaction.unwind = afr_fsetxattr_unwind; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; local->op = GF_FOP_FSETXATTR; @@ -1858,7 +1873,9 @@ afr_removexattr (call_frame_t *frame, xlator_t *this, local->transaction.unwind = afr_removexattr_unwind; loc_copy (&local->loc, loc); - local->inode = inode_ref (loc->inode); + ret = afr_set_inode_local (this, local, loc->inode); + if (ret) + goto out; local->op = GF_FOP_REMOVEXATTR; @@ -1965,7 +1982,9 @@ afr_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, local->transaction.unwind = afr_fremovexattr_unwind; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; local->op = GF_FOP_FREMOVEXATTR; @@ -2060,7 +2079,9 @@ afr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, local->cont.fallocate.len = len; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; if (xdata) local->xdata_req = dict_copy_with_ref (xdata, NULL); @@ -2172,7 +2193,9 @@ afr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, local->cont.discard.len = len; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; if (xdata) local->xdata_req = dict_copy_with_ref (xdata, NULL); @@ -2281,7 +2304,9 @@ afr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, local->cont.zerofill.len = len; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; if (xdata) local->xdata_req = dict_copy_with_ref (xdata, NULL); @@ -2393,7 +2418,9 @@ afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, local->transaction.unwind = afr_xattrop_unwind; loc_copy (&local->loc, loc); - local->inode = inode_ref (loc->inode); + ret = afr_set_inode_local (this, local, loc->inode); + if (ret) + goto out; local->op = GF_FOP_XATTROP; @@ -2487,7 +2514,9 @@ afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, local->transaction.unwind = afr_fxattrop_unwind; local->fd = fd_ref (fd); - local->inode = inode_ref (fd->inode); + ret = afr_set_inode_local (this, local, fd->inode); + if (ret) + goto out; local->op = GF_FOP_FXATTROP; -- cgit