]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: do full pre_dirty()/mark_dirty() on cowed dentries
authorSage Weil <sage@newdream.net>
Tue, 21 Sep 2010 20:44:02 +0000 (13:44 -0700)
committerSage Weil <sage@newdream.net>
Tue, 21 Sep 2010 20:54:13 +0000 (13:54 -0700)
The dir commit/fetch and LogSegment::try_to_expire() rely on any new or
items in the directory getting new versions that correspond to a bump in
the dirfrag version.  This must include dentries/inodes that are created
by the cow process, or else we have problems during dir commit/fetch or
segment expire.

Change the dirty list in the Mutation to include the pv so that we can
properly mark them dirty later.

Leave the inode one alone.  We could theoretically do the same for the
dirty inodes, but this way we avoid projecting them and copying stuff
around.  Any dirty cowed inode will also have a dirty dentry, so it will
still get saved regardless.

Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/MDCache.cc
src/mds/MDCache.h

index 817b7500bc4f1f4b23aa1abf10bad185bce43b64..92da3351039152255c93c57e1e899060ae618d9f 100644 (file)
@@ -1320,6 +1320,7 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn
       dn->first = follows+1;
       CDentry *olddn = dn->dir->add_remote_dentry(dn->name, in->ino(),  in->d_type(),
                                                  oldfirst, follows);
+      olddn->pre_dirty();
       dout(10) << " olddn " << *olddn << dendl;
       metablob->add_remote_dentry(olddn, true);
       mut->add_cow_dentry(olddn);
@@ -1357,6 +1358,7 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn
       if (pcow_inode)
        *pcow_inode = oldin;
       CDentry *olddn = dn->dir->add_primary_dentry(dn->name, oldin, oldfirst, follows);
+      oldin->inode.version = olddn->pre_dirty();
       dout(10) << " olddn " << *olddn << dendl;
       metablob->add_primary_dentry(olddn, true);
       mut->add_cow_dentry(olddn);
@@ -1364,6 +1366,7 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn
       assert(dnl->is_remote());
       CDentry *olddn = dn->dir->add_remote_dentry(dn->name, dnl->get_remote_ino(), dnl->get_remote_d_type(),
                                                  oldfirst, follows);
+      olddn->pre_dirty();
       dout(10) << " olddn " << *olddn << dendl;
       metablob->add_remote_dentry(olddn, true);
       mut->add_cow_dentry(olddn);
index 9cd96115ea561fbbcef0037dd94ad43a58738eda..58921f1f2d9668db84a06bfca4825ceb66f8219b 100644 (file)
@@ -100,7 +100,7 @@ struct Mutation {
   list<ScatterLock*> updated_locks;
 
   list<CInode*> dirty_cow_inodes;
-  list<CDentry*> dirty_cow_dentries;
+  list<pair<CDentry*,version_t> > dirty_cow_dentries;
 
   Mutation() : 
     ls(0),
@@ -206,7 +206,7 @@ struct Mutation {
   }
   void add_cow_dentry(CDentry *dn) {
     pin(dn);
-    dirty_cow_dentries.push_back(dn);
+    dirty_cow_dentries.push_back(pair<CDentry*,version_t>(dn, dn->get_projected_version()));
   }
 
   void apply() {
@@ -217,10 +217,10 @@ struct Mutation {
         p != dirty_cow_inodes.end();
         p++) 
       (*p)->_mark_dirty(ls);
-    for (list<CDentry*>::iterator p = dirty_cow_dentries.begin();
+    for (list<pair<CDentry*,version_t> >::iterator p = dirty_cow_dentries.begin();
         p != dirty_cow_dentries.end();
-        p++) 
-      (*p)->_mark_dirty(ls);
+        p++)
+      p->first->mark_dirty(p->second, ls);
 
     for (list<ScatterLock*>::iterator p = updated_locks.begin();
         p != updated_locks.end();