From f1921c3a952726e025773979a7597de793897058 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 27 Sep 2010 08:31:34 -0700 Subject: [PATCH] mds: don't block request on freezing if we're already auth_pinned. If we already auth_pinned, we're past the gates; don't stop on freezable. This screws up xlock: the lock moves to PREXLOCK state, but the request that would normally xlock it gets deferred because of a racing freezing of the tree. Then the PREXLOCK gather kicks in and badness happens. Signed-off-by: Sage Weil --- src/mds/Locker.cc | 1 + src/mds/Server.cc | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index c329664aec2fb..77668053bbc32 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -3135,6 +3135,7 @@ void Locker::simple_xlock(SimpleLock *lock) if (!gather) { lock->set_state(LOCK_PREXLOCK); + assert("shouldn't be called if we are already xlockable" == 0); } } diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 461c3af56d552..7466e1c08aed9 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1801,7 +1801,8 @@ CInode* Server::rdlock_path_pin_ref(MDRequest *mdr, int n, // auth_pin? // do NOT proceed if freezing, as cap release may defer in that case, and // we could deadlock when we try to lock @ref. - if (ref->is_frozen() || ref->is_freezing()) { + // if we're already auth_pinned, continue; the release has already been processed. + if (ref->is_frozen() || (ref->is_freezing() && !mdr->is_auth_pinned(ref))) { dout(7) << "waiting for !frozen/authpinnable on " << *ref << dendl; ref->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr)); return 0; -- 2.39.5