]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: eliminate children linkages, instead maintain open_children; make split adjust...
authorSage Weil <sage@newdream.net>
Sat, 5 Jul 2008 23:11:12 +0000 (16:11 -0700)
committerSage Weil <sage@newdream.net>
Sat, 5 Jul 2008 23:11:12 +0000 (16:11 -0700)
src/TODO
src/mds/CInode.cc
src/mds/Server.cc
src/mds/snap.cc
src/mds/snap.h

index f2fdbf82ffce24d39df675b72ee42919e4430903..a649fc6c2c3f10229be766551fbfe56f99f94385 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -223,12 +223,7 @@ todo
 - rados bits to do clone+write
 /  - cloning
   - fix cloning on unlinked file (where snaps=[], but head may have follows_snap attr)
-
-/  - SnapRealm open_parents, get_snap_set need to recursively open/examine parents over given ranges...
-/  - realm split
-    - adjust parent/child linkages
-/  - make realm split notifications safe from races from multiple mds's
-    - make sense of snap_highwater...
+  - make sense of snap_highwater...
 
   - figure out how to fix up rados logging
   - snap collections
index 535f0ce477ce810798ff8757b4f2453456f95a17..e429b635d8323a09436d964aa745940a9a25824e 100644 (file)
@@ -980,12 +980,24 @@ CInodeDiscover* CInode::replicate_to( int rep )
 
 void CInode::open_snaprealm()
 {
-  if (!snaprealm)
+  if (!snaprealm) {
     snaprealm = new SnapRealm(mdcache, this);
+
+    snaprealm->open_parent = find_containing_snaprealm();
+    if (snaprealm->open_parent) {
+      snaprealm->open_parent->open_children.insert(snaprealm);
+      dout(10) << " opened snaprealm " << snaprealm
+              << " parent is " << snaprealm->open_parent
+              << " siblings are " << snaprealm->open_parent->open_children
+              << dendl;
+    }
+  }
 }
 void CInode::close_snaprealm()
 {
   if (snaprealm) {
+    if (snaprealm->open_parent)
+      snaprealm->open_parent->open_children.erase(snaprealm);
     delete snaprealm;
     snaprealm = 0;
   }
@@ -998,15 +1010,12 @@ void CInode::close_snaprealm()
 SnapRealm *CInode::find_containing_snaprealm()
 {
   CInode *cur = this;
-  while (1) {
-    if (!cur->get_parent_dn()) {
-      assert(0); // all base inodes should have realms!
-      return 0;
-    }
+  while (cur->get_parent_dn()) {
     cur = cur->get_parent_dn()->get_dir()->get_inode();
     if (cur->snaprealm)
       return cur->snaprealm;
   }
+  return 0;
 }
 
 void CInode::encode_snap(bufferlist &bl)
index c1837c3112e26cd9ac18f4df42b8c9ef475419ea..0de2fa6d269fe545af63ea5e13a4210719a16632 100644 (file)
@@ -4668,10 +4668,10 @@ void Server::handle_client_mksnap(MDRequest *mdr)
     rdlocks.insert(&trace[i]->lock);
 
   // rdlock ancestor snaps
-  CInode *t = diri->get_parent_dn()->get_dir()->get_inode();
-  while (t) {
-    rdlocks.insert(&t->snaplock);
+  CInode *t = diri;
+  while (t->get_parent_dn()) {
     t = t->get_parent_dn()->get_dir()->get_inode();
+    rdlocks.insert(&t->snaplock);
   }
 
   // xlock snap
@@ -4704,12 +4704,11 @@ void Server::handle_client_mksnap(MDRequest *mdr)
     // link them up
     // HACK!  parent may be on another mds...
 
-    SnapRealm *parent = diri->find_containing_snaprealm();
+    SnapRealm *parent = diri->snaprealm->open_parent;
     assert(parent);
+    assert(parent->open_children.count(diri->snaprealm));
     snaplink_t link;
     link.first = 0;
-    link.dirino = diri->ino();
-    parent->children.insert(pair<snapid_t,snaplink_t>(CEPH_NOSNAP, link));
     link.dirino = parent->inode->ino();
     diri->snaprealm->parents.insert(pair<snapid_t,snaplink_t>(CEPH_NOSNAP, link));
 
@@ -4761,16 +4760,12 @@ void Server::handle_client_mksnap(MDRequest *mdr)
       mds->send_message_client(update, p->first);
     }
     
-    // active children, too.
-    for (multimap<snapid_t,snaplink_t>::iterator p = realm->children.find(CEPH_NOSNAP);
-        p != realm->children.end();
-        p++) {
-      CInode *in = mdcache->get_inode(p->second.dirino);
-      if (in) {
-       assert(in->snaprealm);
-       q.push_back(in->snaprealm);
-      }
-    }
+    // notify for active children, too.
+    dout(10) << " " << realm << " open_children are " << realm->open_children << dendl;
+    for (set<SnapRealm*>::iterator p = realm->open_children.begin();
+        p != realm->open_children.end();
+        p++)
+      q.push_back(*p);
   }
 
   // yay
index 31958397e6dbdea4c50d3d232a03b1bb54b0f0b6..01888f03bdbbeb99f2e8e1d58d079bd607610f30 100644 (file)
  * SnapRealm
  */
 
-#define dout(x) if (x < g_conf.debug_mds) *_dout << dbeginl << g_clock.now() \
-                                                << " mds" << mdcache->mds->get_nodeid() \
-                                                << ".snaprealm(" << inode->ino() << ") "
+#define dout(x) if (x <= g_conf.debug_mds) *_dout << dbeginl << g_clock.now() \
+                                                 << " mds" << mdcache->mds->get_nodeid() \
+                                                 << ".cache.snaprealm(" << inode->ino() \
+                                                 << " " << this << ") "
 
 bool SnapRealm::open_parents(MDRequest *mdr)
 {
@@ -94,8 +95,27 @@ void SnapRealm::get_snap_vector(vector<snapid_t> &v)
 
 void SnapRealm::split_at(SnapRealm *child)
 {
-  dout(10) << "split_at " << *child << " on " << *child->inode << dendl;
+  dout(10) << "split_at " << *child 
+          << " on " << *child->inode << dendl;
+
+  // split children
+  dout(10) << " my children are " << open_children << dendl;
+  for (set<SnapRealm*>::iterator p = open_children.begin();
+       p != open_children.end(); ) {
+    SnapRealm *realm = *p;
+    if (realm != child &&
+       child->inode->is_ancestor_of(realm->inode)) {
+      dout(20) << " child gets child realm " << *realm << " on " << *realm->inode << dendl;
+      realm->open_parent = child;
+      child->open_children.insert(realm);
+      open_children.erase(p++);
+    } else {
+      dout(20) << "    keeping child realm " << *realm << " on " << *realm->inode << dendl;
+      p++;
+    }
+  }
 
+  // split inodes_with_caps
   xlist<CInode*>::iterator p = inodes_with_caps.begin();
   while (!p.end()) {
     CInode *in = *p;
@@ -113,13 +133,12 @@ void SnapRealm::split_at(SnapRealm *child)
       if (t == in)
        break;
     }
-    if (!under_child) {
-      dout(20) << " keeping " << *in << dendl;
-      continue;
+    if (under_child) {
+      dout(20) << " child gets " << *in << dendl;
+      in->move_to_containing_realm(child);
+    } else {
+      dout(20) << "    keeping " << *in << dendl;
     }
-    
-    dout(20) << " child gets " << *in << dendl;
-    in->move_to_containing_realm(child);
   }
 
 }
index c5a376049e74252e264d3493de00f7cbc30294ee..ef12bb14c1c5b9480dae160b98d09f45e64ba466 100644 (file)
@@ -85,19 +85,17 @@ struct SnapRealm {
   // realm state
   snapid_t created;
   map<snapid_t, SnapInfo> snaps;
-  multimap<snapid_t, snaplink_t> parents, children;  // key is "last" (or NOSNAP)
+  multimap<snapid_t, snaplink_t> parents;  // key is "last" (or NOSNAP)
 
   void encode(bufferlist& bl) const {
     ::encode(created, bl);
     ::encode(snaps, bl);
     ::encode(parents, bl);
-    ::encode(children, bl);
   }
   void decode(bufferlist::iterator& p) {
     ::decode(created, p);
     ::decode(snaps, p);
     ::decode(parents, p);
-    ::decode(children, p);
   }
 
   // in-memory state
@@ -107,15 +105,18 @@ struct SnapRealm {
   snapid_t highwater;  // largest snap this realm has exposed to clients (implicitly or explicitly)
 
   // caches?
+  SnapRealm *open_parent;
+  set<SnapRealm*> open_children;    // active children that are currently open
+
   //set<snapid_t> cached_snaps;
-  //set<SnapRealm*> cached_active_children;    // active children that are currently open
 
   xlist<CInode*> inodes_with_caps;             // for efficient realm splits
   map<int, xlist<Capability*> > client_caps;   // to identify clients who need snap notifications
 
   SnapRealm(MDCache *c, CInode *in) : 
     created(0),
-    mdcache(c), inode(in), highwater(0) {}
+    mdcache(c), inode(in), highwater(0),
+    open_parent(0) {}
 
   bool open_parents(MDRequest *mdr);
   void get_snap_set(set<snapid_t>& s, snapid_t first=0, snapid_t last=CEPH_NOSNAP);
@@ -151,22 +152,7 @@ inline ostream& operator<<(ostream& out, const SnapRealm &realm) {
     }
     out << ")";
   }
-  if (realm.children.size()) {
-    out << " children=(";
-    for (multimap<snapid_t, snaplink_t>::const_iterator p = realm.parents.begin(); 
-        p != realm.parents.end(); 
-        p++) {
-      if (p != realm.parents.begin()) out << ",";
-      out << p->second.first << "-";
-      if (p->first == CEPH_NOSNAP)
-       out << "head";
-      else
-       out << p->first;
-      out << "=" << p->second.dirino;
-    }
-    out << ")";
-  }
-  out << ")";
+  out << " " << &realm << ")";
   return out;
 }