Whamcloud - gitweb
LU-7829 osc: glimpse lock should match only with granted locks 38/18738/2
authorAndriy Skulysh <andriy.skulysh@seagate.com>
Tue, 16 Feb 2016 17:24:32 +0000 (19:24 +0200)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 23 Mar 2016 06:03:24 +0000 (06:03 +0000)
A deadlock is possible during ccc_prep_size()->ldlm_lock_match() vs
cl_io_lock() which is waiting for a matched lock and conflicts with
already taken lock before ccc_prep_size().

It is better to send an aditional lock request to avoid deadlock.

Seagate-bug-id: MRP-3312
Change-Id: I2eed05da4d587500cfc14350d9cc1b33547df4fe
Signed-off-by: Andriy Skulysh <andriy.skulysh@seagate.com>
Reviewed-on: http://review.whamcloud.com/18738
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/osc/osc_request.c

index f636360..3655730 100644 (file)
@@ -1987,7 +1987,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
        struct lustre_handle lockh = { 0 };
        struct ptlrpc_request *req = NULL;
        int intent = *flags & LDLM_FL_HAS_INTENT;
        struct lustre_handle lockh = { 0 };
        struct ptlrpc_request *req = NULL;
        int intent = *flags & LDLM_FL_HAS_INTENT;
-       __u64 match_lvb = agl ? 0 : LDLM_FL_LVB_READY;
+       __u64 match_flags = *flags;
        enum ldlm_mode mode;
        int rc;
        ENTRY;
        enum ldlm_mode mode;
        int rc;
        ENTRY;
@@ -2021,7 +2021,11 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
         mode = einfo->ei_mode;
         if (einfo->ei_mode == LCK_PR)
                 mode |= LCK_PW;
         mode = einfo->ei_mode;
         if (einfo->ei_mode == LCK_PR)
                 mode |= LCK_PW;
-        mode = ldlm_lock_match(obd->obd_namespace, *flags | match_lvb, res_id,
+       if (agl == 0)
+               match_flags |= LDLM_FL_LVB_READY;
+       if (intent != 0)
+               match_flags |= LDLM_FL_BLOCK_GRANTED;
+       mode = ldlm_lock_match(obd->obd_namespace, match_flags, res_id,
                               einfo->ei_type, policy, mode, &lockh, 0);
        if (mode) {
                struct ldlm_lock *matched;
                               einfo->ei_type, policy, mode, &lockh, 0);
        if (mode) {
                struct ldlm_lock *matched;