Whamcloud - gitweb
LU-6179 llite: Implement ladvise lockahead
[fs/lustre-release.git] / lustre / ldlm / ldlm_lock.c
index 6e4663f..a480054 100644 (file)
@@ -44,6 +44,9 @@
 
 #include "ldlm_internal.h"
 
+struct kmem_cache *ldlm_glimpse_work_kmem;
+EXPORT_SYMBOL(ldlm_glimpse_work_kmem);
+
 /* lock types */
 char *ldlm_lockname[] = {
        [0] = "--",
@@ -2138,8 +2141,9 @@ int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
                rc = 1;
 
        LDLM_LOCK_RELEASE(lock);
-
-       if ((gl_work->gl_flags & LDLM_GL_WORK_NOFREE) == 0)
+       if (gl_work->gl_flags & LDLM_GL_WORK_SLAB_ALLOCATED)
+               OBD_SLAB_FREE_PTR(gl_work, ldlm_glimpse_work_kmem);
+       else
                OBD_FREE_PTR(gl_work);
 
        RETURN(rc);
@@ -2528,14 +2532,21 @@ int ldlm_export_cancel_locks(struct obd_export *exp)
               "left on hash table %d.\n", exp, ecl.ecl_loop,
               atomic_read(&exp->exp_lock_hash->hs_count));
 
+       if (ecl.ecl_loop > 0 &&
+           atomic_read(&exp->exp_lock_hash->hs_count) == 0 &&
+           exp->exp_obd->obd_stopping)
+               ldlm_reprocess_recovery_done(exp->exp_obd->obd_namespace);
+
        return ecl.ecl_loop;
 }
 
 /**
  * Downgrade an exclusive lock.
  *
- * A fast variant of ldlm_lock_convert for convertion of exclusive
- * locks. The convertion is always successful.
+ * A fast variant of ldlm_lock_convert for convertion of exclusive locks. The
+ * convertion may fail if lock was canceled before downgrade, but it doesn't
+ * indicate any problem, because such lock has no reader or writer, and will
+ * be released soon.
  * Used by Commit on Sharing (COS) code.
  *
  * \param lock A lock to convert
@@ -2543,25 +2554,34 @@ int ldlm_export_cancel_locks(struct obd_export *exp)
  */
 void ldlm_lock_downgrade(struct ldlm_lock *lock, enum ldlm_mode new_mode)
 {
-        ENTRY;
+       ENTRY;
 
-        LASSERT(lock->l_granted_mode & (LCK_PW | LCK_EX));
-        LASSERT(new_mode == LCK_COS);
+       LASSERT(new_mode == LCK_COS);
 
-        lock_res_and_lock(lock);
-        ldlm_resource_unlink_lock(lock);
-        /*
-         * Remove the lock from pool as it will be added again in
-         * ldlm_grant_lock() called below.
-         */
-        ldlm_pool_del(&ldlm_lock_to_ns(lock)->ns_pool, lock);
+       lock_res_and_lock(lock);
 
-        lock->l_req_mode = new_mode;
-        ldlm_grant_lock(lock, NULL);
-        unlock_res_and_lock(lock);
-        ldlm_reprocess_all(lock->l_resource);
+       if (!(lock->l_granted_mode & (LCK_PW | LCK_EX))) {
+               unlock_res_and_lock(lock);
 
-        EXIT;
+               LASSERT(lock->l_granted_mode == LCK_MINMODE);
+               LDLM_DEBUG(lock, "lock was canceled before downgrade");
+               RETURN_EXIT;
+       }
+
+       ldlm_resource_unlink_lock(lock);
+       /*
+        * Remove the lock from pool as it will be added again in
+        * ldlm_grant_lock() called below.
+        */
+       ldlm_pool_del(&ldlm_lock_to_ns(lock)->ns_pool, lock);
+       lock->l_req_mode = new_mode;
+       ldlm_grant_lock(lock, NULL);
+
+       unlock_res_and_lock(lock);
+
+       ldlm_reprocess_all(lock->l_resource);
+
+       EXIT;
 }
 EXPORT_SYMBOL(ldlm_lock_downgrade);
 
@@ -2727,9 +2747,19 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 {
         va_list args;
         struct obd_export *exp = lock->l_export;
-        struct ldlm_resource *resource = lock->l_resource;
+       struct ldlm_resource *resource = NULL;
         char *nid = "local";
 
+       /* on server-side resource of lock doesn't change */
+       if ((lock->l_flags & LDLM_FL_NS_SRV) != 0) {
+               if (lock->l_resource != NULL)
+                       resource = ldlm_resource_getref(lock->l_resource);
+       } else if (spin_trylock(&lock->l_lock)) {
+               if (lock->l_resource != NULL)
+                       resource = ldlm_resource_getref(lock->l_resource);
+               spin_unlock(&lock->l_lock);
+       }
+
         va_start(args, fmt);
 
         if (exp && exp->exp_connection) {
@@ -2806,7 +2836,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
        case LDLM_IBITS:
                libcfs_debug_vmsg2(msgdata, fmt, args,
                        " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
-                       "res: "DLDLMRES" bits %#llx rrc: %d type: %s "
+                       "res: "DLDLMRES" bits %#llx/%#llx rrc: %d type: %s "
                        "flags: %#llx nid: %s remote: %#llx expref: %d "
                        "pid: %u timeout: %lu lvb_type: %d\n",
                        ldlm_lock_to_ns_name(lock),
@@ -2817,6 +2847,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
                        ldlm_lockname[lock->l_req_mode],
                        PLDLMRES(resource),
                        lock->l_policy_data.l_inodebits.bits,
+                       lock->l_policy_data.l_inodebits.try_bits,
                        atomic_read(&resource->lr_refcount),
                        ldlm_typename[resource->lr_type],
                        lock->l_flags, nid, lock->l_remote_handle.cookie,
@@ -2847,5 +2878,6 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
                break;
        }
        va_end(args);
+       ldlm_resource_putref(resource);
 }
 EXPORT_SYMBOL(_ldlm_lock_debug);