Whamcloud - gitweb
LU-1914 ldlm: add doxygen comments
[fs/lustre-release.git] / lustre / ldlm / ldlm_plain.c
index 5664052..a543519 100644 (file)
  * Author: Phil Schwan <phil@clusterfs.com>
  */
 
+/**
+ * This file contains implementation of PLAIN lock type.
+ *
+ * PLAIN locks are the simplest form of LDLM locking, and are used when
+ * there only needs to be a single lock on a resource. This avoids some
+ * of the complexity of EXTENT and IBITS lock types, but doesn't allow
+ * different "parts" of a resource to be locked concurrently.  Example
+ * use cases for PLAIN locks include locking of MGS configuration logs
+ * and (as of Lustre 2.4) quota records.
+ */
+
 #define DEBUG_SUBSYSTEM S_LDLM
 
 #ifdef __KERNEL__
 #include "ldlm_internal.h"
 
 #ifdef HAVE_SERVER_SUPPORT
+/**
+ * Determine if the lock is compatible with all locks on the queue.
+ *
+ * If \a work_list is provided, conflicting locks are linked there.
+ * If \a work_list is not provided, we exit this function on first conflict.
+ *
+ * \retval 0 if there are conflicting locks in the \a queue
+ * \retval 1 if the lock is compatible to all locks in \a queue
+ */
 static inline int
 ldlm_plain_compat_queue(cfs_list_t *queue, struct ldlm_lock *req,
                         cfs_list_t *work_list)
@@ -67,15 +87,18 @@ ldlm_plain_compat_queue(cfs_list_t *queue, struct ldlm_lock *req,
         cfs_list_for_each(tmp, queue) {
                 lock = cfs_list_entry(tmp, struct ldlm_lock, l_res_link);
 
-                if (req == lock)
-                        RETURN(compat);
+               /* We stop walking the queue if we hit ourselves so we don't
+                * take conflicting locks enqueued after us into account,
+                * or we'd wait forever. */
+               if (req == lock)
+                       RETURN(compat);
 
-                 /* last lock in mode group */
-                 tmp = &cfs_list_entry(lock->l_sl_mode.prev,
-                                       struct ldlm_lock,
-                                       l_sl_mode)->l_res_link;
+               /* Advance loop cursor to last lock of mode group. */
+               tmp = &cfs_list_entry(lock->l_sl_mode.prev,
+                                     struct ldlm_lock,
+                                     l_sl_mode)->l_res_link;
 
-                 if (lockmode_compat(lock->l_req_mode, req_mode))
+               if (lockmode_compat(lock->l_req_mode, req_mode))
                         continue;
 
                 if (!work_list)
@@ -83,8 +106,8 @@ ldlm_plain_compat_queue(cfs_list_t *queue, struct ldlm_lock *req,
 
                 compat = 0;
 
-                /* add locks of the mode group to @work_list as
-                 * blocking locks for @req */
+               /* Add locks of the mode group to \a work_list as
+                * blocking locks for \a req. */
                 if (lock->l_blocking_ast)
                         ldlm_add_ast_work_item(lock, req, work_list);
 
@@ -102,13 +125,21 @@ ldlm_plain_compat_queue(cfs_list_t *queue, struct ldlm_lock *req,
         RETURN(compat);
 }
 
-/* If first_enq is 0 (ie, called from ldlm_reprocess_queue):
+/**
+ * Process a granting attempt for plain lock.
+ * Must be called with ns lock held.
+ *
+ * This function looks for any conflicts for \a lock in the granted or
+ * waiting queues. The lock is granted if no conflicts are found in
+ * either queue.
+ *
+ * If \a first_enq is 0 (ie, called from ldlm_reprocess_queue):
  *   - blocking ASTs have already been sent
- *   - must call this function with the resource lock held
  *
- * If first_enq is 1 (ie, called from ldlm_lock_enqueue):
- *   - blocking ASTs have not been sent
- *   - must call this function with the resource lock held */
+ * If \a first_enq is 1 (ie, called from ldlm_lock_enqueue):
+ *   - blocking ASTs have not been sent yet, so list of conflicting locks
+ *     would be collected and ASTs sent.
+ */
 int ldlm_process_plain_lock(struct ldlm_lock *lock, __u64 *flags,
                            int first_enq, ldlm_error_t *err,
                            cfs_list_t *work_list)