Whamcloud - gitweb
b=13103
authorgreen <green>
Sat, 11 Aug 2007 23:24:41 +0000 (23:24 +0000)
committergreen <green>
Sat, 11 Aug 2007 23:24:41 +0000 (23:24 +0000)
r=huangwei,wangdi

Teach ldlm_cli_enqueue_fini that flock locks could disappear immediatelly after
being granted.

lustre/ChangeLog
lustre/ldlm/ldlm_request.c

index b1ec220..a03d5b9 100644 (file)
@@ -171,6 +171,15 @@ Frequency  : rare
 Description: Oops in read and write path when failing to allocate lock.
 Details    : Check if lock allocation failed and return error back.
 
+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.
+
 
 --------------------------------------------------------------------------------
 
index 3bc0fdd..bb2d2aa 100644 (file)
@@ -317,7 +317,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)",
@@ -536,7 +540,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;
 
@@ -632,9 +636,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, einfo->ei_type, policy ? 1 : 0,
-                                   einfo->ei_mode, flags, lvb, lvb_len,
-                                   lvb_swabber, lockh, rc);
+        err = ldlm_cli_enqueue_fini(exp, req, einfo->ei_type, policy ? 1 : 0,
+                                    einfo->ei_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);