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>
if (!gather) {
lock->set_state(LOCK_PREXLOCK);
+ assert("shouldn't be called if we are already xlockable" == 0);
}
}
// 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;