From 479875b80a1ef3349d108ffaa11d257dfb18d0c6 Mon Sep 17 00:00:00 2001 From: shaver <shaver> Date: Fri, 19 Dec 2003 14:17:00 +0000 Subject: [PATCH] b=2420: don't acquire a duplicate lock when processing a resent GETATTR, just grab the dchild directly and sample the data. Fixes recovery-small.sh. r=phik,buffalo --- lustre/mds/handler.c | 45 +++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 9430b37c97..1bd9bba31e 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -608,7 +608,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req, struct obd_ucred uc; struct lustre_handle parent_lockh; int namesize; - int rc = 0, cleanup_phase = 0; + int rc = 0, cleanup_phase = 0, resent_req = 0; char *name; ENTRY; @@ -670,12 +670,33 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req, } #endif - rc = mds_get_parent_child_locked(obd, &obd->u.mds, &body->fid1, - &parent_lockh, &dparent, LCK_PR, - name, namesize, child_lockh, - &dchild, LCK_PR); - if (rc) - GOTO(cleanup, rc); + if (child_lockh->cookie != 0) { + LASSERT(lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT); + resent_req = 1; + } + + if (resent_req == 0) { + rc = mds_get_parent_child_locked(obd, &obd->u.mds, &body->fid1, + &parent_lockh, &dparent, + LCK_PR, name, namesize, + child_lockh, &dchild, LCK_PR); + if (rc) + GOTO(cleanup, rc); + } else { + struct ldlm_lock *granted_lock; + struct ll_fid child_fid; + struct ldlm_resource *res; + DEBUG_REQ(D_DLMTRACE, req, "resent, not enqueuing new locks"); + granted_lock = ldlm_handle2lock(child_lockh); + LASSERT(granted_lock); + + res = granted_lock->l_resource; + child_fid.id = res->lr_name.name[0]; + child_fid.generation = res->lr_name.name[1]; + dchild = mds_fid2dentry(&obd->u.mds, &child_fid, NULL); + LASSERT(dchild); + LDLM_LOCK_PUT(granted_lock); + } cleanup_phase = 2; /* dchild, dparent, locks */ @@ -702,11 +723,13 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req, cleanup: switch (cleanup_phase) { case 2: - if (rc && dchild->d_inode) - ldlm_lock_decref(child_lockh, LCK_PR); - ldlm_lock_decref(&parent_lockh, LCK_PR); + if (resent_req == 0) { + if (rc && dchild->d_inode) + ldlm_lock_decref(child_lockh, LCK_PR); + ldlm_lock_decref(&parent_lockh, LCK_PR); + l_dput(dparent); + } l_dput(dchild); - l_dput(dparent); case 1: pop_ctxt(&saved, &obd->obd_ctxt, &uc); default: ; -- GitLab