From 8f0bb839ea91161471de6947eaebb4a3d7a58fdc Mon Sep 17 00:00:00 2001 From: green Date: Sat, 11 Aug 2007 23:24:41 +0000 Subject: [PATCH] b=13103 r=huangwei,wangdi Teach ldlm_cli_enqueue_fini that flock locks could disappear immediatelly after being granted. --- 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 b1ec220..a03d5b9 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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. + -------------------------------------------------------------------------------- diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 3bc0fdd..bb2d2aa 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -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); -- 1.8.3.1