Whamcloud - gitweb
LU-13645 ldlm: group locks for DOM IBIT lock 06/39406/7
authorVitaly Fertman <c17818@cray.com>
Tue, 4 Aug 2020 12:12:04 +0000 (15:12 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 30 Oct 2020 06:19:57 +0000 (06:19 +0000)
Group lock is supposed to be taken on such operations as layout swap
used for e.g. HSM, and is to be taken for DOM locks as well.

HPE-bug-id: LUS-8987
Signed-off-by: Vitaly Fertman <c17818@cray.com>
Change-Id: I97888e1aee853d7fe04548681b2ed6805cb494ae
Reviewed-on: https://review.whamcloud.com/39406
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
14 files changed:
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/ldlm/ldlm_inodebits.c
lustre/ldlm/ldlm_internal.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_resource.c
lustre/mdc/mdc_dev.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_io.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanity-dom.sh
lustre/tests/sanityn.sh
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index cf9b359..375bd88 100644 (file)
@@ -2438,6 +2438,7 @@ struct ldlm_inodebits {
                __u64 try_bits; /* optional bits to try */
                __u64 cancel_bits; /* for lock convert */
        };
+       __u64 li_gid;
 };
 
 struct ldlm_flock_wire {
index 7dd78d0..68914d9 100644 (file)
@@ -157,8 +157,9 @@ restart:
  */
 static int
 ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req,
-                           struct list_head *work_list)
+                           __u64 *ldlm_flags, struct list_head *work_list)
 {
+       enum ldlm_mode req_mode = req->l_req_mode;
        struct list_head *tmp;
        struct ldlm_lock *lock;
        __u64 req_bits = req->l_policy_data.l_inodebits.bits;
@@ -167,6 +168,8 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req,
 
        ENTRY;
 
+       lockmode_verify(req_mode);
+
        /* There is no sense in lock with no bits set. Also such a lock
         * would be compatible with any other bit lock.
         * Meanwhile that can be true if there were just try_bits and all
@@ -201,10 +204,41 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req,
                        continue;
                }
 
-               /* locks' mode are compatible, bits don't matter */
-               if (lockmode_compat(lock->l_req_mode, req->l_req_mode)) {
-                       /* jump to last lock in mode group */
-                       tmp = mode_tail;
+               if (lockmode_compat(lock->l_req_mode, req_mode)) {
+                       /* non group locks are compatible, bits don't matter */
+                       if (likely(req_mode != LCK_GROUP)) {
+                               /* jump to last lock in mode group */
+                               tmp = mode_tail;
+                               continue;
+                       }
+
+                       if (req->l_policy_data.l_inodebits.li_gid ==
+                           lock->l_policy_data.l_inodebits.li_gid) {
+                               if (ldlm_is_granted(lock))
+                                       RETURN(2);
+
+                               if (*ldlm_flags & LDLM_FL_BLOCK_NOWAIT)
+                                       RETURN(-EWOULDBLOCK);
+
+                               /* Place the same group together */
+                               ldlm_resource_insert_lock_after(lock, req);
+                               RETURN(0);
+                       }
+               }
+
+               /* GROUP locks are placed to a head of the waiting list, but
+                * grouped by gid. */
+               if (unlikely(req_mode == LCK_GROUP && !ldlm_is_granted(lock))) {
+                       compat = 0;
+                       if (lock->l_req_mode != LCK_GROUP) {
+                               /* Already not a GROUP lock, insert before. */
+                               ldlm_resource_insert_lock_before(lock, req);
+                               break;
+                       }
+                       /* Still GROUP but a different gid(the same gid would
+                        * be handled above). Keep searching for the same gid */
+                       LASSERT(req->l_policy_data.l_inodebits.li_gid !=
+                               lock->l_policy_data.l_inodebits.li_gid);
                        continue;
                }
 
@@ -241,14 +275,23 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req,
                                    !ldlm_is_cos_incompat(req) &&
                                    ldlm_is_cos_enabled(req) &&
                                    lock->l_client_cookie == req->l_client_cookie)
-                                       goto not_conflicting;
+                                       goto skip_work_list;
+
+                               compat = 0;
+
+                               if (unlikely(lock->l_req_mode == LCK_GROUP)) {
+                                       LASSERT(ldlm_has_dom(lock));
+
+                                       if (*ldlm_flags & LDLM_FL_BLOCK_NOWAIT)
+                                               RETURN(-EWOULDBLOCK);
+
+                                       goto skip_work_list;
+                               }
 
                                /* Found a conflicting policy group. */
                                if (!work_list)
                                        RETURN(0);
 
-                               compat = 0;
-
                                /* Add locks of the policy group to @work_list
                                 * as blocking locks for @req */
                                if (lock->l_blocking_ast)
@@ -260,7 +303,7 @@ ldlm_inodebits_compat_queue(struct list_head *queue, struct ldlm_lock *req,
                                                ldlm_add_ast_work_item(lock,
                                                                req, work_list);
                        }
-not_conflicting:
+skip_work_list:
                        if (tmp == mode_tail)
                                break;
 
@@ -280,7 +323,7 @@ not_conflicting:
  * waiting queues. The lock is granted if no conflicts are found in
  * either queue.
  */
-int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
+int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *ldlm_flags,
                                enum ldlm_process_intention intention,
                                enum ldlm_error *err,
                                struct list_head *work_list)
@@ -288,7 +331,7 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
        struct ldlm_resource *res = lock->l_resource;
        struct list_head *grant_work = intention == LDLM_PROCESS_ENQUEUE ?
                                                        NULL : work_list;
-       int rc;
+       int rc, rc2 = 0;
        ENTRY;
 
        *err = ELDLM_LOCK_ABORTED;
@@ -297,7 +340,7 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
 
        if (intention == LDLM_PROCESS_RESCAN) {
                struct list_head *bl_list =
-                       *flags & LDLM_FL_BLOCK_NOWAIT ? NULL : work_list;
+                       *ldlm_flags & LDLM_FL_BLOCK_NOWAIT ? NULL : work_list;
 
                LASSERT(lock->l_policy_data.l_inodebits.bits != 0);
 
@@ -320,11 +363,13 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
                 * any blocked locks from granted queue during every reprocess
                 * and bl_ast will be sent if needed.
                 */
+               *ldlm_flags = 0;
                rc = ldlm_inodebits_compat_queue(&res->lr_granted, lock,
-                                                bl_list);
+                                                ldlm_flags, bl_list);
                if (!rc)
                        RETURN(LDLM_ITER_STOP);
-               rc = ldlm_inodebits_compat_queue(&res->lr_waiting, lock, NULL);
+               rc = ldlm_inodebits_compat_queue(&res->lr_waiting, lock,
+                                                ldlm_flags, NULL);
                if (!rc)
                        RETURN(LDLM_ITER_STOP);
 
@@ -333,7 +378,7 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
                        lock->l_policy_data.l_inodebits.bits |=
                                lock->l_policy_data.l_inodebits.try_bits;
                        lock->l_policy_data.l_inodebits.try_bits = 0;
-                       *flags |= LDLM_FL_LOCK_CHANGED;
+                       *ldlm_flags |= LDLM_FL_LOCK_CHANGED;
                }
                ldlm_resource_unlink_lock(lock);
                ldlm_grant_lock(lock, grant_work);
@@ -342,16 +387,26 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
                RETURN(LDLM_ITER_CONTINUE);
        }
 
-       rc = ldlm_inodebits_compat_queue(&res->lr_granted, lock, work_list);
-       rc += ldlm_inodebits_compat_queue(&res->lr_waiting, lock, work_list);
+       rc = ldlm_inodebits_compat_queue(&res->lr_granted, lock,
+                                        ldlm_flags, work_list);
+       if (rc < 0)
+               GOTO(out, *err = rc);
 
        if (rc != 2) {
+               rc2 = ldlm_inodebits_compat_queue(&res->lr_waiting, lock,
+                                                 ldlm_flags, work_list);
+               if (rc2 < 0)
+                       GOTO(out, *err = rc = rc2);
+       }
+
+       if (rc + rc2 != 2) {
                /* if there were only bits to try and all are conflicting */
                if ((lock->l_policy_data.l_inodebits.bits |
                     lock->l_policy_data.l_inodebits.try_bits)) {
-                       /* There is no sense to set LDLM_FL_NO_TIMEOUT to @flags
-                        * for DOM lock while they are enqueued through intents,
-                        * i.e. @lock here is local which does not timeout. */
+                       /* There is no sense to set LDLM_FL_NO_TIMEOUT to
+                        * @ldlm_flags for DOM lock while they are enqueued
+                        * through intents, i.e. @lock here is local which does
+                        * not timeout. */
                        *err = ELDLM_OK;
                }
        } else {
@@ -360,7 +415,7 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
                        lock->l_policy_data.l_inodebits.bits |=
                                lock->l_policy_data.l_inodebits.try_bits;
                        lock->l_policy_data.l_inodebits.try_bits = 0;
-                       *flags |= LDLM_FL_LOCK_CHANGED;
+                       *ldlm_flags |= LDLM_FL_LOCK_CHANGED;
                }
                LASSERT(lock->l_policy_data.l_inodebits.bits);
                ldlm_resource_unlink_lock(lock);
@@ -369,6 +424,8 @@ int ldlm_process_inodebits_lock(struct ldlm_lock *lock, __u64 *flags,
        }
 
        RETURN(LDLM_ITER_CONTINUE);
+out:
+       return rc;
 }
 #endif /* HAVE_SERVER_SUPPORT */
 
@@ -376,6 +433,7 @@ void ldlm_ibits_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy,
                                     union ldlm_policy_data *lpolicy)
 {
        lpolicy->l_inodebits.bits = wpolicy->l_inodebits.bits;
+       lpolicy->l_inodebits.li_gid = wpolicy->l_inodebits.li_gid;
        /**
         * try_bits are to be handled outside of generic write_to_local due
         * to different behavior on a server and client.
@@ -388,6 +446,7 @@ void ldlm_ibits_policy_local_to_wire(const union ldlm_policy_data *lpolicy,
        memset(wpolicy, 0, sizeof(*wpolicy));
        wpolicy->l_inodebits.bits = lpolicy->l_inodebits.bits;
        wpolicy->l_inodebits.try_bits = lpolicy->l_inodebits.try_bits;
+       wpolicy->l_inodebits.li_gid = lpolicy->l_inodebits.li_gid;
 }
 
 /**
@@ -535,7 +594,7 @@ int ldlm_inodebits_alloc_lock(struct ldlm_lock *lock)
 }
 
 void ldlm_inodebits_add_lock(struct ldlm_resource *res, struct list_head *head,
-                            struct ldlm_lock *lock)
+                            struct ldlm_lock *lock, bool tail)
 {
        int i;
 
@@ -544,15 +603,36 @@ void ldlm_inodebits_add_lock(struct ldlm_resource *res, struct list_head *head,
 
        if (head == &res->lr_waiting) {
                for (i = 0; i < MDS_INODELOCK_NUMBITS; i++) {
-                       if (lock->l_policy_data.l_inodebits.bits & BIT(i))
+                       if (!(lock->l_policy_data.l_inodebits.bits & BIT(i)))
+                               continue;
+                       if (tail)
                                list_add_tail(&lock->l_ibits_node->lin_link[i],
-                                       &res->lr_ibits_queues->liq_waiting[i]);
+                                        &res->lr_ibits_queues->liq_waiting[i]);
+                       else
+                               list_add(&lock->l_ibits_node->lin_link[i],
+                                        &res->lr_ibits_queues->liq_waiting[i]);
                }
        } else if (head == &res->lr_granted && lock->l_ibits_node != NULL) {
                for (i = 0; i < MDS_INODELOCK_NUMBITS; i++)
                        LASSERT(list_empty(&lock->l_ibits_node->lin_link[i]));
                OBD_SLAB_FREE_PTR(lock->l_ibits_node, ldlm_inodebits_slab);
                lock->l_ibits_node = NULL;
+       } else if (head != &res->lr_granted) {
+               /* we are inserting in a middle of a list, after @head */
+               struct ldlm_lock *orig = list_entry(head, struct ldlm_lock,
+                                                   l_res_link);
+               LASSERT(orig->l_policy_data.l_inodebits.bits ==
+                       lock->l_policy_data.l_inodebits.bits);
+               /* The is no a use case to insert before with exactly matched
+                * set of bits */
+               LASSERT(tail == false);
+
+               for (i = 0; i < MDS_INODELOCK_NUMBITS; i++) {
+                       if (!(lock->l_policy_data.l_inodebits.bits & (1 << i)))
+                               continue;
+                       list_add(&lock->l_ibits_node->lin_link[i],
+                                &orig->l_ibits_node->lin_link[i]);
+               }
        }
 }
 
index 58b2db6..84c3182 100644 (file)
@@ -208,7 +208,7 @@ void ldlm_extent_unlink_lock(struct ldlm_lock *lock);
 
 int ldlm_inodebits_alloc_lock(struct ldlm_lock *lock);
 void ldlm_inodebits_add_lock(struct ldlm_resource *res, struct list_head *head,
-                            struct ldlm_lock *lock);
+                            struct ldlm_lock *lock, bool tail);
 void ldlm_inodebits_unlink_lock(struct ldlm_lock *lock);
 
 /* ldlm_flock.c */
index 00d4f43..546f351 100644 (file)
@@ -1215,6 +1215,12 @@ static int lock_matches(struct ldlm_lock *lock, struct ldlm_match_data *data)
                     data->lmd_policy->l_inodebits.bits) !=
                    data->lmd_policy->l_inodebits.bits)
                        return INTERVAL_ITER_CONT;
+
+               if (unlikely(match == LCK_GROUP) &&
+                   data->lmd_policy->l_inodebits.li_gid != LDLM_GID_ANY &&
+                   lpol->l_inodebits.li_gid !=
+                   data->lmd_policy->l_inodebits.li_gid)
+                       return INTERVAL_ITER_CONT;
                break;
        default:
                ;
@@ -2799,7 +2805,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
        switch (resource->lr_type) {
        case LDLM_EXTENT:
                libcfs_debug_msg(msgdata,
-                                "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s [%llu->%llu] (req %llu->%llu) flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n",
+                                "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s [%llu->%llu] (req %llu->%llu) gid %llu flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n",
                                 &vaf,
                                 ldlm_lock_to_ns_name(lock), lock,
                                 lock->l_handle.h_cookie,
@@ -2813,6 +2819,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
                                 lock->l_policy_data.l_extent.start,
                                 lock->l_policy_data.l_extent.end,
                                 lock->l_req_extent.start, lock->l_req_extent.end,
+                                lock->l_req_extent.gid,
                                 lock->l_flags, nid,
                                 lock->l_remote_handle.cookie,
                                 exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
@@ -2844,7 +2851,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 
        case LDLM_IBITS:
                libcfs_debug_msg(msgdata,
-                                "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " bits %#llx/%#llx rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n",
+                                "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " bits %#llx/%#llx rrc: %d type: %s gid %llu flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n",
                                 &vaf,
                                 ldlm_lock_to_ns_name(lock),
                                 lock, lock->l_handle.h_cookie,
@@ -2857,6 +2864,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
                                 lock->l_policy_data.l_inodebits.try_bits,
                                 atomic_read(&resource->lr_refcount),
                                 ldlm_typename[resource->lr_type],
+                                lock->l_policy_data.l_inodebits.li_gid,
                                 lock->l_flags, nid,
                                 lock->l_remote_handle.cookie,
                                 exp ? refcount_read(&exp->exp_handle.h_ref) : -99,
index a18daa8..0f4c9d4 100644 (file)
@@ -1623,7 +1623,7 @@ static void __ldlm_resource_add_lock(struct ldlm_resource *res,
                list_add(&lock->l_res_link, head);
 
        if (res->lr_type == LDLM_IBITS)
-               ldlm_inodebits_add_lock(res, head, lock);
+               ldlm_inodebits_add_lock(res, head, lock, tail);
 
        ldlm_resource_dump(D_INFO, res);
 }
@@ -1655,6 +1655,11 @@ void ldlm_resource_insert_lock_after(struct ldlm_lock *original,
 
 /**
  * Insert a lock into resource before the specified lock.
+ *
+ * IBITS waiting locks are to be inserted to the ibit lists as well, and only
+ * the insert-after operation is supported for them, because the set of bits
+ * of the previous and the new locks must match. Therefore, get the previous
+ * lock and insert after.
  */
 void ldlm_resource_insert_lock_before(struct ldlm_lock *original,
                                       struct ldlm_lock *new)
index 3edd170..eddfdda 100644 (file)
 #include "mdc_internal.h"
 
 static void mdc_lock_build_policy(const struct lu_env *env,
+                                 const struct cl_lock *lock,
                                  union ldlm_policy_data *policy)
 {
        memset(policy, 0, sizeof *policy);
        policy->l_inodebits.bits = MDS_INODELOCK_DOM;
+       if (lock) {
+               policy->l_inodebits.li_gid = lock->cll_descr.cld_gid;
+       }
 }
 
 int mdc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data)
@@ -147,7 +151,8 @@ struct ldlm_lock *mdc_dlmlock_at_pgoff(const struct lu_env *env,
        ENTRY;
 
        fid_build_reg_res_name(lu_object_fid(osc2lu(obj)), resname);
-       mdc_lock_build_policy(env, policy);
+       mdc_lock_build_policy(env, NULL, policy);
+       policy->l_inodebits.li_gid = LDLM_GID_ANY;
 
        flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING;
        if (dap_flags & OSC_DAP_FL_TEST_LOCK)
@@ -885,7 +890,7 @@ enqueue_base:
         * osc_lock.
         */
        fid_build_reg_res_name(lu_object_fid(osc2lu(osc)), resname);
-       mdc_lock_build_policy(env, policy);
+       mdc_lock_build_policy(env, lock, policy);
        LASSERT(!oscl->ols_speculative);
        result = mdc_enqueue_send(env, osc_export(osc), resname,
                                  &oscl->ols_flags, policy,
@@ -951,6 +956,8 @@ int mdc_lock_init(const struct lu_env *env, struct cl_object *obj,
 
        ols->ols_flags = flags;
        ols->ols_speculative = !!(enqflags & CEF_SPECULATIVE);
+       if (lock->cll_descr.cld_mode == CLM_GROUP)
+               ols->ols_flags |= LDLM_FL_ATOMIC_CB;
 
        if (ols->ols_flags & LDLM_FL_HAS_INTENT) {
                ols->ols_flags |= LDLM_FL_BLOCK_GRANTED;
index 68f98d0..2a0c36f 100644 (file)
@@ -164,6 +164,13 @@ void mdt_lock_reg_init(struct mdt_lock_handle *lh, enum ldlm_mode lm)
        lh->mlh_type = MDT_REG_LOCK;
 }
 
+void mdt_lh_reg_init(struct mdt_lock_handle *lh, struct ldlm_lock *lock)
+{
+       mdt_lock_reg_init(lh, lock->l_req_mode);
+       if (lock->l_req_mode == LCK_GROUP)
+               lh->mlh_gid = lock->l_policy_data.l_inodebits.li_gid;
+}
+
 void mdt_lock_pdo_init(struct mdt_lock_handle *lh, enum ldlm_mode lock_mode,
                       const struct lu_name *lname)
 {
@@ -3528,6 +3535,7 @@ int mdt_object_local_lock(struct mdt_thread_info *info, struct mdt_object *o,
 
        policy->l_inodebits.bits = *ibits;
        policy->l_inodebits.try_bits = trybits;
+       policy->l_inodebits.li_gid = lh->mlh_gid;
 
         /*
          * Use LDLM_FL_LOCAL_ONLY for this lock. We do not know yet if it is
@@ -5654,8 +5662,9 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
                        m->mdt_skip_lfsck = 1;
        }
 
-       /* DoM files get IO lock at open optionally by default */
-       m->mdt_opts.mo_dom_lock = ALWAYS_DOM_LOCK_ON_OPEN;
+       /* Just try to get a DoM lock by default. Otherwise, having a group
+        * lock granted, it may get blocked for a long time. */
+       m->mdt_opts.mo_dom_lock = TRYLOCK_DOM_ON_OPEN;
        /* DoM files are read at open and data is packed in the reply */
        m->mdt_opts.mo_dom_read_open = 1;
 
index 8e22408..e1b12aa 100644 (file)
@@ -371,6 +371,7 @@ struct mdt_lock_handle {
        /* Regular lock */
        struct lustre_handle    mlh_reg_lh;
        enum ldlm_mode          mlh_reg_mode;
+       __u64                   mlh_gid;
 
        /* Pdirops lock */
        struct lustre_handle    mlh_pdo_lh;
@@ -780,6 +781,7 @@ void mdt_lock_pdo_init(struct mdt_lock_handle *lh, enum ldlm_mode lock_mode,
                       const struct lu_name *lname);
 
 void mdt_lock_reg_init(struct mdt_lock_handle *lh, enum ldlm_mode lm);
+void mdt_lh_reg_init(struct mdt_lock_handle *lh, struct ldlm_lock *lock);
 
 int mdt_lock_setup(struct mdt_thread_info *info, struct mdt_object *mo,
                   struct mdt_lock_handle *lh);
index 0ffee16..2115c0a 100644 (file)
@@ -1225,7 +1225,8 @@ int mdt_brw_enqueue(struct mdt_thread_info *mti, struct ldlm_namespace *ns,
        /* resent case */
        if (!lustre_handle_is_used(&lhc->mlh_reg_lh)) {
                mdt_lock_handle_init(lhc);
-               mdt_lock_reg_init(lhc, (*lockp)->l_req_mode);
+               mdt_lh_reg_init(lhc, *lockp);
+
                /* This will block MDT thread but it should be fine until
                 * client caches small amount of data for DoM, which should be
                 * smaller than one BRW RPC and should be able to be
index 46a692c..4c1557f 100644 (file)
@@ -3533,7 +3533,7 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)sizeof(((struct ldlm_extent *)0)->gid));
 
        /* Checks for struct ldlm_inodebits */
-       LASSERTF((int)sizeof(struct ldlm_inodebits) == 16, "found %lld\n",
+       LASSERTF((int)sizeof(struct ldlm_inodebits) == 24, "found %lld\n",
                 (long long)(int)sizeof(struct ldlm_inodebits));
        LASSERTF((int)offsetof(struct ldlm_inodebits, bits) == 0, "found %lld\n",
                 (long long)(int)offsetof(struct ldlm_inodebits, bits));
@@ -3543,6 +3543,11 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct ldlm_inodebits, try_bits));
        LASSERTF((int)sizeof(((struct ldlm_inodebits *)0)->try_bits) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct ldlm_inodebits *)0)->try_bits));
+       LASSERTF((int)offsetof(struct ldlm_inodebits, li_gid) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct ldlm_inodebits, li_gid));
+
+       LASSERTF((int)sizeof(((struct ldlm_inodebits *)0)->li_gid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct ldlm_inodebits *)0)->li_gid));
 
        /* Checks for struct ldlm_flock_wire */
        LASSERTF((int)sizeof(struct ldlm_flock_wire) == 32, "found %lld\n",
index 783d45c..ffff7db 100644 (file)
@@ -194,7 +194,7 @@ run_test sanity "Run sanity with Data-on-MDT files"
 test_sanityn()
 {
        SANITYN_ONLY=${SANITYN_ONLY:-"1 2 4 5 6 7 8 9 10 11 12 14 17 19 20 \
-                                     23 27 39 51a 51c 51d"}
+                                     23 27 39 51a 51c 51d 107"}
        SANITYN_REPEAT=${SANITYN_REPEAT:-1}
        # XXX: to fix 60
        ONLY=$SANITYN_ONLY ONLY_REPEAT=$SANITYN_REPEAT OSC="mdc" DOM="yes" \
index 5a70f3b..58081b4 100755 (executable)
@@ -5295,7 +5295,7 @@ test_106c() {
 }
 run_test 106c "Verify statx attributes mask"
 
-test_107() { # LU-1031
+test_107a() { # LU-1031
        dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
        local gid1=14091995
        local gid2=16022000
@@ -5308,7 +5308,7 @@ test_107() { # LU-1031
        local MULTIPID2=$!
        kill -USR1 $MULTIPID2
        sleep 2
-       if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
+       if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
                error "First grouplock does not block second one"
        else
                echo "First grouplock blocks second one"
@@ -5317,7 +5317,55 @@ test_107() { # LU-1031
        wait $MULTIPID1
        wait $MULTIPID2
 }
-run_test 107 "Basic grouplock conflict"
+run_test 107a "Basic grouplock conflict"
+
+test_107b() {
+       dd if=/dev/zero of=$DIR1/$tfile bs=1M count=10
+       local gid1=14091995
+       local gid2=16022000
+
+       $LFS getstripe $DIR1/$tfile
+
+       multiop_bg_pause $DIR1/$tfile OG${gid1}_g${gid1}c || return 1
+       local MULTIPID1=$!
+       multiop $DIR2/$tfile Or10c &
+       local MULTIPID2=$!
+       sleep 2
+
+       if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
+               error "Grouplock does not block IO"
+       else
+               echo "Grouplock blocks IO"
+       fi
+
+       multiop $DIR2/$tfile OG${gid2}_g${gid2}c &
+       local MULTIPID3=$!
+       sleep 2
+       if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
+               error "First grouplock does not block second one"
+       else
+               echo "First grouplock blocks second one"
+       fi
+
+       kill -USR1 $MULTIPID1
+       sleep 2
+
+       if [[ $(ps h -o comm -p $MULTIPID3) == "" ]]; then
+               error "Second grouplock thread disappeared"
+       fi
+
+       if [[ $(ps h -o comm -p $MULTIPID2) == "" ]]; then
+               error "Second grouplock does not block IO"
+       else
+               echo "Second grouplock blocks IO"
+       fi
+
+       kill -USR1 $MULTIPID3
+       wait $MULTIPID1
+       wait $MULTIPID2
+       wait $MULTIPID3
+}
+run_test 107b "Grouplock is added to the head of waiting list"
 
 log "cleanup: ======================================================"
 
index 189f136..1ec105c 100644 (file)
@@ -1513,6 +1513,7 @@ check_ldlm_inodebits(void)
        CHECK_STRUCT(ldlm_inodebits);
        CHECK_MEMBER(ldlm_inodebits, bits);
        CHECK_MEMBER(ldlm_inodebits, try_bits);
+       CHECK_MEMBER(ldlm_inodebits, li_gid);
 }
 
 static void
index d266c04..5084d96 100644 (file)
@@ -3559,7 +3559,7 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)sizeof(((struct ldlm_extent *)0)->gid));
 
        /* Checks for struct ldlm_inodebits */
-       LASSERTF((int)sizeof(struct ldlm_inodebits) == 16, "found %lld\n",
+       LASSERTF((int)sizeof(struct ldlm_inodebits) == 24, "found %lld\n",
                 (long long)(int)sizeof(struct ldlm_inodebits));
        LASSERTF((int)offsetof(struct ldlm_inodebits, bits) == 0, "found %lld\n",
                 (long long)(int)offsetof(struct ldlm_inodebits, bits));
@@ -3569,6 +3569,11 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct ldlm_inodebits, try_bits));
        LASSERTF((int)sizeof(((struct ldlm_inodebits *)0)->try_bits) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct ldlm_inodebits *)0)->try_bits));
+       LASSERTF((int)offsetof(struct ldlm_inodebits, li_gid) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct ldlm_inodebits, li_gid));
+       LASSERTF((int)sizeof(((struct ldlm_inodebits *)0)->li_gid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct ldlm_inodebits *)0)->li_gid));
+
 
        /* Checks for struct ldlm_flock_wire */
        LASSERTF((int)sizeof(struct ldlm_flock_wire) == 32, "found %lld\n",