]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: block request is freezing
authorSage Weil <sage@newdream.net>
Sat, 25 Sep 2010 21:44:50 +0000 (14:44 -0700)
committerSage Weil <sage@newdream.net>
Sat, 25 Sep 2010 21:44:50 +0000 (14:44 -0700)
This prevents a deadlock where:

 - client request releases caps
 - caps release deferred (freezing)
 - request proceeds (freezing)
 - can't revoke caps because they're released (but deferred)
 deadlock!

Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/Locker.cc
src/mds/Server.cc

index 13a60212c91e1984a275f99ef37696dae3519075..c329664aec2fb6cc5c6172ef5f71d3c1fb094d15 100644 (file)
@@ -1797,6 +1797,16 @@ void Locker::_do_null_snapflush(CInode *head_in, client_t client, snapid_t follo
 
 bool Locker::should_defer_client_cap_frozen(CInode *in)
 {
+  /*
+   * This policy needs to be AT LEAST as permissive as allowing a client request
+   * to go forward, or else a client request can release something, the release
+   * gets deferred, but the request gets processed and deadlocks because when the
+   * caps can't get revoked.
+   *
+   * Currently, a request wait if anything locked is freezing (can't
+   * auth_pin), which would avoid any deadlock with cap release.  Thus @in
+   * _MUST_ be in the lock/auth_pin set.
+   */
   return (in->is_freezing() && (in->filelock.is_stable() &&
                                in->authlock.is_stable() &&
                                in->xattrlock.is_stable() &&
index 7475f4749be4a0cbf222141a2bb7e33d911eb8a4..461c3af56d552549b5335ba459f88e7a1804cfcc 100644 (file)
@@ -1799,7 +1799,9 @@ CInode* Server::rdlock_path_pin_ref(MDRequest *mdr, int n,
     }
 
     // auth_pin?
-    if (ref->is_frozen()) {
+    //   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()) {
       dout(7) << "waiting for !frozen/authpinnable on " << *ref << dendl;
       ref->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr));
       return 0;