]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: assimilate dirty rstat inodes during scatter_writeback
authorSage Weil <sage@newdream.net>
Thu, 23 Sep 2010 23:16:20 +0000 (16:16 -0700)
committerSage Weil <sage@newdream.net>
Fri, 24 Sep 2010 18:44:22 +0000 (11:44 -0700)
We put some of the predirty_journal_parents() code that calls the
project_rstat_inode_to_frag() into a common helper and use that.

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

index 359835a1afa6ed93102197e146c927ca2f35e8ba..8916fc2ab24760400aaef6424afdfded1fe1c56f 100644 (file)
@@ -771,6 +771,39 @@ void CDir::merge(int bits, list<Context*>& waiters, bool replay)
 
 
 
+void CDir::assimilate_dirty_rstat_inodes()
+{
+  dout(10) << "assimilate_dirty_rstat_inodes" << dendl;
+  for (elist<CInode*>::iterator p = dirty_rstat_inodes.begin_use_current();
+       !p.end(); ++p) {
+    CInode *in = *p;
+    inode_t *pi = in->project_inode();
+    pi->version = in->pre_dirty();
+
+    inode->mdcache->project_rstat_inode_to_frag(in, this, 0, 0);
+  }
+  dout(10) << "assimilate_dirty_rstat_inodes done" << dendl;
+}
+
+void CDir::assimilate_dirty_rstat_inodes_finish(Mutation *mut, EMetaBlob *blob)
+{
+  dout(10) << "assimilate_dirty_rstat_inodes_finish" << dendl;
+  elist<CInode*>::iterator p = dirty_rstat_inodes.begin_use_current();
+  while (!p.end()) {
+    CInode *in = *p;
+    CDentry *dn = in->get_projected_parent_dn();
+    ++p;
+
+    mut->auth_pin(in);
+    mut->add_projected_inode(in);
+
+    in->clear_dirty_rstat();
+    blob->add_primary_dentry(dn, true, in);
+  }
+  assert(dirty_rstat_inodes.empty());
+}
+
+
 
 
 /****************************************
index c3df6f4d0c22fefe1c413e689f163c072a41c6ac..a10fc504539de146fa016c8a4aad112a00fb0512 100644 (file)
@@ -169,6 +169,9 @@ public:
   // my inodes with dirty rstat data
   elist<CInode*> dirty_rstat_inodes;     
 
+  void assimilate_dirty_rstat_inodes();
+  void assimilate_dirty_rstat_inodes_finish(Mutation *mut, EMetaBlob *blob);
+
 protected:
   version_t projected_version;
   list<fnode_t*> projected_fnode;
index 62821cf8e80d2a2d998e5104675422e32c0ebe1c..572fbf31b22455fa46ad069f4f172b5a6eef7a2a 100644 (file)
@@ -1463,9 +1463,13 @@ void CInode::finish_scatter_gather_update(int type)
        dout(20) << fg << " " << *dir << dendl;
 
        fnode_t *pf = dir->get_projected_fnode();
-       if (dir->is_auth())
+       if (dir->is_auth()) {
          pf = dir->project_fnode();
 
+         // first push any inodes with dirty rstat into this dirfrag
+         dir->assimilate_dirty_rstat_inodes();
+       }
+
        if (pf->accounted_rstat.version == pi->rstat.version) {
          dout(20) << fg << "           rstat " << pf->rstat << dendl;
          dout(20) << fg << " accounted_rstat " << pf->accounted_rstat << dendl;
@@ -1532,6 +1536,8 @@ void CInode::finish_scatter_gather_update_accounted(int type, Mutation *mut, EMe
     mut->add_projected_fnode(dir);
     metablob->add_dir(dir, true);
     mut->auth_pin(dir);
+
+    dir->assimilate_dirty_rstat_inodes_finish(mut, metablob);
   }
 }
 
index 95710178519bec8b12db3eab3fffbe2d594e4bc2..1279440ae85d41b84f7e7539d4ffcfa631ea81c4 100644 (file)
@@ -1426,6 +1426,35 @@ inode_t *MDCache::journal_dirty_inode(Mutation *mut, EMetaBlob *metablob, CInode
 
 // nested ---------------------------------------------------------------
 
+void MDCache::project_rstat_inode_to_frag(CInode *cur, CDir *parent, snapid_t first, int linkunlink)
+{
+  CDentry *parentdn = cur->get_projected_parent_dn();
+  inode_t *curi = cur->get_projected_inode();
+
+  dout(20) << "    frag head is [" << parent->first << ",head] " << dendl;
+  dout(20) << " inode update is [" << first << "," << cur->last << "]" << dendl;
+
+  /*
+   * FIXME.  this incompletely propagates rstats to _old_ parents
+   * (i.e. shortly after a directory rename).  but we need full
+   * blown hard link backpointers to make this work properly...
+   */
+  snapid_t floor = parentdn->first;
+  dout(20) << " floor of " << floor << " from parent dn " << *parentdn << dendl;
+
+  if (cur->last >= floor)
+    project_rstat_inode_to_frag(*curi, MAX(first, floor), cur->last, parent, linkunlink);
+      
+  for (set<snapid_t>::iterator p = cur->dirty_old_rstats.begin();
+       p != cur->dirty_old_rstats.end();
+       p++) {
+    old_inode_t& old = cur->old_inodes[*p];
+    if (*p >= floor)
+      project_rstat_inode_to_frag(old.inode, MAX(old.first, floor), *p, parent);
+  }
+  cur->dirty_old_rstats.clear();
+}
+
 
 void MDCache::project_rstat_inode_to_frag(inode_t& inode, snapid_t ofirst, snapid_t last,
                                          CDir *parent, int linkunlink)
@@ -1724,7 +1753,14 @@ void MDCache::predirty_journal_parents(Mutation *mut, EMetaBlob *blob,
 
     
     // rstat
-    if (primary_dn) { 
+    if (!primary_dn) {
+      // don't update parent this pass
+    } else if (!parent->inode->nestlock.can_wrlock(-1)) {
+      dout(20) << " unwritable parent nestlock " << parent->inode->nestlock
+              << ", marking dirty rstat on " << *cur << dendl;
+      cur->mark_dirty_rstat();      
+      mds->locker->mark_updated_scatterlock(&parent->inode->nestlock);
+   } else {
       SnapRealm *prealm = parent->inode->find_snaprealm();
       
       snapid_t follows = cfollows;
@@ -1735,28 +1771,9 @@ void MDCache::predirty_journal_parents(Mutation *mut, EMetaBlob *blob,
       if (cur->first > first)
        first = cur->first;
 
-      dout(20) << "    frag head is [" << parent->first << ",head] " << dendl;
-      dout(20) << " inode update is [" << first << "," << cur->last << "]" << dendl;
+      project_rstat_inode_to_frag(cur, parent, first, linkunlink);
 
-      /*
-       * FIXME.  this incompletely propagates rstats to _old_ parents
-       * (i.e. shortly after a directory rename).  but we need full
-       * blow hard link backpointers to make this work properly...
-       */
-      snapid_t floor = parentdn->first;
-      dout(20) << " floor of " << floor << " from parent dn " << *parentdn << dendl;
-
-      if (cur->last >= floor)
-       project_rstat_inode_to_frag(*curi, MAX(first, floor), cur->last, parent, linkunlink);
-      
-      for (set<snapid_t>::iterator p = cur->dirty_old_rstats.begin();
-          p != cur->dirty_old_rstats.end();
-          p++) {
-       old_inode_t& old = cur->old_inodes[*p];
-       if (*p >= floor)
-         project_rstat_inode_to_frag(old.inode, MAX(old.first, floor), *p, parent);
-      }
-      cur->dirty_old_rstats.clear();
+      cur->clear_dirty_rstat();
     }
 
     bool stop = false;
index 07f54a2989dc670cd44c574da6227993885ce9a4..5d2b7e284a97dc7b152930c212f7e6ea310e1689 100644 (file)
@@ -589,6 +589,7 @@ public:
                          CInode **pcow_inode=0);
   inode_t *journal_dirty_inode(Mutation *mut, EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP);
 
+  void project_rstat_inode_to_frag(CInode *cur, CDir *parent, snapid_t first, int linkunlink);
   void project_rstat_inode_to_frag(inode_t& inode, snapid_t ofirst, snapid_t last,
                                   CDir *parent, int linkunlink=0);
   void project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accounted_rstat,