]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: do not double-queue file recovery in eval_gather
authorSage Weil <sage@inktank.com>
Fri, 7 Jun 2013 04:38:56 +0000 (21:38 -0700)
committerGreg Farnum <greg@inktank.com>
Wed, 9 Oct 2013 20:47:07 +0000 (13:47 -0700)
This fixes a specific case of double-queuing seen in #4832:

 - client goes stale, inode marked NEEDSRECOVER
 - eval does sync, queued, -> RECOVERING
 - client resumes
 - client goes stale (again), inode marked NEEDSRECOVER
 - eval_gather queues *again*

Note that a cursory look at the recovery code makes me think this needs
a much more serious overhaul.  In particular, I don't think we should
be triggering recovery when transitioning *from* a stable state, but
explicitly when we are flagged, or when gathering.  We should probably
also hold a wrlock over the recovery period and remove the force_wrlock
kludge from the final size check.  Opened ticket #5268.

Signed-off-by: Sage Weil <sage@inktank.com>
(cherry picked from commit a08d62045657713bf0a5372bf14136082ec3b17e)
Reviewed-by: Greg Farnum <greg@inktank.com>
src/mds/Locker.cc

index c5ddb92d93e3e448a50bde3c636ae0aea5d99968..fd46be09320620e79176dfa507b1c80b79083566 100644 (file)
@@ -644,15 +644,14 @@ void Locker::eval_gather(SimpleLock *lock, bool first, bool *pneed_issue, list<C
 
     if (lock->get_sm() == &sm_filelock) {
       assert(in);
-      if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
+      if (in->state_test(CInode::STATE_RECOVERING)) {
+       dout(7) << "eval_gather finished gather, but still recovering" << dendl;
+      } else if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
        dout(7) << "eval_gather finished gather, but need to recover" << dendl;
        mds->mdcache->queue_file_recover(in);
        mds->mdcache->do_file_recover();
       }
-      if (in->state_test(CInode::STATE_RECOVERING)) {
-       dout(7) << "eval_gather finished gather, but still recovering" << dendl;
-       return;
-      }
+      return;
     }
 
     if (!lock->get_parent()->is_auth()) {