]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: split snaprealm on unlink; clean up rename realm updates
authorSage Weil <sage@newdream.net>
Tue, 5 Aug 2008 21:09:18 +0000 (14:09 -0700)
committerSage Weil <sage@newdream.net>
Tue, 5 Aug 2008 21:09:18 +0000 (14:09 -0700)
src/TODO
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc
src/mds/snap.cc
src/mds/snap.h

index 8c3ce950660780d62008a1af654f06f293a7880a..42c572ed9cdd4c778f061feb16750914772ad60c 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -34,15 +34,6 @@ snaps on mds
 - mds open within snapshot
 - client snap read
 
-
-- test rejoin
-- client reconnect
-  - esp cap claim
-
-
-
-/- call open_parents() where needed.
-  - what about during recovery?  e.g. client reconnected caps...
 - mds server ops
   - link rollback
   - rename rollback
index 10b2ee157a497ee9e21e2ed0c678061ed789ab59..2887bfd3d0d772bdea20b60ee690834fc30d35cf 100644 (file)
@@ -1206,7 +1206,7 @@ void CInode::purge_stale_snap_data(const set<snapid_t>& snaps)
 }
 */
 
-void CInode::open_snaprealm()
+void CInode::open_snaprealm(bool nosplit)
 {
   if (!snaprealm) {
     SnapRealm *parent = find_snaprealm();
@@ -1217,18 +1217,22 @@ void CInode::open_snaprealm()
               << " siblings are " << parent->open_children
               << dendl;
       snaprealm->parent = parent;
-      parent->split_at(snaprealm);
+      if (!nosplit)
+       parent->split_at(snaprealm);
       parent->open_children.insert(snaprealm);
     }
   }
 }
-void CInode::close_snaprealm()
+void CInode::close_snaprealm(bool nojoin)
 {
   if (snaprealm) {
     dout(15) << "close_snaprealm " << *snaprealm << dendl;
     snaprealm->close_parents();
-    if (snaprealm->parent)
+    if (snaprealm->parent) {
       snaprealm->parent->open_children.erase(snaprealm);
+      //if (!nojoin)
+      //snaprealm->parent->join(snaprealm);
+    }
     delete snaprealm;
     snaprealm = 0;
   }
index 0ec80acb7fcd4b63980f8118d9e9d4e2de4ef61c..6b189d4655e853876cbfbcb9749142f30e4821ae 100644 (file)
@@ -454,8 +454,8 @@ public:
 
 
   // -- snap --
-  void open_snaprealm();
-  void close_snaprealm();
+  void open_snaprealm(bool no_split=false);
+  void close_snaprealm(bool no_join=false);
   SnapRealm *find_snaprealm();
   void encode_snap_blob(bufferlist &bl);
   void decode_snap_blob(bufferlist &bl);
index 2e4134410365d7ef058c6484143394036de22b93..c2844bfe6c333c8517a357d4ade03b2d7d718c7b 100644 (file)
@@ -2491,7 +2491,7 @@ void Server::_link_remote_finish(MDRequest *mdr, bool inc,
     for (map<int,int>::iterator it = dn->replicas_begin();
         it != dn->replicas_end();
         it++) {
-      dout(7) << "_unlink_remote_finish sending MDentryUnlink to mds" << it->first << dendl;
+      dout(7) << "_link_remote_finish sending MDentryUnlink to mds" << it->first << dendl;
       MDentryUnlink *unlink = new MDentryUnlink(dn->dir->dirfrag(), dn->name);
       mds->send_message_mds(unlink, it->first);
     }
@@ -2961,11 +2961,20 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn)
   le->metablob.add_null_dentry(dn, true);
 
   if (dn->is_primary()) {
+    // project snaprealm, too
+    bufferlist snapbl;
+    if (!dn->inode->snaprealm) {
+      dn->inode->open_snaprealm(true);   // don't do a split
+      dn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl);
+      dn->inode->close_snaprealm(true);  // or a matching join
+    } else
+      dn->inode->snaprealm->project_past_parent(straydn->dir->inode->snaprealm, snapbl);
+
     // primary link.  add stray dentry.
     assert(straydn);
     mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, -1);
     mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, straydn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
-    le->metablob.add_primary_dentry(straydn, true, dn->inode, pi);
+    le->metablob.add_primary_dentry(straydn, true, dn->inode, pi, 0, &snapbl);
   } else {
     // remote link.  update remote inode.
     mdcache->predirty_journal_parents(mdr, &le->metablob, dn->inode, dn->dir, PREDIRTY_DIR, -1);
@@ -2994,6 +3003,12 @@ void Server::_unlink_local_finish(MDRequest *mdr,
   if (straydn) {
     dout(20) << " straydn is " << *straydn << dendl;
     straydn->dir->link_primary_inode(straydn, in);
+
+    if (!straydn->inode->snaprealm) {
+      straydn->inode->open_snaprealm();
+      mdcache->do_realm_split_notify(straydn->inode);
+    }
+    straydn->inode->snaprealm->add_past_parent(dn->dir->inode->find_snaprealm());
   }
 
   dn->mark_dirty(dnpv, mdr->ls);  
@@ -3700,28 +3715,8 @@ void Server::_rename_prepare(MDRequest *mdr,
   } else if (srcdn->is_primary()) {
     // project snap parent update?
     bufferlist snapbl;
-    if (!srcdn->inode->snaprealm)
-      srcdn->inode->open_snaprealm();
-    if (destdn->is_auth()) {
-      SnapRealm *realm = srcdn->inode->snaprealm;
-      snapid_t oldlast = realm->parent->get_newest_snap();
-      snapid_t newlast = destdn->dir->inode->find_snaprealm()->get_last_created();
-      snapid_t first = realm->current_parent_since;
-
-      snapid_t old_since = realm->current_parent_since;
-      realm->current_parent_since = MAX(oldlast, newlast) + 1;
-      if (oldlast >= first) {
-       realm->past_parents[oldlast].ino = realm->parent->inode->ino();
-       realm->past_parents[oldlast].first = first;
-       dout(10) << " projecting new past_parent [" << first << "," << oldlast << "] = "
-                << realm->parent->inode->ino() << " on " << *realm << dendl;
-      }
-      dout(10) << " projected current_parent_since " << realm->current_parent_since << " on" << *realm << dendl;
-      ::encode(*realm, snapbl);
-      if (oldlast >= first)
-       realm->past_parents.erase(oldlast);
-      realm->current_parent_since = old_since;
-    }
+    if (destdn->is_auth() && srcdn->inode->snaprealm)
+      srcdn->inode->snaprealm->project_past_parent(destdn->dir->inode->find_snaprealm(), snapbl);
     
     if (!destdn->is_null())
       mdcache->journal_cow_dentry(mdr, metablob, destdn);
@@ -3833,23 +3828,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       destdn->inode->pop_and_dirty_projected_inode(mdr->ls);
 
     // snap parent update?
-    if (destdn->inode->is_dir()) {
-      SnapRealm *realm = destdn->inode->snaprealm;
-      snapid_t oldlast = srcdn->dir->inode->find_snaprealm()->get_newest_snap();
-      snapid_t newlast = destdn->dir->inode->find_snaprealm()->get_last_created();
-      snapid_t first = realm->current_parent_since;
-      
-      if (oldlast >= realm->current_parent_since) {
-       SnapRealm *oldparent = srcdn->dir->inode->find_snaprealm();
-       realm->past_parents[oldlast].ino = oldparent->inode->ino();
-       realm->past_parents[oldlast].first = realm->current_parent_since;
-       realm->add_open_past_parent(oldparent);
-       dout(10) << " adding past_parent [" << realm->past_parents[oldlast].first << "," << oldlast << "] = "
-                << realm->past_parents[oldlast].ino << " on " << *realm << dendl;
-      }
-      realm->current_parent_since = MAX(oldlast, newlast) + 1;
-      dout(10) << " set current_parent_since " << realm->current_parent_since << " on " << *realm << dendl;
-    }
+    if (destdn->is_auth() && destdn->inode->snaprealm)
+      destdn->inode->snaprealm->add_past_parent(srcdn->dir->inode->find_snaprealm());
   }
 
   // src
index 83f0301138e16179ebf8818a904349a221e72c5c..0541a179e70a590eebc55de731fe4bcc53dc3872 100644 (file)
@@ -385,7 +385,6 @@ void SnapRealm::split_at(SnapRealm *child)
 
 
 
-
 void SnapRealm::build_snap_trace(bufferlist& snapbl)
 {
   SnapRealmInfo info;
@@ -421,3 +420,45 @@ void SnapRealm::build_snap_trace(bufferlist& snapbl)
   if (parent)
     parent->build_snap_trace(snapbl);
 }
+
+
+
+
+void SnapRealm::project_past_parent(SnapRealm *newparent, bufferlist& snapbl)
+{
+  snapid_t newlast = newparent->get_last_created();
+  snapid_t oldlast = parent->get_newest_snap();
+  snapid_t first = current_parent_since;
+
+  if (oldlast >= current_parent_since) {
+    past_parents[oldlast].ino = parent->inode->ino();
+    past_parents[oldlast].first = first;
+    dout(10) << "project_past_parent new past_parent [" << first << "," << oldlast << "] = "
+            << parent->inode->ino() << dendl;
+  }
+  current_parent_since = MAX(oldlast, newlast) + 1;
+  dout(10) << "project_past_parent current_parent_since " << current_parent_since << dendl;
+
+  ::encode(*this, snapbl);
+
+  if (oldlast >= first)
+    past_parents.erase(oldlast);
+  current_parent_since = first;
+}
+
+void SnapRealm::add_past_parent(SnapRealm *oldparent)
+{
+  snapid_t newlast = parent->get_last_created();
+  snapid_t oldlast = oldparent->get_newest_snap();
+  snapid_t first = current_parent_since;
+  
+  if (oldlast >= current_parent_since) {
+    past_parents[oldlast].ino = oldparent->inode->ino();
+    past_parents[oldlast].first = first;
+    add_open_past_parent(oldparent);
+    dout(10) << "add_past_parent [" << first << "," << oldlast << "] = "
+            << oldparent->inode->ino() << dendl;
+  }
+  current_parent_since = MAX(oldlast, newlast) + 1;
+  dout(10) << "add_past_parent current_parent_since " << current_parent_since << dendl;
+}
index 3f5d63c23357e4f579d13108f7a3e0cf6b871c5a..077e9c70e508ebd78c8327602b355b9783cf37aa 100644 (file)
@@ -155,6 +155,9 @@ struct SnapRealm {
   void add_open_past_parent(SnapRealm *parent);
   void close_parents();
 
+  void project_past_parent(SnapRealm *newparent, bufferlist& snapbl);
+  void add_past_parent(SnapRealm *oldparent);
+
   void build_snap_set(set<snapid_t>& s, 
                      snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed,
                      snapid_t first, snapid_t last);
@@ -199,6 +202,7 @@ struct SnapRealm {
       parent->open_children.insert(this);
   }
   void split_at(SnapRealm *child);
+  void join(SnapRealm *child);
 
   void add_cap(int client, Capability *cap) {
     client_caps[client].push_back(&cap->snaprealm_caps_item);