]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix open undef dirfrags
authorYan, Zheng <zheng.z.yan@intel.com>
Wed, 15 Jan 2014 04:13:52 +0000 (12:13 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Mon, 17 Feb 2014 01:37:51 +0000 (09:37 +0800)
Undef inode may contain a undef dirfrag (*). When undef inode is
opened, we should force fragment the undef dirfrag (*). because
we may open other dirfrags later, the undef dirfrag (*) will
overlap with them.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/CDir.cc
src/mds/CDir.h
src/mds/MDCache.cc
src/mds/MDCache.h

index f0dc962f1f9c02ac574e953d80c95b1104526915..99bbc841e33602c62ce8c405042511a9827fc6cd 100644 (file)
@@ -1522,6 +1522,8 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
     }
   }
 
+  list<CInode*> undef_inodes;
+
   // purge stale snaps?
   // only if we have past_parents open!
   bool purged_any = false;
@@ -1636,10 +1638,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
        if (in) {
          dout(12) << "_fetched  had dentry " << *dn << dendl;
          if (in->state_test(CInode::STATE_REJOINUNDEF)) {
-           assert(cache->mds->is_rejoin());
-           assert(in->vino() == vinodeno_t(inode.ino, last));
-           in->state_clear(CInode::STATE_REJOINUNDEF);
-           cache->opened_undef_inode(in);
+           undef_inodes.push_back(in);
            undef_inode = true;
          }
        } else
@@ -1749,6 +1748,15 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   // mark complete, !fetching
   mark_complete();
   state_clear(STATE_FETCHING);
+
+  // open & force frags
+  while (!undef_inodes.empty()) {
+    CInode *in = undef_inodes.front();
+    undef_inodes.pop_front();
+    in->state_clear(CInode::STATE_REJOINUNDEF);
+    cache->opened_undef_inode(in);
+  }
+
   auth_unpin(this);
 
   // kick waiters
index 30c01822f6a078e7801f4178783d05fa42fa8bc7..02e76d8c87dfadee0e6ae7b7e8d9b803e627a4e6 100644 (file)
@@ -131,7 +131,8 @@ public:
   static const unsigned MASK_STATE_FRAGMENT_KEPT = 
   (STATE_DIRTY|
    STATE_EXPORTBOUND |
-   STATE_IMPORTBOUND);
+   STATE_IMPORTBOUND |
+   STATE_REJOINUNDEF);
 
   // -- rep spec --
   static const int REP_NONE =     0;
index 3a16ae7d5485e021646254e518996146c9df9c53..96a17154fd0591bfff4efd4bbb0a6d16e1d2faf9 100644 (file)
@@ -5548,19 +5548,8 @@ bool MDCache::open_undef_inodes_dirfrags()
     CInode *diri = dir->get_inode();
     if (diri->state_test(CInode::STATE_REJOINUNDEF))
       continue;
-    if (dir->state_test(CDir::STATE_REJOINUNDEF) && dir->get_frag() == frag_t()) {
-      rejoin_undef_dirfrags.erase(dir);
-      dir->state_clear(CDir::STATE_REJOINUNDEF);
-      diri->force_dirfrags();
-      list<CDir*> ls;
-      diri->get_dirfrags(ls);
-      for (list<CDir*>::iterator q = ls.begin(); q != ls.end(); ++q) {
-       rejoin_undef_dirfrags.insert(*q);
-       (*q)->state_set(CDir::STATE_REJOINUNDEF);
-       (*q)->fetch(gather.new_sub());
-      }
-      continue;
-    }
+    if (dir->state_test(CDir::STATE_REJOINUNDEF))
+      assert(diri->dirfragtree.is_leaf(dir->get_frag()));
     dir->fetch(gather.new_sub());
   }
   assert(gather.has_subs());
@@ -5568,6 +5557,23 @@ bool MDCache::open_undef_inodes_dirfrags()
   return true;
 }
 
+void MDCache::opened_undef_inode(CInode *in) {
+  dout(10) << "opened_undef_inode " << *in << dendl;
+  rejoin_undef_inodes.erase(in);
+  if (in->is_dir()) {
+    if (in->has_dirfrags() && !in->dirfragtree.is_leaf(frag_t())) {
+      CDir *dir = in->get_dirfrag(frag_t());
+      assert(dir);
+      rejoin_undef_dirfrags.erase(dir);
+      in->force_dirfrags();
+      list<CDir*> ls;
+      in->get_dirfrags(ls);
+      for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p)
+       rejoin_undef_dirfrags.insert(*p);
+    }
+  }
+}
+
 void MDCache::finish_snaprealm_reconnect(client_t client, SnapRealm *realm, snapid_t seq)
 {
   if (seq < realm->get_newest_seq()) {
@@ -8201,25 +8207,9 @@ void MDCache::_open_ino_traverse_dir(inodeno_t ino, open_ino_info_t& info, int r
 
 void MDCache::_open_ino_fetch_dir(inodeno_t ino, MMDSOpenIno *m, CDir *dir)
 {
-  if (dir->state_test(CDir::STATE_REJOINUNDEF) && dir->get_frag() == frag_t()) {
-    rejoin_undef_dirfrags.erase(dir);
-    dir->state_clear(CDir::STATE_REJOINUNDEF);
-
-    CInode *diri = dir->get_inode();
-    diri->force_dirfrags();
-    list<CDir*> ls;
-    diri->get_dirfrags(ls);
-
-    C_GatherBuilder gather(g_ceph_context, _open_ino_get_waiter(ino, m));
-    for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
-      rejoin_undef_dirfrags.insert(*p);
-      (*p)->state_set(CDir::STATE_REJOINUNDEF);
-      (*p)->fetch(gather.new_sub());
-    }
-    assert(gather.has_subs());
-    gather.activate();
-  } else
-    dir->fetch(_open_ino_get_waiter(ino, m));
+  if (dir->state_test(CDir::STATE_REJOINUNDEF))
+    assert(dir->get_inode()->dirfragtree.is_leaf(dir->get_frag()));
+  dir->fetch(_open_ino_get_waiter(ino, m));
 }
 
 int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
index 6087e984742914a18bf08061e6b350b7b5d4405e..34b9e8c9ca3de1db961c34526b7c6ded24241415 100644 (file)
@@ -514,12 +514,10 @@ public:
   void open_snap_parents();
 
   bool open_undef_inodes_dirfrags();
+  void opened_undef_inode(CInode *in);
   void opened_undef_dirfrag(CDir *dir) {
     rejoin_undef_dirfrags.erase(dir);
   }
-  void opened_undef_inode(CInode *in) {
-    rejoin_undef_inodes.erase(in);
-  }
 
   void reissue_all_caps();