]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: move snaprealm projection to operate cooperatively with inode projection.
authorGreg Farnum <gregf@hq.newdream.net>
Thu, 19 Aug 2010 18:47:50 +0000 (11:47 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Thu, 19 Aug 2010 22:33:53 +0000 (15:33 -0700)
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc

index cefdf192570fb0a4c045a60617d172f0c5cd090e..d60454950f152f0811b7252c93d20d93c2bd90d6 100644 (file)
@@ -243,19 +243,21 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
 
 sr_t *CInode::project_snaprealm(snapid_t snapid)
 {
-  if (projected_srnode.empty()) {
+  sr_t *new_snaprealm;
+  if (!projected_snaprealm_ptr) {
     if (snaprealm)
-      projected_srnode.push_back(new sr_t(snaprealm->srnode));
+      new_snaprealm = new sr_t(snaprealm->srnode);
     else {
-      projected_srnode.push_back(new sr_t());
-      projected_srnode.back()->created = snapid;
-      projected_srnode.back()->current_parent_since = snapid;
+      new_snaprealm = new sr_t();
+      new_snaprealm->created = snapid;
+      new_snaprealm->current_parent_since = snapid;
     }
   }
   else
-    projected_srnode.push_back(new sr_t(*projected_srnode.back()));
-  dout(0) << "project_snaprealm " << projected_srnode.back() << dendl;
-  return projected_srnode.back();
+    new_snaprealm = new sr_t(*projected_snaprealm_ptr);
+  dout(0) << "project_snaprealm " << new_snaprealm << dendl;
+  projected_nodes.back()->snapnode = new_snaprealm;
+  return new_snaprealm;
 }
 
 /* if newparent != parent, add parent to past_parents
@@ -280,20 +282,19 @@ void CInode::project_past_parent(SnapRealm *newparent, bufferlist& snapbl)
   new_snap->encode(snapbl);
 }
 
-void CInode::pop_projected_snaprealm()
+void CInode::pop_projected_snaprealm(sr_t *next_snaprealm)
 {
-  assert(!projected_srnode.empty());
-  dout(0) << "pop_projected_snaprealm " << projected_srnode.front()
-          << " seq" << projected_srnode.front()->seq << dendl;
+  assert(next_snaprealm);
+  dout(0) << "pop_projected_snaprealm " << next_snaprealm
+          << " seq" << next_snaprealm->seq << dendl;
   bool invalidate_cached_snaps = false;
   if (!snaprealm)
     open_snaprealm();
-  else if (projected_srnode.front()->past_parents.size() !=
+  else if (next_snaprealm->past_parents.size() !=
            snaprealm->srnode.past_parents.size())
     invalidate_cached_snaps = true;
-  snaprealm->srnode = *projected_srnode.front();
-  delete projected_srnode.front();
-  projected_srnode.pop_front();
+  snaprealm->srnode = *next_snaprealm;
+  delete next_snaprealm;
 
   if (invalidate_cached_snaps)
     snaprealm->invalidate_cached_snaps();
index 305aa2dca1c86667ea2bb1d25ad29b57344b14a1..1376e06f271ba7440f5c07be05d76bf5f0f64cd9 100644 (file)
@@ -235,14 +235,14 @@ public:
   }
 
   sr_t *project_snaprealm(snapid_t snapid=0);
-  void pop_projected_snaprealm();
+  void pop_projected_snaprealm(sr_t *next_snaprealm);
   sr_t *get_projected_srnode() {
-    if (projected_srnode.empty())
+    if (!projected_snaprealm_ptr)
       if (snaprealm)
         return &snaprealm->srnode;
       else return NULL;
     else
-      return projected_srnode.back();
+      return projected_snaprealm_ptr;
   }
   void project_past_parent(SnapRealm *newparent, bufferlist& snapbl);
 
index 9313d68026a31a9345944817c50b08c15ddae287..842a55930a98fc2540eec633bf1ec5f69bd6250d 100644 (file)
@@ -4088,22 +4088,26 @@ void Server::_unlink_local_finish(MDRequest *mdr,
 
   // relink as stray?  (i.e. was primary link?)
   CDentry::linkage_t *straydnl = 0;
+  sr_t *next_snap = 0;
   if (straydn) {
     dout(20) << " straydn is " << *straydn << dendl;
     straydnl = straydn->pop_projected_linkage();
     
+    next_snap = straydnl->get_inode()->projected_nodes.front()->snapnode;
+    mdcache->touch_dentry_bottom(straydn);
+  }
+
+  dn->mark_dirty(dnpv, mdr->ls);
+  mdr->apply();
+
+  if (straydn) {
     bool isnew = false;
     if (!straydnl->get_inode()->snaprealm)
       isnew = true;
-    straydnl->get_inode()->pop_projected_snaprealm();
+    straydnl->get_inode()->pop_projected_snaprealm(next_snap);
     if (isnew)
       mdcache->do_realm_invalidate_and_update_notify(straydnl->get_inode(), CEPH_SNAP_OP_SPLIT, true);
-
-    mdcache->touch_dentry_bottom(straydn);
   }
-
-  dn->mark_dirty(dnpv, mdr->ls);  
-  mdr->apply();
   
   mds->mdcache->send_dentry_unlink(dn, straydn);
   
@@ -4881,7 +4885,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
        bool isnew = false;
        if (!straydnl->get_inode()->snaprealm)
          isnew = true;
-       straydnl->get_inode()->pop_projected_snaprealm();
+       sr_t *next_snap = straydnl->get_inode()->projected_nodes.front()->snapnode;
+       straydnl->get_inode()->pop_projected_snaprealm(next_snap);
        if (isnew)
          mdcache->do_realm_invalidate_and_update_notify(straydnl->get_inode(), CEPH_SNAP_OP_SPLIT);
       }
@@ -4940,11 +4945,12 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       destdnl->get_inode()->state_set(CInode::STATE_AUTH);
     }
 
+    sr_t *next_snap = NULL;
     if (destdn->is_auth()) {
       CInode *desti = destdnl->get_inode();
+      next_snap = desti->projected_nodes.front()->snapnode;
       desti->pop_and_dirty_projected_inode(mdr->ls);
 
-      
       if (desti->is_dir()) {
        mdr->ls->renamed_files.push_back(&desti->item_renamed_file);
        desti->state_set(CInode::STATE_DIRTYPARENT);
@@ -4953,8 +4959,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
     }
 
     // snap parent update?
-    if (destdn->is_auth() && destdnl->get_inode()->snaprealm)
-      destdnl->get_inode()->pop_projected_snaprealm();
+    if (next_snap)
+      destdnl->get_inode()->pop_projected_snaprealm(next_snap);
   }
 
   // src
@@ -5715,15 +5721,6 @@ void Server::handle_client_mksnap(MDRequest *mdr)
   pi->ctime = info.stamp;
   pi->version = diri->pre_dirty();
 
-  mdr->ls = mdlog->get_current_segment();
-  EUpdate *le = new EUpdate(mdlog, "mksnap");
-  mdlog->start_entry(le);
-
-  le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
-  le->metablob.add_table_transaction(TABLE_SNAP, stid);
-  mdcache->predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY, false);
-  mdcache->journal_cow_inode(mdr, &le->metablob, diri);
-  
   // project the snaprealm
   bufferlist snapbl;
   sr_t *newsnap = diri->project_snaprealm(snapid);
@@ -5732,6 +5729,16 @@ void Server::handle_client_mksnap(MDRequest *mdr)
   newsnap->last_created = snapid;
   newsnap->encode(snapbl);
 
+  // journal the inode changes
+  mdr->ls = mdlog->get_current_segment();
+  EUpdate *le = new EUpdate(mdlog, "mksnap");
+  mdlog->start_entry(le);
+
+  le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
+  le->metablob.add_table_transaction(TABLE_SNAP, stid);
+  mdcache->predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY, false);
+  mdcache->journal_cow_inode(mdr, &le->metablob, diri);
+  // journal the snaprealm changes
   le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, 0, &snapbl);
 
   mdlog->submit_entry(le, new C_MDS_mksnap_finish(mds, mdr, diri, info));
@@ -5742,6 +5749,8 @@ void Server::_mksnap_finish(MDRequest *mdr, CInode *diri, SnapInfo &info)
 {
   dout(10) << "_mksnap_finish " << *mdr << " " << info << dendl;
 
+  sr_t *next_snaprealm = diri->projected_nodes.front()->snapnode;
+
   diri->pop_and_dirty_projected_inode(mdr->ls);
   mdr->apply();
 
@@ -5750,7 +5759,7 @@ void Server::_mksnap_finish(MDRequest *mdr, CInode *diri, SnapInfo &info)
   // create snap
   snapid_t snapid = info.snapid;
   int op = (diri->snaprealm? CEPH_SNAP_OP_CREATE : CEPH_SNAP_OP_SPLIT);
-  diri->pop_projected_snaprealm();
+  diri->pop_projected_snaprealm(next_snaprealm);
   dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
 
   mdcache->do_realm_invalidate_and_update_notify(diri, op);
@@ -5845,11 +5854,6 @@ void Server::handle_client_rmsnap(MDRequest *mdr)
   mdr->ls = mdlog->get_current_segment();
   EUpdate *le = new EUpdate(mdlog, "rmsnap");
   mdlog->start_entry(le);
-
-  le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
-  le->metablob.add_table_transaction(TABLE_SNAP, stid);
-  mdcache->predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY, false);
-  mdcache->journal_cow_inode(mdr, &le->metablob, diri);
   
   // project the snaprealm
   bufferlist snapbl;
@@ -5859,6 +5863,11 @@ void Server::handle_client_rmsnap(MDRequest *mdr)
   newnode->last_destroyed = seq;
   newnode->encode(snapbl);
 
+  le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
+  le->metablob.add_table_transaction(TABLE_SNAP, stid);
+  mdcache->predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY, false);
+  mdcache->journal_cow_inode(mdr, &le->metablob, diri);
+
   le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, 0, &snapbl);
 
   mdlog->submit_entry(le, new C_MDS_rmsnap_finish(mds, mdr, diri, snapid));
@@ -5873,13 +5882,15 @@ void Server::_rmsnap_finish(MDRequest *mdr, CInode *diri, snapid_t snapid)
   snapid_t seq;
   ::decode(seq, p);  
 
+  sr_t *next_snaprealm = diri->projected_nodes.front()->snapnode;
+
   diri->pop_and_dirty_projected_inode(mdr->ls);
   mdr->apply();
 
   mds->snapclient->commit(stid, mdr->ls);
 
   // remove snap
-  diri->pop_projected_snaprealm();
+  diri->pop_projected_snaprealm(next_snaprealm);
   dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
 
   mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_DESTROY);