Whamcloud - gitweb
LU-19098 hsm: don't print progname twice with lhsmtool
[fs/lustre-release.git] / lustre / ofd / ofd_dlm.c
index c18ade0..7d075b7 100644 (file)
@@ -1,35 +1,14 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
+// SPDX-License-Identifier: GPL-2.0
+
 /*
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2015, Intel Corporation.
+ * Copyright (c) 2012, 2017, Intel Corporation.
  */
+
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/ofd/ofd_dlm.c
  *
  * This file contains OBD Filter Device (OFD) LDLM-related code which is just
  * intent handling for glimpse lock.
@@ -51,25 +30,6 @@ struct ofd_intent_args {
        int                     error;
 };
 
-int ofd_dlm_init(void)
-{
-       ldlm_glimpse_work_kmem = kmem_cache_create("ldlm_glimpse_work_kmem",
-                                            sizeof(struct ldlm_glimpse_work),
-                                            0, 0, NULL);
-       if (ldlm_glimpse_work_kmem == NULL)
-               return -ENOMEM;
-       else
-               return 0;
-}
-
-void ofd_dlm_exit(void)
-{
-       if (ldlm_glimpse_work_kmem) {
-               kmem_cache_destroy(ldlm_glimpse_work_kmem);
-               ldlm_glimpse_work_kmem = NULL;
-       }
-}
-
 /**
  * OFD interval callback.
  *
@@ -117,39 +77,20 @@ void ofd_dlm_exit(void)
  * \param[in] n                interval node
  * \param[in,out] args intent arguments, gl work list for identified locks
  *
- * \retval             INTERVAL_ITER_STOP if the interval is lower than
+ * \retval             true if the interval is lower than
  *                     file size, caller stops execution
- * \retval             INTERVAL_ITER_CONT if callback finished successfully
+ * \retval             false if callback finished successfully
  *                     and caller may continue execution
  */
-static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
+static bool ofd_intent_cb(struct ldlm_lock *lock, struct ofd_intent_args *arg)
 {
-       struct ldlm_interval     *node = (struct ldlm_interval *)n;
-       struct ofd_intent_args   *arg = args;
        __u64                     size = arg->size;
-       struct ldlm_lock         *victim_lock = NULL;
-       struct ldlm_lock         *lck;
        struct ldlm_glimpse_work *gl_work = NULL;
-       int rc = 0;
+       bool rc;
 
        /* If the interval is lower than the current file size, just break. */
-       if (interval_high(n) <= size)
-               GOTO(out, rc = INTERVAL_ITER_STOP);
-
-       /* Find the 'victim' lock from this interval */
-       list_for_each_entry(lck, &node->li_group, l_sl_policy) {
-
-               victim_lock = LDLM_LOCK_GET(lck);
-
-               /* the same policy group - every lock has the
-                * same extent, so needn't do it any more */
-               break;
-       }
-
-       /* l_export can be null in race with eviction - In that case, we will
-        * not find any locks in this interval */
-       if (!victim_lock)
-               GOTO(out, rc = INTERVAL_ITER_CONT);
+       if (lock->l_policy_data.l_extent.end <= size)
+               GOTO(out, rc = true);
 
        /*
         * This check is for lock taken in ofd_destroy_by_fid() that does
@@ -158,55 +99,54 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
         * Hence, if you are grabbing DLM locks on the server, always set
         * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()).
         */
-       if (victim_lock->l_glimpse_ast == NULL) {
-               LDLM_DEBUG(victim_lock, "no l_glimpse_ast");
+       if (lock->l_glimpse_ast == NULL) {
+               LDLM_DEBUG(lock, "no l_glimpse_ast");
                arg->no_glimpse_ast = true;
-               GOTO(out_release, rc = INTERVAL_ITER_STOP);
+               GOTO(out, rc = true);
        }
 
        /* If NO_EXPANSION is not set, this is an active lock, and we don't need
         * to glimpse any further once we've glimpsed the client holding this
-        * lock.  So set us up to stop.  See comment above this function. */
-       if (!(victim_lock->l_flags & LDLM_FL_NO_EXPANSION))
-               rc = INTERVAL_ITER_STOP;
+        * lock.  So set us up to stop.  See comment above this function.
+        */
+       if (!(lock->l_flags & LDLM_FL_NO_EXPANSION))
+               rc = true;
        else
-               rc = INTERVAL_ITER_CONT;
+               rc = false;
 
        /* Check to see if we're already set up to send a glimpse to this
         * client; if so, don't add this lock to the glimpse list - We need
         * only glimpse each client once. (And if we know that client holds
         * an active lock, we can stop glimpsing.  So keep the rc set in the
-        * check above.) */
+        * check above.)
+        */
        list_for_each_entry(gl_work, &arg->gl_list, gl_list) {
-               if (gl_work->gl_lock->l_export == victim_lock->l_export)
-                       GOTO(out_release, rc);
+               if (gl_work->gl_lock->l_export == lock->l_export)
+                       GOTO(out, rc);
        }
 
-       if (!OBD_FAIL_CHECK(OBD_FAIL_OST_GL_WORK_ALLOC))
+       if (!CFS_FAIL_CHECK(OBD_FAIL_OST_GL_WORK_ALLOC))
                OBD_SLAB_ALLOC_PTR_GFP(gl_work, ldlm_glimpse_work_kmem,
                                       GFP_ATOMIC);
 
        if (!gl_work) {
                arg->error = -ENOMEM;
-               GOTO(out_release, rc = INTERVAL_ITER_STOP);
+               GOTO(out, rc = true);
        }
 
        /* Populate the gl_work structure. */
-       gl_work->gl_lock = victim_lock;
+       gl_work->gl_lock = ldlm_lock_get(lock);
        list_add_tail(&gl_work->gl_list, &arg->gl_list);
        /* There is actually no need for a glimpse descriptor when glimpsing
-        * extent locks */
+        * extent locks
+        */
        gl_work->gl_desc = NULL;
        /* This tells ldlm_work_gl_ast_lock this was allocated from a slab and
-        * must be freed in a slab-aware manner. */
+        * must be freed in a slab-aware manner.
+        */
        gl_work->gl_flags = LDLM_GL_WORK_SLAB_ALLOCATED;
 
        GOTO(out, rc);
-
-out_release:
-       /* If the victim doesn't go on the glimpse list, we must release it */
-       LDLM_LOCK_RELEASE(victim_lock);
-
 out:
        return rc;
 }
@@ -232,9 +172,10 @@ out:
  * \retval             ELDLM_LOCK_ABORTED in other cases except error
  * \retval             negative errno on error
  */
-int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
-                     void *req_cookie, enum ldlm_mode mode, __u64 flags,
-                     void *data)
+
+int ofd_intent_policy(const struct lu_env *env, struct ldlm_namespace *ns,
+                     struct ldlm_lock **lockp, void *req_cookie,
+                     enum ldlm_mode mode, __u64 flags, void *data)
 {
        struct ptlrpc_request *req = req_cookie;
        struct ldlm_lock *lock = *lockp;
@@ -254,6 +195,11 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
        struct ldlm_glimpse_work *pos, *tmp;
        ENTRY;
 
+       /* update stats for intent in intent policy */
+       if (ptlrpc_req2svc(req)->srv_stats != NULL)
+               lprocfs_counter_incr(ptlrpc_req2svc(req)->srv_stats,
+                                    PTLRPC_LAST_CNTR + LDLM_GLIMPSE_ENQUEUE);
+
        INIT_LIST_HEAD(&arg.gl_list);
        arg.no_glimpse_ast = false;
        arg.error = 0;
@@ -280,9 +226,9 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
         */
 
        if (flags & LDLM_FL_BLOCK_NOWAIT) {
-               OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_AGL_DELAY, 5);
+               CFS_FAIL_TIMEOUT(OBD_FAIL_LDLM_AGL_DELAY, 5);
 
-               if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_AGL_NOLOCK))
+               if (CFS_FAIL_CHECK(OBD_FAIL_LDLM_AGL_NOLOCK))
                        RETURN(ELDLM_LOCK_ABORTED);
        }
 
@@ -302,7 +248,7 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
 
        /* The lock met with no resistance; we're finished. */
        if (rc == LDLM_ITER_CONTINUE) {
-               if (OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_GLIMPSE, 2)) {
+               if (CFS_FAIL_TIMEOUT(OBD_FAIL_LDLM_GLIMPSE, 2)) {
                        ldlm_resource_unlink_lock(lock);
                        err = ELDLM_LOCK_ABORTED;
                } else {
@@ -338,11 +284,18 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
        /* Check for PW locks beyond the size in the LVB, build the list
         * of locks to glimpse (arg.gl_list) */
        for (idx = 0; idx < LCK_MODE_NUM; idx++) {
+               struct ldlm_lock *lck;
+
                tree = &res->lr_itree[idx];
                if (tree->lit_mode == LCK_PR)
                        continue;
 
-               interval_iterate_reverse(tree->lit_root, ofd_intent_cb, &arg);
+               for (lck = extent_last(tree);
+                    lck;
+                    lck = extent_prev(lck))
+                       if (ofd_intent_cb(lck, &arg))
+                               break;
+
                if (arg.error) {
                        unlock_res(res);
                        GOTO(out, rc = arg.error);
@@ -372,7 +325,7 @@ out:
         * must clean up.  Usually due to a race with unlink.*/
        list_for_each_entry_safe(pos, tmp, &arg.gl_list, gl_list) {
                list_del(&pos->gl_list);
-               LDLM_LOCK_RELEASE(pos->gl_lock);
+               ldlm_lock_put(pos->gl_lock);
                OBD_SLAB_FREE_PTR(pos, ldlm_glimpse_work_kmem);
        }