aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortsutomu.owa@toshiba.co.jp <tsutomu.owa@toshiba.co.jp>2017-09-15 15:17:23 -0400
committerDavid Teigland <teigland@redhat.com>2017-09-25 13:45:21 -0400
commit294e7e458763dc1d229cbbe7147a6034bfc6e39a (patch)
tree5b5d3cda6d51e5f5c8a4817b7f4446a2c181515f
parent173a31fe2b23b3ccc45d0b70edb225b1d836c31d (diff)
DLM: fix conversion deadlock when DLM_LKF_NODLCKWT flag is set
When the DLM_LKF_NODLCKWT flag was set, even if conversion deadlock was detected, the caller of can_be_granted() was unknown. We change the behavior of can_be_granted() and change it to detect conversion deadlock regardless of whether the DLM_LKF_NODLCKWT flag is set or not. And depending on whether the DLM_LKF_NODLCKWT flag is set or not, we change the behavior at the caller of can_be_granted(). This fix has no effect except when using DLM_LKF_NODLCKWT flag. Currently, ocfs2 uses the DLM_LKF_NODLCKWT flag and does not expect a cancel operation from conversion deadlock when calling dlm_lock(). ocfs2 is implemented to perform a cancel operation by requesting BASTs (callback). Signed-off-by: Tadashi Miyauchi <miyauchi@toshiba-tops.co.jp> Signed-off-by: Tsutomu Owa <tsutomu.owa@toshiba.co.jp> Signed-off-by: David Teigland <teigland@redhat.com>
-rw-r--r--fs/dlm/lock.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index d4aaddec1b16..f145a2a9d6cb 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -2465,14 +2465,12 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
2465 if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) { 2465 if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) {
2466 lkb->lkb_grmode = DLM_LOCK_NL; 2466 lkb->lkb_grmode = DLM_LOCK_NL;
2467 lkb->lkb_sbflags |= DLM_SBF_DEMOTED; 2467 lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
2468 } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) { 2468 } else if (err) {
2469 if (err) 2469 *err = -EDEADLK;
2470 *err = -EDEADLK; 2470 } else {
2471 else { 2471 log_print("can_be_granted deadlock %x now %d",
2472 log_print("can_be_granted deadlock %x now %d", 2472 lkb->lkb_id, now);
2473 lkb->lkb_id, now); 2473 dlm_dump_rsb(r);
2474 dlm_dump_rsb(r);
2475 }
2476 } 2474 }
2477 goto out; 2475 goto out;
2478 } 2476 }
@@ -2501,13 +2499,6 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
2501 return rv; 2499 return rv;
2502} 2500}
2503 2501
2504/* FIXME: I don't think that can_be_granted() can/will demote or find deadlock
2505 for locks pending on the convert list. Once verified (watch for these
2506 log_prints), we should be able to just call _can_be_granted() and not
2507 bother with the demote/deadlk cases here (and there's no easy way to deal
2508 with a deadlk here, we'd have to generate something like grant_lock with
2509 the deadlk error.) */
2510
2511/* Returns the highest requested mode of all blocked conversions; sets 2502/* Returns the highest requested mode of all blocked conversions; sets
2512 cw if there's a blocked conversion to DLM_LOCK_CW. */ 2503 cw if there's a blocked conversion to DLM_LOCK_CW. */
2513 2504
@@ -2545,9 +2536,22 @@ static int grant_pending_convert(struct dlm_rsb *r, int high, int *cw,
2545 } 2536 }
2546 2537
2547 if (deadlk) { 2538 if (deadlk) {
2548 log_print("WARN: pending deadlock %x node %d %s", 2539 /*
2549 lkb->lkb_id, lkb->lkb_nodeid, r->res_name); 2540 * If DLM_LKB_NODLKWT flag is set and conversion
2550 dlm_dump_rsb(r); 2541 * deadlock is detected, we request blocking AST and
2542 * down (or cancel) conversion.
2543 */
2544 if (lkb->lkb_exflags & DLM_LKF_NODLCKWT) {
2545 if (lkb->lkb_highbast < lkb->lkb_rqmode) {
2546 queue_bast(r, lkb, lkb->lkb_rqmode);
2547 lkb->lkb_highbast = lkb->lkb_rqmode;
2548 }
2549 } else {
2550 log_print("WARN: pending deadlock %x node %d %s",
2551 lkb->lkb_id, lkb->lkb_nodeid,
2552 r->res_name);
2553 dlm_dump_rsb(r);
2554 }
2551 continue; 2555 continue;
2552 } 2556 }
2553 2557
@@ -3123,7 +3127,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
3123 deadlock, so we leave it on the granted queue and return EDEADLK in 3127 deadlock, so we leave it on the granted queue and return EDEADLK in
3124 the ast for the convert. */ 3128 the ast for the convert. */
3125 3129
3126 if (deadlk) { 3130 if (deadlk && !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
3127 /* it's left on the granted queue */ 3131 /* it's left on the granted queue */
3128 revert_lock(r, lkb); 3132 revert_lock(r, lkb);
3129 queue_cast(r, lkb, -EDEADLK); 3133 queue_cast(r, lkb, -EDEADLK);