]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use helper for scatter dirfrag update; use on local dirfrags
authorSage Weil <sage@newdream.net>
Wed, 3 Nov 2010 20:08:06 +0000 (13:08 -0700)
committerSage Weil <sage@newdream.net>
Wed, 3 Nov 2010 20:08:06 +0000 (13:08 -0700)
Any time we scatter is an opportunity to update the dirfrag with the
accounted scatter stat if it is out of date.  We should use that
opportunity even when the dirfrag is on the same node as the inode (i.e.,
not just through decode_lock_state).

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

index 7f35a54ef7cf20b2380647b7e6c7c0d69f5d528a..368a1530c2b64b5b2d561fd117f61b5704d9ddd7 100644 (file)
@@ -1164,17 +1164,6 @@ void CInode::encode_lock_state(int type, bufferlist& bl)
   }
 }
 
-struct C_Inode_FragUpdate : public Context {
-  CInode *in;
-  CDir *dir;
-  Mutation *mut;
-
-  C_Inode_FragUpdate(CInode *i, CDir *d, Mutation *m) : in(i), dir(d), mut(m) {}
-  void finish(int r) {
-    in->_finish_frag_update(dir, mut);
-  }    
-};
-
 
 /* for more info on scatterlocks, see comments by Locker::scatter_writebehind */
 
@@ -1299,40 +1288,8 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
            dout(10) << fg << " first " << dir->first << " -> " << fgfirst
                     << " on " << *dir << dendl;
            dir->first = fgfirst;
-
-           if (dir->is_frozen()) {
-             dout(10) << fg << " frozen, marking " << filelock << " stale " << *dir << dendl;
-             filelock.set_stale();
-           } else {
-             filelock.clear_stale();
-             fnode_t *pf = dir->get_projected_fnode();
-
-             if (pf->accounted_fragstat.version != fragstat.version) {
-               dout(10) << fg << " journaling accounted_fragstat update v" << fragstat.version << dendl;
-
-               MDLog *mdlog = mdcache->mds->mdlog;
-               Mutation *mut = new Mutation;
-               mut->ls = mdlog->get_current_segment();
-               EUpdate *le = new EUpdate(mdlog, "lock ifile accounted_fragstat update");
-               mdlog->start_entry(le);
-
-               pf = dir->project_fnode();
-               pf->version = dir->pre_dirty();
-               pf->accounted_fragstat = fragstat;
-               pf->fragstat.version = fragstat.version;
-               mut->add_projected_fnode(dir);
-
-               le->metablob.add_dir_context(dir);
-               le->metablob.add_dir(dir, true);
-
-               assert(!dir->is_frozen());
-               mut->auth_pin(dir);
-
-               mdlog->submit_entry(le, new C_Inode_FragUpdate(this, dir, mut));
-             } else {
-               dout(10) << fg << " accounted_fragstat unchanged at v" << fragstat.version << dendl;
-             }
-           }
+           fnode_t *pf = dir->get_projected_fnode();
+           finish_scatter_update(&filelock, dir, dirstat.version, pf->accounted_fragstat.version);
          }
        }
       }
@@ -1380,43 +1337,11 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
          }
        } else {
          if (dir && dir->is_auth()) {
-           if (dir->is_frozen()) {
-             dout(10) << fg << " frozen, marking " << nestlock << " stale " << *dir << dendl;
-             nestlock.set_stale();
-           } else {
-             nestlock.clear_stale();
-             dout(10) << fg << " first " << dir->first << " -> " << fgfirst
-                 << " on " << *dir << dendl;
-             dir->first = fgfirst;
-
-             fnode_t *pf = dir->get_projected_fnode();
-
-             if (pf->accounted_rstat.version != rstat.version) {
-               dout(10) << fg << " journaling accounted_rstat update v" << rstat.version << dendl;
-
-               MDLog *mdlog = mdcache->mds->mdlog;
-               Mutation *mut = new Mutation;
-               mut->ls = mdlog->get_current_segment();
-               EUpdate *le = new EUpdate(mdlog, "lock inest accounted_rstat update");
-               mdlog->start_entry(le);
-
-               pf = dir->project_fnode();
-               pf->version = dir->pre_dirty();
-               pf->accounted_rstat = rstat;
-               pf->rstat.version = rstat.version;
-               mut->add_projected_fnode(dir);
-
-               le->metablob.add_dir_context(dir);
-               le->metablob.add_dir(dir, true);
-
-               assert(!dir->is_frozen());
-               mut->auth_pin(dir);
-
-               mdlog->submit_entry(le, new C_Inode_FragUpdate(this, dir, mut));
-             } else {
-               dout(10) << fg << " accounted_rstat unchanged at v" << rstat.version << dendl;
-             }
-           }
+           dout(10) << fg << " first " << dir->first << " -> " << fgfirst
+                    << " on " << *dir << dendl;
+           dir->first = fgfirst;
+           fnode_t *pf = dir->get_projected_fnode();
+           finish_scatter_update(&nestlock, dir, rstat.version, pf->accounted_rstat.version);
          }
        }
       }
@@ -1459,13 +1384,6 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
   }
 }
 
-void CInode::_finish_frag_update(CDir *dir, Mutation *mut)
-{
-  dout(10) << "_finish_frag_update on " << *dir << dendl;
-  mut->apply();
-  mut->cleanup();
-  delete mut;
-}
 
 
 void CInode::clear_dirty_scattered(int type)
@@ -1530,6 +1448,83 @@ void CInode::start_scatter(ScatterLock *lock)
   }
 }
 
+struct C_Inode_FragUpdate : public Context {
+  CInode *in;
+  CDir *dir;
+  Mutation *mut;
+
+  C_Inode_FragUpdate(CInode *i, CDir *d, Mutation *m) : in(i), dir(d), mut(m) {}
+  void finish(int r) {
+    in->_finish_frag_update(dir, mut);
+  }    
+};
+
+void CInode::finish_scatter_update(ScatterLock *lock, CDir *dir,
+                                  version_t inode_version, version_t dir_accounted_version)
+{
+  frag_t fg = dir->get_frag();
+  assert(dir->is_auth());
+
+  if (dir->is_frozen()) {
+    dout(10) << "finish_scatter_update " << fg << " frozen, marking " << *lock << " stale " << *dir << dendl;
+    lock->set_stale();
+  } else {
+    lock->clear_stale();
+
+    if (dir_accounted_version != inode_version) {
+      dout(10) << "finish_scatter_update " << fg << " journaling accounted scatterstat update v" << inode_version << dendl;
+
+      MDLog *mdlog = mdcache->mds->mdlog;
+      Mutation *mut = new Mutation;
+      mut->ls = mdlog->get_current_segment();
+
+      inode_t *pi = get_projected_inode();
+      fnode_t *pf = dir->project_fnode();
+      pf->version = dir->pre_dirty();
+
+      const char *ename = 0;
+      switch (lock->get_type()) {
+      case CEPH_LOCK_IFILE:
+       pf->fragstat.version = pi->dirstat.version;
+       pf->accounted_fragstat = pf->fragstat;
+       ename = "lock ifile accounted scatter stat update";
+       break;
+      case CEPH_LOCK_INEST:
+       pf->rstat.version = pi->rstat.version;
+       pf->accounted_rstat = pf->rstat;
+       ename = "lock inest accounted scatter stat update";
+       break;
+      default:
+       assert(0);
+      }
+       
+      mut->add_projected_fnode(dir);
+
+      EUpdate *le = new EUpdate(mdlog, ename);
+      mdlog->start_entry(le);
+      le->metablob.add_dir_context(dir);
+      le->metablob.add_dir(dir, true);
+      
+      assert(!dir->is_frozen());
+      mut->auth_pin(dir);
+      
+      mdlog->submit_entry(le, new C_Inode_FragUpdate(this, dir, mut));
+    } else {
+      dout(10) << "finish_scatter_update " << fg << " accounted " << *lock
+              << " scatter stat unchanged at v" << dir_accounted_version << dendl;
+    }
+  }
+}
+
+void CInode::_finish_frag_update(CDir *dir, Mutation *mut)
+{
+  dout(10) << "_finish_frag_update on " << *dir << dendl;
+  mut->apply();
+  mut->cleanup();
+  delete mut;
+}
+
+
 /*
  * when we gather a lock, we need to assimilate dirfrag changes into the inode
  * state.  it's possible we can't update the dirfrag accounted_rstat/fragstat
index 5ca8bf3d430a8556b841d62563181bce62b4cb72..b1e6ac9dc6ebc558da684b826942426b69638a31 100644 (file)
@@ -709,6 +709,8 @@ public:
   void clear_dirty_scattered(int type);
 
   void start_scatter(ScatterLock *lock);
+  void finish_scatter_update(ScatterLock *lock, CDir *dir,
+                            version_t inode_version, version_t dir_accounted_version);
   void finish_scatter_gather_update(int type);
   void finish_scatter_gather_update_accounted(int type, Mutation *mut, EMetaBlob *metablob);