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>
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)",
[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;
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);