Whamcloud - gitweb
LU-9109 ldlm: restore missing newlines in ldlm sysfs files
[fs/lustre-release.git] / lustre / ofd / ofd_dlm.c
index 8c43a06..972d6ec 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
  *
  * lustre/ofd/ofd_dlm.c
  *
- * Author: Mike Pershin <tappro@whamcloud.com>
- * Author: Alex Zhuravlev <bzzz@whamcloud.com>
+ * This file contains OBD Filter Device (OFD) LDLM-related code which is just
+ * intent handling for glimpse lock.
+ *
+ * Author: Andreas Dilger <andreas.dilger@intel.com>
+ * Author: Jinshan Xiong <jinshan.xiong@intel.com>
+ * Author: Alexey Zhuravlev <alexey.zhuravlev@intel.com>
+ * Author: Mikhail Pershin <mike.pershin@intel.com>
  */
 
 #define DEBUG_SUBSYSTEM S_FILTER
@@ -49,6 +50,22 @@ struct ofd_intent_args {
        int                     *liblustre;
 };
 
+/**
+ * OFD interval callback.
+ *
+ * The interval_callback_t is part of interval_iterate_reverse() and is called
+ * for each interval in tree. The OFD interval callback searches for locks
+ * covering extents beyond the given args->size. This is used to decide if LVB
+ * data is outdated.
+ *
+ * \param[in] n                interval node
+ * \param[in] args     intent arguments
+ *
+ * \retval             INTERVAL_ITER_STOP if the interval is lower than
+ *                     file size, caller stops execution
+ * \retval             INTERVAL_ITER_CONT if callback finished successfully
+ *                     and caller may continue execution
+ */
 static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
 {
        struct ldlm_interval     *node = (struct ldlm_interval *)n;
@@ -61,7 +78,7 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
        if (interval_high(n) <= size)
                return INTERVAL_ITER_STOP;
 
-       cfs_list_for_each_entry(lck, &node->li_group, l_sl_policy) {
+       list_for_each_entry(lck, &node->li_group, l_sl_policy) {
                /* Don't send glimpse ASTs to liblustre clients.
                 * They aren't listening for them, and they do
                 * entirely synchronous I/O anyways. */
@@ -87,30 +104,52 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
        return INTERVAL_ITER_CONT;
 }
 
+/**
+ * OFD lock intent policy
+ *
+ * This defines ldlm_namespace::ns_policy interface for OFD.
+ * Intent policy is called when lock has an intent, for OFD that
+ * means glimpse lock and policy fills Lock Value Block (LVB).
+ *
+ * If already granted lock is found it will be placed in \a lockp and
+ * returned back to caller function.
+ *
+ * \param[in] ns        namespace
+ * \param[in,out] lockp         pointer to the lock
+ * \param[in] req_cookie incoming request
+ * \param[in] mode      LDLM mode
+ * \param[in] flags     LDLM flags
+ * \param[in] data      opaque data, not used in OFD policy
+ *
+ * \retval             ELDLM_LOCK_REPLACED if already granted lock was found
+ *                     and placed in \a lockp
+ * \retval             ELDLM_LOCK_ABORTED in other cases except error
+ * \retval             negative value on error
+ */
 int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
-                     void *req_cookie, ldlm_mode_t mode, __u64 flags,
+                     void *req_cookie, enum ldlm_mode mode, __u64 flags,
                      void *data)
 {
-       struct ptlrpc_request           *req = req_cookie;
-       struct ldlm_lock                *lock = *lockp, *l = NULL;
-       struct ldlm_resource            *res = lock->l_resource;
-       ldlm_processing_policy           policy;
-       struct ost_lvb                  *res_lvb, *reply_lvb;
-       struct ldlm_reply               *rep;
-       ldlm_error_t                     err;
-       int                              idx, rc, only_liblustre = 1;
-       __u64                            tmpflags = 0;
-       struct ldlm_interval_tree       *tree;
-       struct ofd_intent_args           arg;
-       __u32                            repsize[3] = {
+       struct ptlrpc_request *req = req_cookie;
+       struct ldlm_lock *lock = *lockp, *l = NULL;
+       struct ldlm_resource *res = lock->l_resource;
+       ldlm_processing_policy policy;
+       struct ost_lvb *res_lvb, *reply_lvb;
+       struct ldlm_reply *rep;
+       enum ldlm_error err;
+       int idx, rc, only_liblustre = 1;
+       struct ldlm_interval_tree *tree;
+       struct ofd_intent_args arg;
+       __u32 repsize[3] = {
                [MSG_PTLRPC_BODY_OFF] = sizeof(struct ptlrpc_body),
                [DLM_LOCKREPLY_OFF]   = sizeof(*rep),
                [DLM_REPLY_REC_OFF]   = sizeof(*reply_lvb)
        };
-       struct ldlm_glimpse_work         gl_work;
-       CFS_LIST_HEAD(gl_list);
+       struct ldlm_glimpse_work gl_work;
+       struct list_head gl_list;
        ENTRY;
 
+       INIT_LIST_HEAD(&gl_list);
        lock->l_lvb_type = LVB_T_OST;
        policy = ldlm_get_processing_policy(res);
        LASSERT(policy != NULL);
@@ -142,8 +181,17 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
 
        LASSERT(ns == ldlm_res_to_ns(res));
        lock_res(res);
-       rc = policy(lock, &tmpflags, 0, &err, NULL);
-       check_res_locked(res);
+
+       /* Check if this is a resend case (MSG_RESENT is set on RPC) and a
+        * lock was found by ldlm_handle_enqueue(); if so no need to grant
+        * it again. */
+       if (flags & LDLM_FL_RESENT) {
+               rc = LDLM_ITER_CONTINUE;
+       } else {
+               __u64 tmpflags = 0;
+               rc = policy(lock, &tmpflags, 0, &err, NULL);
+               check_res_locked(res);
+       }
 
        /* The lock met with no resistance; we're finished. */
        if (rc == LDLM_ITER_CONTINUE) {
@@ -216,11 +264,11 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
        }
 
        /*
-        * This check is for lock taken in ofd_prepare_destroy() that does
+        * This check is for lock taken in ofd_destroy_by_fid() that does
         * not have l_glimpse_ast set. So the logic is: if there is a lock
         * with no l_glimpse_ast set, this object is being destroyed already.
         * Hence, if you are grabbing DLM locks on the server, always set
-        * non-NULL glimpse_ast (e.g., ldlm_request.c:ldlm_glimpse_ast()).
+        * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()).
         */
        if (l->l_glimpse_ast == NULL) {
                /* We are racing with unlink(); just return -ENOENT */
@@ -234,7 +282,7 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
        gl_work.gl_lock = LDLM_LOCK_GET(l);
        /* The glimpse callback is sent to one single extent lock. As a result,
         * the gl_work list is just composed of one element */
-       cfs_list_add_tail(&gl_work.gl_list, &gl_list);
+       list_add_tail(&gl_work.gl_list, &gl_list);
        /* There is actually no need for a glimpse descriptor when glimpsing
         * extent locks */
        gl_work.gl_desc = NULL;
@@ -243,7 +291,7 @@ int ofd_intent_policy(struct ldlm_namespace *ns, struct ldlm_lock **lockp,
 
        rc = ldlm_glimpse_locks(res, &gl_list); /* this will update the LVB */
 
-       if (!cfs_list_empty(&gl_list))
+       if (!list_empty(&gl_list))
                LDLM_LOCK_RELEASE(l);
 
        lock_res(res);