]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't block request on freezing if we're already auth_pinned.
authorSage Weil <sage@newdream.net>
Mon, 27 Sep 2010 15:31:34 +0000 (08:31 -0700)
committerSage Weil <sage@newdream.net>
Mon, 27 Sep 2010 15:31:34 +0000 (08:31 -0700)
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>
src/mds/Locker.cc
src/mds/Server.cc

index c329664aec2fb6cc5c6172ef5f71d3c1fb094d15..77668053bbc32312fc44cf7291e1f5ed339ba391 100644 (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);
   }
 }
 
index 461c3af56d552549b5335ba459f88e7a1804cfcc..7466e1c08aed9070d77d61892e8837ca358294eb 100644 (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;