From aa2c223fa1ef786b447398d430e7a10411351898 Mon Sep 17 00:00:00 2001 From: green Date: Sun, 12 Aug 2007 00:38:22 +0000 Subject: [PATCH] b=13103 r=wangdi,huangwei Teach ldlm_cli_enqueue_fini that flock locks could disappear immediately after granting --- lustre/ChangeLog | 9 +++++++++ lustre/ldlm/ldlm_request.c | 21 ++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index eb733c3..8476a29 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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. diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 45e8137..f06737c 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -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); -- 1.8.3.1