Whamcloud - gitweb
b=13103
authorgreen <green>
Sun, 12 Aug 2007 00:38:22 +0000 (00:38 +0000)
committergreen <green>
Sun, 12 Aug 2007 00:38:22 +0000 (00:38 +0000)
r=wangdi,huangwei

Teach ldlm_cli_enqueue_fini that flock locks could disappear immediately after
granting

lustre/ChangeLog
lustre/ldlm/ldlm_request.c

index eb733c3..8476a29 100644 (file)
@@ -69,6 +69,15 @@ Description: reply_lock_interpret crash due to race with it and lock cancel.
 Details    : Do not replay locks that are being cancelled. Do not reference
              locks by their address during replay, just by their handle.
 
+Severity   : normal
+Bugzilla   : 13103
+Frequency  : When flocks are used.
+Description: assertion failure in ldlm_cli_enquque_fini for non NULL lock.
+Details    : Flock locks might destroy just granted lock if it could be merged
+             with another existing flock, this is done in completion handler,
+            so teach ldlm_cli_enquque_fini that this is a valid case for
+            flock locks.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
index 45e8137..f06737c 100644 (file)
@@ -323,7 +323,11 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
 
         lock = ldlm_handle2lock(lockh);
         /* ldlm_cli_enqueue is holding a reference on this lock. */
-        LASSERT(lock != NULL);
+        if (!lock) {
+                LASSERT(type == LDLM_FLOCK);
+                RETURN(-ENOLCK);
+        }
+
         if (rc != ELDLM_OK) {
                 LASSERT(!is_replay);
                 LDLM_DEBUG(lock, "client-side enqueue END (%s)",
@@ -552,7 +556,7 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
                         [DLM_LOCKREQ_OFF]     = sizeof(*body),
                         [DLM_REPLY_REC_OFF]   = lvb_len };
         int is_replay = *flags & LDLM_FL_REPLAY;
-        int req_passed_in = 1, rc;
+        int req_passed_in = 1, rc, err;
         struct ptlrpc_request *req;
         ENTRY;
 
@@ -646,9 +650,16 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
 
         LDLM_DEBUG(lock, "sending request");
         rc = ptlrpc_queue_wait(req);
-        rc = ldlm_cli_enqueue_fini(exp, req, type, policy ? 1 : 0,
-                                   mode, flags, lvb, lvb_len, lvb_swabber,
-                                   lockh, rc);
+        err = ldlm_cli_enqueue_fini(exp, req, type, policy ? 1 : 0,
+                                    mode, flags, lvb, lvb_len, lvb_swabber,
+                                    lockh, rc);
+
+        /* If ldlm_cli_enqueue_fini did not find the lock, we need to free
+         * one reference that we took */
+        if (err == -ENOLCK)
+                LDLM_LOCK_PUT(lock);
+        else
+                rc = err;
 
         if (!req_passed_in && req != NULL) {
                 ptlrpc_req_finished(req);