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().

Signed-off-by: Tadashi Miyauchi <miyau...@toshiba-tops.co.jp>
Signed-off-by: Tsutomu Owa <tsutomu....@toshiba.co.jp>
---
 fs/dlm/lock.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 35502d4..edee26a 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -2466,14 +2466,12 @@ static int can_be_granted(struct dlm_rsb *r, struct 
dlm_lkb *lkb, int now,
                if (lkb->lkb_exflags & DLM_LKF_CONVDEADLK) {
                        lkb->lkb_grmode = DLM_LOCK_NL;
                        lkb->lkb_sbflags |= DLM_SBF_DEMOTED;
-               } else if (!(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
-                       if (err)
-                               *err = -EDEADLK;
-                       else {
-                               log_print("can_be_granted deadlock %x now %d",
-                                         lkb->lkb_id, now);
-                               dlm_dump_rsb(r);
-                       }
+               } else if (err) {
+                       *err = -EDEADLK;
+               } else {
+                       log_print("can_be_granted deadlock %x now %d",
+                                 lkb->lkb_id, now);
+                       dlm_dump_rsb(r);
                }
                goto out;
        }
@@ -2519,6 +2517,7 @@ static int grant_pending_convert(struct dlm_rsb *r, int 
high, int *cw,
        int recover = rsb_flag(r, RSB_RECOVER_GRANT);
        int hi, demoted, quit, grant_restart, demote_restart;
        int deadlk;
+       int exflags;
 
        quit = 0;
  restart:
@@ -2549,6 +2548,17 @@ static int grant_pending_convert(struct dlm_rsb *r, int 
high, int *cw,
                        log_print("WARN: pending deadlock %x node %d %s",
                                  lkb->lkb_id, lkb->lkb_nodeid, r->res_name);
                        dlm_dump_rsb(r);
+                       /*
+                        * If DLM_LKB_NODLKWT flag is set and conversion
+                        * deadlock is detected, we request blocking AST and
+                        * down (or cancel) conversion.
+                        */
+                       if (lkb->lkb_exflags & DLM_LKF_NODLCKWT &&
+                           lkb->lkb_highbast < lkb->lkb_rqmode) {
+                               queue_bast(r, lkb, lkb->lkb_rqmode);
+                               lkb->lkb_highbast = lkb->lkb_rqmode;
+                       }
+
                        continue;
                }
 
@@ -3124,7 +3134,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb 
*lkb)
           deadlock, so we leave it on the granted queue and return EDEADLK in
           the ast for the convert. */
 
-       if (deadlk) {
+       if (deadlk && !(lkb->lkb_exflags & DLM_LKF_NODLCKWT)) {
                /* it's left on the granted queue */
                revert_lock(r, lkb);
                queue_cast(r, lkb, -EDEADLK);
-- 
2.7.4





Reply via email to