|
|
3604df |
From 478e3949c19c7ef60737f170d9f3ee60aa9f59c9 Mon Sep 17 00:00:00 2001
|
|
|
3604df |
From: Krutika Dhananjay <kdhananj@redhat.com>
|
|
|
3604df |
Date: Fri, 25 Nov 2016 15:54:30 +0530
|
|
|
3604df |
Subject: [PATCH 193/206] cluster/afr: Fix deadlock due to compound fops
|
|
|
3604df |
|
|
|
3604df |
Backport of: http://review.gluster.org/15929
|
|
|
3604df |
|
|
|
3604df |
When an afr data transaction is eligible for using
|
|
|
3604df |
eager-lock, this information is represented in
|
|
|
3604df |
local->transaction.eager_lock_on. However, if non-blocking
|
|
|
3604df |
inodelk attempt (which is a full lock) fails, AFR falls back
|
|
|
3604df |
to blocking locks which are range locks. At this point,
|
|
|
3604df |
local->transaction.eager_lock[] per brick is reset but
|
|
|
3604df |
local->transaction.eager_lock_on is still true.
|
|
|
3604df |
When AFR decides to compound post-op and unlock, it is after
|
|
|
3604df |
confirming that the transaction did not use eager lock (well,
|
|
|
3604df |
except for a small bug where local->transaction.locks_acquired[]
|
|
|
3604df |
is not considered).
|
|
|
3604df |
|
|
|
3604df |
But within afr_post_op_unlock_do(), afr again incorrectly sets
|
|
|
3604df |
the lock range to full-lock based on local->transaction.eager_lock_on
|
|
|
3604df |
value. This is a bug and can lead to deadlock since the locks acquired
|
|
|
3604df |
were range locks and a full unlock is being sent leading to unlock failure
|
|
|
3604df |
and thereby every other lock request (be it from SHD or other clients or
|
|
|
3604df |
glfsheal) getting blocked forever and the user perceives a hang.
|
|
|
3604df |
|
|
|
3604df |
FIX:
|
|
|
3604df |
Unconditionally rely on the range locks in inodelk object for unlocking
|
|
|
3604df |
when using compounded post-op + unlock.
|
|
|
3604df |
|
|
|
3604df |
Big thanks to Pranith for helping with the debugging.
|
|
|
3604df |
|
|
|
3604df |
Change-Id: Ie5af0de1f1a9dc1821dfde3654bab0e54d753281
|
|
|
3604df |
BUG: 1396166
|
|
|
3604df |
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
|
|
|
3604df |
Reviewed-on: https://code.engineering.redhat.com/gerrit/91332
|
|
|
3604df |
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
3604df |
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
3604df |
---
|
|
|
3604df |
xlators/cluster/afr/src/afr-transaction.c | 22 ++++++++--------------
|
|
|
3604df |
1 file changed, 8 insertions(+), 14 deletions(-)
|
|
|
3604df |
|
|
|
3604df |
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
|
|
|
3604df |
index fe53f49..690062f 100644
|
|
|
3604df |
--- a/xlators/cluster/afr/src/afr-transaction.c
|
|
|
3604df |
+++ b/xlators/cluster/afr/src/afr-transaction.c
|
|
|
3604df |
@@ -838,7 +838,7 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
|
|
|
3604df |
int ret = 0;
|
|
|
3604df |
int idx = 0;
|
|
|
3604df |
int nothing_failed = 1;
|
|
|
3604df |
- int piggyback = 0;
|
|
|
3604df |
+ gf_boolean_t compounded_unlock = _gf_true;
|
|
|
3604df |
gf_boolean_t need_undirty = _gf_false;
|
|
|
3604df |
|
|
|
3604df |
afr_handle_quorum (frame);
|
|
|
3604df |
@@ -912,9 +912,11 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
|
|
|
3604df |
if (local->transaction.pre_op[i] &&
|
|
|
3604df |
local->transaction.eager_lock[i]) {
|
|
|
3604df |
if (fd_ctx->lock_piggyback[i])
|
|
|
3604df |
- piggyback = 1;
|
|
|
3604df |
+ compounded_unlock = _gf_false;
|
|
|
3604df |
+ else if (fd_ctx->lock_acquired[i])
|
|
|
3604df |
+ compounded_unlock = _gf_false;
|
|
|
3604df |
}
|
|
|
3604df |
- if (piggyback == 1)
|
|
|
3604df |
+ if (compounded_unlock == _gf_false)
|
|
|
3604df |
break;
|
|
|
3604df |
}
|
|
|
3604df |
}
|
|
|
3604df |
@@ -923,7 +925,7 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
|
|
|
3604df |
|
|
|
3604df |
/* Do not compound if any brick got piggybacked lock as
|
|
|
3604df |
* unlock should not be done for that. */
|
|
|
3604df |
- if (local->compound && !piggyback) {
|
|
|
3604df |
+ if (local->compound && compounded_unlock) {
|
|
|
3604df |
afr_post_op_unlock_do (frame, this, xattr,
|
|
|
3604df |
afr_changelog_post_op_done,
|
|
|
3604df |
AFR_TRANSACTION_POST_OP);
|
|
|
3604df |
@@ -1434,11 +1436,9 @@ afr_post_op_unlock_do (call_frame_t *frame, xlator_t *this, dict_t *xattr,
|
|
|
3604df |
compound_args_t *args = NULL;
|
|
|
3604df |
afr_internal_lock_t *int_lock = NULL;
|
|
|
3604df |
afr_inodelk_t *inodelk = NULL;
|
|
|
3604df |
- struct gf_flock *flock_use = NULL;
|
|
|
3604df |
int i = 0;
|
|
|
3604df |
int call_count = 0;
|
|
|
3604df |
struct gf_flock flock = {0,};
|
|
|
3604df |
- struct gf_flock full_flock = {0,};
|
|
|
3604df |
int ret = 0;
|
|
|
3604df |
|
|
|
3604df |
local = frame->local;
|
|
|
3604df |
@@ -1451,8 +1451,6 @@ afr_post_op_unlock_do (call_frame_t *frame, xlator_t *this, dict_t *xattr,
|
|
|
3604df |
flock.l_start = inodelk->flock.l_start;
|
|
|
3604df |
flock.l_len = inodelk->flock.l_len;
|
|
|
3604df |
flock.l_type = F_UNLCK;
|
|
|
3604df |
- full_flock.l_type = F_UNLCK;
|
|
|
3604df |
-
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
ret = afr_changelog_prepare (this, frame, &call_count, changelog_resume,
|
|
|
3604df |
@@ -1480,22 +1478,18 @@ afr_post_op_unlock_do (call_frame_t *frame, xlator_t *this, dict_t *xattr,
|
|
|
3604df |
local->fd, GF_XATTROP_ADD_ARRAY,
|
|
|
3604df |
xattr, xdata);
|
|
|
3604df |
i++;
|
|
|
3604df |
- if (!local->transaction.eager_lock_on)
|
|
|
3604df |
- flock_use = &flock;
|
|
|
3604df |
- else
|
|
|
3604df |
- flock_use = &full_flock;
|
|
|
3604df |
|
|
|
3604df |
if (afr_is_inodelk_transaction(local)) {
|
|
|
3604df |
if (local->fd) {
|
|
|
3604df |
COMPOUND_PACK_ARGS (finodelk, GF_FOP_FINODELK,
|
|
|
3604df |
args, i,
|
|
|
3604df |
int_lock->domain, local->fd,
|
|
|
3604df |
- F_SETLK, flock_use, NULL);
|
|
|
3604df |
+ F_SETLK, &flock, NULL);
|
|
|
3604df |
} else {
|
|
|
3604df |
COMPOUND_PACK_ARGS (inodelk, GF_FOP_INODELK,
|
|
|
3604df |
args, i,
|
|
|
3604df |
int_lock->domain, &local->loc,
|
|
|
3604df |
- F_SETLK, flock_use, NULL);
|
|
|
3604df |
+ F_SETLK, &flock, NULL);
|
|
|
3604df |
}
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
--
|
|
|
3604df |
2.9.3
|
|
|
3604df |
|