]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix bounding frag rstat/fragstat update during import
authorSage Weil <sage@newdream.net>
Thu, 23 Sep 2010 17:00:07 +0000 (10:00 -0700)
committerSage Weil <sage@newdream.net>
Thu, 23 Sep 2010 23:44:47 +0000 (16:44 -0700)
Be careful about when we update bounding dirfrag info during an import.  If
the lock is in a MIX state, we do NOT want to update, since the inode
auth doesn't know jack (unless they are also dirfrag auth, in which case
we'll find out when we unscatter anyway).

Fixes fix 9d81f9d6.

src/mds/CInode.cc

index cea9981f38c4a204eaed3a6e2e5db49f2095a2db..14079dffbca644543e65cbadf71970cc6e91bdfd 100644 (file)
@@ -2289,20 +2289,38 @@ void CInode::decode_import(bufferlist::iterator& p,
       ::decode(fg, q);
       CDir *dir = get_dirfrag(fg);
       assert(dir);  // we should have all bounds open
-      if (!dir->is_auth()) {
-       ::decode(dir->fnode.fragstat, q);
-       ::decode(dir->fnode.accounted_fragstat, q);
-       ::decode(dir->fnode.rstat, q);
-       ::decode(dir->fnode.accounted_rstat, q);
-       dout(10) << " took fragstat/rstat info for " << *dir << dendl;
-      } else {
-       dout(10) << " skipped fragstat/rstat info for " << *dir << dendl;
+
+      // Only take the remote's fragstat/rstat if we are non-auth for
+      // this dirfrag AND the lock is NOT in a scattered (MIX) state.
+      // We know lock is stable, and MIX is the only state in which
+      // the inode auth (who sent us this data) may not have the best
+      // info.
+
+      // HMM: Are there cases where dir->is_auth() is an insufficient
+      // check because the dirfrag is under migration?  That implies
+      // it is frozen (and in a SYNC or LOCK state).  FIXME.
+
+      if (dir->is_auth() ||
+         filelock.get_state() == LOCK_MIX) {
+       dout(10) << " skipped fragstat info for " << *dir << dendl;
        frag_info_t f;
-       nest_info_t n;
        ::decode(f, q);
        ::decode(f, q);
+      } else {
+       ::decode(dir->fnode.fragstat, q);
+       ::decode(dir->fnode.accounted_fragstat, q);
+       dout(10) << " took fragstat info for " << *dir << dendl;
+      }
+      if (dir->is_auth() ||
+         nestlock.get_state() == LOCK_MIX) {
+       dout(10) << " skipped rstat info for " << *dir << dendl;
+       nest_info_t n;
        ::decode(n, q);
        ::decode(n, q);
+      } else {
+       ::decode(dir->fnode.rstat, q);
+       ::decode(dir->fnode.accounted_rstat, q);
+       dout(10) << " took rstat info for " << *dir << dendl;
       }
     }
   }