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 <sage@newdream.net>
This commit is contained in:
Sage Weil 2010-09-27 08:31:34 -07:00
parent ead92c4fbe
commit f1921c3a95
2 changed files with 3 additions and 1 deletions

View File

@ -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);
}
}

View File

@ -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;