]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
more split fun
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 26 Jul 2007 23:36:28 +0000 (23:36 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 26 Jul 2007 23:36:28 +0000 (23:36 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1559 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/mds/include/frag.h
branches/sage/mds/mds/CDentry.cc
branches/sage/mds/mds/CInode.cc
branches/sage/mds/mds/MDCache.cc
branches/sage/mds/mds/MDCache.h
branches/sage/mds/mds/Migrator.cc
branches/sage/mds/messages/MExportDirPrep.h
branches/sage/mds/messages/MMDSFragmentNotify.h

index 50a2fb76682062b339a82ec28eec18c5542be1f2..6e64646eb691fcd3ec6db6c6156d5141969aff00 100644 (file)
@@ -361,13 +361,12 @@ class fragtree_t {
   }
 
   bool force_to_leaf(frag_t x) {
-    assert(!is_leaf(x));
+    if (is_leaf(x))
+      return false;
 
     frag_t parent = get_branch_or_leaf(x);
     assert(parent.bits() <= x.bits());
 
-    bool changed = false;
-
     // do we need to split from parent to x?
     if (parent.bits() < x.bits()) {
       int spread = x.bits() - parent.bits();
@@ -375,12 +374,10 @@ class fragtree_t {
       if (nb == 0) {
        // easy: split parent (a leaf) by the difference
        split(parent, spread);
-       return true;
       }
       assert(nb > spread);
       
       // add an intermediary split
-      changed = true;
       merge(parent, nb);
       split(parent, spread);
 
@@ -401,13 +398,12 @@ class fragtree_t {
       q.pop_front();
       int nb = get_split(t);
       if (nb) {
-       changed = true;
        merge(t, nb);         // merge this point, and
        t.split(nb, q);   // queue up children
       }
     }
 
-    return changed;
+    return true;
   }
 
   // verify that we describe a legal partition of the namespace.
@@ -529,7 +525,7 @@ public:
 
 inline ostream& operator<<(ostream& out, fragset_t& fs) 
 {
-  return out << "fragset_t(" << fs.get() << ")" << endl;
+  return out << "fragset_t(" << fs.get() << ")";
 }
 
 #endif
index fa74f9f89acbe82fe5642173ba87f6545a5157ac..cbefecc1075a4941347590478df1adb2e30279c7 100644 (file)
@@ -27,7 +27,7 @@
 #include <cassert>
 
 #undef dout
-#define dout(x)  if (x <= g_conf.debug || x <= g_conf.debug_mds) cout << g_clock.now() << " mds" << dir->cache->mds->get_nodeid() << ".cache.den(" << dir->ino() << " " << name << ") "
+#define dout(x)  if (x <= g_conf.debug || x <= g_conf.debug_mds) cout << g_clock.now() << " mds" << dir->cache->mds->get_nodeid() << ".cache.den(" << dir->dirfrag() << " " << name << ") "
 
 ostream& CDentry::print_db_line_prefix(ostream& out) 
 {
index e467e6b724e7810b38f08b3cedb1577bc542767c..d19cf66b832b93c83a28e3c6191bec654628bca2 100644 (file)
@@ -58,7 +58,8 @@ ostream& operator<<(ostream& out, CInode& in)
   }
 
   if (in.is_symlink()) out << " symlink";
-
+  if (in.is_dir() && !in.dirfragtree.empty()) out << " " << in.dirfragtree;
+  
   out << " v" << in.get_version();
 
   // locks
@@ -643,8 +644,6 @@ void CInode::adjust_nested_auth_pins(int a)
 
 pair<int,int> CInode::authority() 
 {
-  //if (is_root())
-  //return CDIR_AUTH_ROOTINODE;  // root _inode_ is locked to mds0.
   if (force_auth.first >= 0) 
     return force_auth;
 
index 5c8b2af6a22477f8f53f3ff1e27eabb09ff5f30a..40936be58ff3f02c8be605c95d92a4379c70b4cf 100644 (file)
@@ -673,6 +673,7 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set<CDir*>& bounds, pair<in
   show_subtrees();
 }
 
+
 void MDCache::adjust_bounded_subtree_auth(CDir *dir, list<dirfrag_t>& bound_dfs, pair<int,int> auth)
 {
   dout(7) << "adjust_bounded_subtree_auth " << dir->get_dir_auth() << " -> " << auth
@@ -693,6 +694,34 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, list<dirfrag_t>& bound_dfs,
   adjust_bounded_subtree_auth(dir, bounds, auth);
 }
 
+void MDCache::map_dirfrag_set(list<dirfrag_t>& dfs, set<CDir*>& result)
+{
+  // group by inode
+  map<inodeno_t, fragset_t> ino_fragset;
+  for (list<dirfrag_t>::iterator p = dfs.begin(); p != dfs.end(); ++p)
+    ino_fragset[p->ino].insert(p->frag);
+
+  // get frags
+  for (map<inodeno_t, fragset_t>::iterator p = ino_fragset.begin();
+       p != ino_fragset.end();
+       ++p) {
+    CInode *in = get_inode(p->first);
+    if (!in) continue;
+
+    list<frag_t> fglist;
+    for (set<frag_t>::iterator q = p->second.begin(); q != p->second.end(); ++q)
+      in->dirfragtree.get_leaves_under(*q, fglist);
+
+    dout(15) << "map_dirfrag_set " << p->second << " -> " << fglist
+            << " on " << *in << endl;
+
+    for (list<frag_t>::iterator q = fglist.begin(); q != fglist.end(); ++q) {
+      CDir *dir = in->get_dirfrag(*q);
+      if (dir) result.insert(dir);
+    }
+  }
+}
+
 
 
 CDir *MDCache::get_subtree_root(CDir *dir)
@@ -3759,15 +3788,15 @@ int MDCache::path_traverse(MDRequest *mdr, Message *req,     // who
         // discover?
         assert(!cur->is_auth());
         if (cur->is_ambiguous_auth()) {
-         dout(10) << "traverse: need dir, waiting for single auth on " << *cur << endl;
+         dout(10) << "traverse: need dirfrag " << fg << ", waiting for single auth on " << *cur << endl;
          cur->add_waiter(CInode::WAIT_SINGLEAUTH, _get_waiter(mdr, req));
          return 1;
        } else if (dir_discovers.count(cur->ino())) {
-          dout(10) << "traverse: need dir, already doing discover for " << *cur << endl;
+          dout(10) << "traverse: need dirfrag " << fg << ", already doing discover for " << *cur << endl;
          assert(cur->is_waiter_for(CInode::WAIT_DIR));
        } else {
          filepath want = path.postfixpath(depth);
-         dout(10) << "traverse: need dir, doing discover, want " << want.get_path() 
+         dout(10) << "traverse: need dirfrag " << fg << ", doing discover, want " << want.get_path() 
                   << " from " << *cur << endl;
          mds->send_message_mds(new MDiscover(mds->get_nodeid(),
                                              cur->ino(),
@@ -5141,6 +5170,9 @@ CDir *MDCache::add_replica_dir(CInode *diri,
     dis.update_dir(dir);
     dout(7) << "add_replica_dir had " << *dir << " nonce " << dir->replica_nonce << endl;
   } else {
+    // force frag to leaf in the diri tree
+    diri->dirfragtree.force_to_leaf(fg);
+
     // add replica.
     dir = diri->add_dirfrag( new CDir(diri, fg, this, false) );
     dis.update_dir(dir);
index 4f1a41e1f64cb9caad2bf9727a6484581a01c526..2e423777d25820621ec6267bc36440b8bfc8eb89 100644 (file)
@@ -246,6 +246,7 @@ public:
   void adjust_bounded_subtree_auth(CDir *dir, list<dirfrag_t>& bounds, int a) {
     adjust_bounded_subtree_auth(dir, bounds, pair<int,int>(a, CDIR_AUTH_UNKNOWN));
   }
+  void map_dirfrag_set(list<dirfrag_t>& dfs, set<CDir*>& result);
   void adjust_export_state(CDir *dir);
   void try_subtree_merge(CDir *root);
   void try_subtree_merge_at(CDir *root);
index bcb80d3117d55ed2c7d2f032fa7b7bc465473642..7150c46a4ff532bd363054e3fba36489677074a8 100644 (file)
@@ -631,7 +631,7 @@ void Migrator::export_frozen(CDir *dir)
       // include the dirfrag?  only if it's not the bounding subtree root.
       if (cur != bound) {
        assert(cur->is_auth());
-        prep->add_dirfrag( new CDirDiscover(cur, cur->add_replica(dest)) );  // yay!
+        prep->add_dirfrag( cur->replicate_to(dest) );  // yay!
         dout(7) << "  added " << *cur << endl;
       }
       
@@ -642,9 +642,11 @@ void Migrator::export_frozen(CDir *dir)
          it != inode_trace.end();
          it++) {
       CInode *in = *it;
+      dout(7) << "  added " << *in->parent << endl;
       dout(7) << "  added " << *in << endl;
       prep->add_inode( in->parent->get_dir()->dirfrag(),
-                       in->parent->get_name(),
+                      in->parent->get_name(),
+                       in->parent->replicate_to(dest),
                        in->replicate_to(dest) );
     }
 
@@ -1341,8 +1343,10 @@ void Migrator::handle_export_prep(MExportDirPrep *m)
   map<inodeno_t, fragset_t> bound_dirfragset;
   for (list<dirfrag_t>::iterator p = m->get_bounds().begin();
        p != m->get_bounds().end();
-       ++p) 
+       ++p) {
+    dout(10) << " bound " << *p << endl;
     bound_dirfragset[p->ino].insert(p->frag);
+  }
 
   // assimilate contents?
   if (!m->did_assim()) {
@@ -1442,10 +1446,10 @@ void Migrator::handle_export_prep(MExportDirPrep *m)
        dout(7) << "  pinning import bound " << *bound << endl;
        bound->get(CDir::PIN_IMPORTBOUND);
        bound->state_set(CDir::STATE_IMPORTBOUND);
-       import_bounds.insert(bound);
       } else {
        dout(7) << "  already pinned import bound " << *bound << endl;
       }
+      import_bounds.insert(bound);
     }
   }
 
@@ -1988,7 +1992,9 @@ void Migrator::handle_export_notify(MExportDirNotify *m)
     dout(7) << "handle_export_notify " << old_auth << " -> " << new_auth
            << " on " << *dir << endl;
     // adjust auth
-    cache->adjust_bounded_subtree_auth(dir, m->get_bounds(), new_auth);
+    set<CDir*> have;
+    cache->map_dirfrag_set(m->get_bounds(), have);
+    cache->adjust_bounded_subtree_auth(dir, have, new_auth);
     
     // induce a merge?
     cache->try_subtree_merge(dir);
index 8d54276f0bd835f604077b868c032eb8c2d39481..5789e301e8b1110b5f6f75b32dd954b0f9614e71 100644 (file)
@@ -31,6 +31,7 @@ class MExportDirPrep : public Message {
   list<dirfrag_t>                bounds;
 
   list<CInodeDiscover*>          inodes;
+  list<CDentryDiscover*>         dentries;
   map<inodeno_t,dirfrag_t>       inode_dirfrag;
   map<inodeno_t,string>          inode_dentry;
 
@@ -45,6 +46,7 @@ class MExportDirPrep : public Message {
   dirfrag_t get_dirfrag() { return dirfrag; }
   list<dirfrag_t>& get_bounds() { return bounds; }
   list<CInodeDiscover*>& get_inodes() { return inodes; }
+  list<CDentryDiscover*>& get_dentries() { return dentries; }
   list<frag_t>& get_inode_dirfrags(inodeno_t ino) { 
     return frags_by_ino[ino];
   }
@@ -77,6 +79,10 @@ class MExportDirPrep : public Message {
          iit != inodes.end();
          iit++)
       delete *iit;
+    for (list<CDentryDiscover*>::iterator p = dentries.begin();
+         p != dentries.end();
+         p++)
+      delete *p;
     for (map<dirfrag_t,CDirDiscover*>::iterator dit = dirfrags.begin();
          dit != dirfrags.end();
          dit++) 
@@ -92,10 +98,11 @@ class MExportDirPrep : public Message {
   void add_export(dirfrag_t df) {
     bounds.push_back( df );
   }
-  void add_inode(dirfrag_t df, const string& dentry, CInodeDiscover *in) {
+  void add_inode(dirfrag_t df, const string& name, CDentryDiscover *dn, CInodeDiscover *in) {
     inodes.push_back(in);
+    dentries.push_back(dn);
     inode_dirfrag[in->get_ino()] = df;
-    inode_dentry[in->get_ino()] = dentry;
+    inode_dentry[in->get_ino()] = name;
   }
   void add_dirfrag(CDirDiscover *dir) {
     dirfrags[dir->get_dirfrag()] = dir;
@@ -121,6 +128,11 @@ class MExportDirPrep : public Message {
       CInodeDiscover *in = new CInodeDiscover;
       in->_decode(payload, off);
       inodes.push_back(in);
+
+      // dentry
+      CDentryDiscover *dn = new CDentryDiscover;
+      dn->_decode(payload, off);
+      dentries.push_back(dn);
       
       // dentry
       string d;
@@ -158,12 +170,13 @@ class MExportDirPrep : public Message {
     // inodes
     int ni = inodes.size();
     payload.append((char*)&ni, sizeof(int));
-    for (list<CInodeDiscover*>::iterator iit = inodes.begin();
-         iit != inodes.end();
-         iit++) {
+    list<CDentryDiscover*>::iterator dit = dentries.begin();
+    list<CInodeDiscover*>::iterator iit = inodes.begin();
+    while (iit != inodes.end()) {
       (*iit)->_encode(payload);
-      
-      // dentry
+      (*dit)->_encode(payload);
+
+      // dentry name
       _encode(inode_dentry[(*iit)->get_ino()], payload);
 
       // dir ino
@@ -172,6 +185,9 @@ class MExportDirPrep : public Message {
 
       // child frags
       ::_encode(frags_by_ino[(*iit)->get_ino()], payload);
+
+      iit++;
+      dit++;
     }
 
     // dirs
index b7994386c00bc83d2d570745ac48c28f1935f983..232cce92427bb7b2cd0a40a9a8036f07037aa848 100644 (file)
@@ -22,7 +22,7 @@ using namespace std;
 class MMDSFragmentNotify : public Message {
   inodeno_t ino;
   frag_t basefrag;
-  char bits;
+  int8_t bits;
 
  public:
   inodeno_t get_ino() { return ino; }
@@ -39,21 +39,21 @@ class MMDSFragmentNotify : public Message {
   virtual char *get_type_name() { return "fragment_notify"; }
   void print(ostream& o) {
     o << "fragment_notify(" << ino << "#" << basefrag
-         << " " << bits << ")";
+      << " " << (int)bits << ")";
   }
 
   virtual void decode_payload() {
     int off = 0;
-       ::_decode(ino, payload, off);
-       ::_decode(basefrag, payload, off);
-       ::_decode(bits, payload, off);
-       ::_decode(basebl, payload, off);
+    ::_decode(ino, payload, off);
+    ::_decode(basefrag, payload, off);
+    ::_decode(bits, payload, off);
+    ::_decode(basebl, payload, off);
   }
   virtual void encode_payload() {
-       ::_encode(ino, payload);
-       ::_encode(basefrag, payload);
-       ::_encode(bits, payload);
-       ::_encode(basebl, payload);
+    ::_encode(ino, payload);
+    ::_encode(basefrag, payload);
+    ::_encode(bits, payload);
+    ::_encode(basebl, payload);
   }
 };