]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: recursive counts for anchors
authorSage Weil <sage@newdream.net>
Tue, 27 May 2008 15:03:43 +0000 (08:03 -0700)
committerSage Weil <sage@newdream.net>
Tue, 27 May 2008 15:03:43 +0000 (08:03 -0700)
src/include/types.h
src/mds/Locker.cc
src/mds/MDCache.cc
src/mds/MDCache.h

index c9d40d899ecb109de45bb6a48f3b1dad3443a859..802b0f8fede3f605dde262616ccfbdd8120e9593 100644 (file)
@@ -203,16 +203,19 @@ struct FileLayout {
 struct frag_info_t {
   version_t version;
 
+  // this frag
   utime_t mtime;
   __u64 nfiles;        // files
   __u64 nsubdirs;      // subdirs
   __u64 size() const { return nfiles + nsubdirs; }
 
-  utime_t rctime;      // \max_{children}(ctime, nested_ctime)
+  // this frag + children
+  utime_t rctime;
   __u64 rbytes;
   __u64 rfiles;
   __u64 rsubdirs;
   __u64 rsize() const { return rfiles + rsubdirs; }
+  __u64 ranchors;  // for dirstat, includes inode's anchored flag.
 
   void take_diff(const frag_info_t &cur, frag_info_t &acc) {
     if (cur.mtime > mtime)
@@ -225,6 +228,7 @@ struct frag_info_t {
     rbytes += cur.rbytes - acc.rbytes;
     rfiles += cur.rfiles - acc.rfiles;
     rsubdirs += cur.rsubdirs - acc.rsubdirs;
+    ranchors += cur.ranchors - acc.ranchors;
     acc = cur;
     acc.version = version;
   }
@@ -236,6 +240,7 @@ struct frag_info_t {
     ::encode(rbytes, bl);
     ::encode(rfiles, bl);
     ::encode(rsubdirs, bl);
+    ::encode(ranchors, bl);
     ::encode(rctime, bl);
   }
   void decode(bufferlist::iterator &bl) {
@@ -245,6 +250,7 @@ struct frag_info_t {
     ::decode(rbytes, bl);
     ::decode(rfiles, bl);
     ::decode(rsubdirs, bl);
+    ::decode(ranchors, bl);
     ::decode(rctime, bl);
  }
 };
@@ -260,6 +266,7 @@ inline ostream& operator<<(ostream &out, const frag_info_t &f) {
             << " " << f.size() << "=" << f.nfiles << "+" << f.nsubdirs
             << " rc" << f.rctime
             << " b" << f.rbytes
+            << " a" << f.ranchors
             << " " << f.rsize() << "=" << f.rfiles << "+" << f.rsubdirs
             << ")";    
 }
index 4b7cd3efee0f26d287a0c95361786de22e30ec63..dbe467d89c49e32a28c1c00ea4a632b7f897a3cb 100644 (file)
@@ -1242,7 +1242,7 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob,
 
   inode_t *curi = in->get_projected_inode();
 
-  __s64 drbytes = 1, drfiles = 0, drsubdirs = 0;
+  __s64 drbytes = 1, drfiles = 0, drsubdirs = 0, dranchors = 0;
   utime_t rctime;
 
   // build list of inodes to wrlock, dirty, and update
@@ -1268,6 +1268,8 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob,
     if (do_parent) {
       dout(10) << "predirty_nested updating mtime/size on " << *parent << dendl;
       pf->fragstat.mtime = mut->now;
+      if (mut->now > pf->fragstat.rctime)
+       pf->fragstat.rctime = mut->now;
       if (linkunlink) {
        if (in->is_dir())
          pf->fragstat.nsubdirs += linkunlink;
@@ -1280,14 +1282,17 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob,
        drbytes = curi->dirstat.rbytes - curi->accounted_dirstat.rbytes;
        drfiles = curi->dirstat.rfiles - curi->accounted_dirstat.rfiles;
        drsubdirs = curi->dirstat.rsubdirs - curi->accounted_dirstat.rsubdirs;
+       dranchors = curi->dirstat.ranchors - curi->accounted_dirstat.ranchors;
       } else if (linkunlink < 0) {
        drbytes = 0 - curi->accounted_dirstat.rbytes;
        drfiles = 0 - curi->accounted_dirstat.rfiles;
        drsubdirs = 0 - curi->accounted_dirstat.rsubdirs;
+       dranchors = 0 - curi->accounted_dirstat.ranchors;
       } else {
        drbytes = curi->dirstat.rbytes;
        drfiles = curi->dirstat.rfiles;
        drsubdirs = curi->dirstat.rsubdirs;
+       dranchors = curi->dirstat.ranchors;
       }
       rctime = MAX(curi->ctime, curi->dirstat.rctime);
 
@@ -1297,6 +1302,7 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob,
       pf->fragstat.rbytes += drbytes;
       pf->fragstat.rfiles += drfiles;
       pf->fragstat.rsubdirs += drsubdirs;
+      pf->fragstat.ranchors += dranchors;
       pf->fragstat.rctime = rctime;
     
       curi->accounted_dirstat = curi->dirstat;
@@ -1335,7 +1341,10 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob,
     inode_t *pi = pin->project_inode();
     pi->version = pin->pre_dirty();
     pi->dirstat.version++;
+    dout(15) << "predirty_nested take_diff " << pf->fragstat << dendl;
+    dout(15) << "predirty_nested         - " << pf->accounted_fragstat << dendl;
     pi->dirstat.take_diff(pf->fragstat, pf->accounted_fragstat);
+    dout(15) << "predirty_nested     gives " << pi->dirstat << " on " << *pin << dendl;
 
     // next parent!
     cur = pin;
index 272cde55aa6677ba46f96d5df7e9ba71bd24a79a..1826b07fdf1229160e3d75be9e12fb5fe75cf0e3 100644 (file)
@@ -4753,16 +4753,15 @@ for (int i=0; i<CInode::NUM_PINS; i++) {
 // --------------------------------------------------------------------
 // ANCHORS
 
-// CREATE
-
-class C_MDC_AnchorCreatePrepared : public Context {
+class C_MDC_AnchorPrepared : public Context {
   MDCache *cache;
   CInode *in;
+  bool add;
 public:
   version_t atid;
-  C_MDC_AnchorCreatePrepared(MDCache *c, CInode *i) : cache(c), in(i) {}
+  C_MDC_AnchorPrepared(MDCache *c, CInode *i, bool a) : cache(c), in(i), add(a) {}
   void finish(int r) {
-    cache->_anchor_create_prepared(in, atid);
+    cache->_anchor_prepared(in, atid, add);
   }
 };
 
@@ -4799,77 +4798,10 @@ void MDCache::anchor_create(MDRequest *mdr, CInode *in, Context *onfinish)
   in->make_anchor_trace(trace);
   
   // do it
-  C_MDC_AnchorCreatePrepared *fin = new C_MDC_AnchorCreatePrepared(this, in);
+  C_MDC_AnchorPrepared *fin = new C_MDC_AnchorPrepared(this, in, true);
   mds->anchorclient->prepare_create(in->ino(), trace, &fin->atid, fin);
 }
 
-class C_MDC_AnchorCreateLogged : public Context {
-  MDCache *cache;
-  CInode *in;
-  version_t atid;
-  LogSegment *ls;
-public:
-  C_MDC_AnchorCreateLogged(MDCache *c, CInode *i, version_t t, LogSegment *s) : 
-    cache(c), in(i), atid(t), ls(s) {}
-  void finish(int r) {
-    cache->_anchor_create_logged(in, atid, ls);
-  }
-};
-
-void MDCache::_anchor_create_prepared(CInode *in, version_t atid)
-{
-  dout(10) << "_anchor_create_prepared " << *in << " atid " << atid << dendl;
-  assert(in->inode.anchored == false);
-
-  // update the logged inode copy
-  inode_t *pi = in->project_inode();
-  pi->anchored = true;
-  pi->version = in->pre_dirty();
-
-  // note anchor transaction
-  EUpdate *le = new EUpdate(mds->mdlog, "anchor_create");
-  le->metablob.add_dir_context(in->get_parent_dir());
-  le->metablob.add_primary_dentry(in->parent, true, 0, pi);
-  le->metablob.add_anchor_transaction(atid);
-  mds->mdlog->submit_entry(le, new C_MDC_AnchorCreateLogged(this, in, atid,
-                                                           mds->mdlog->get_current_segment()));
-}
-
-
-void MDCache::_anchor_create_logged(CInode *in, version_t atid, LogSegment *ls)
-{
-  dout(10) << "_anchor_create_logged on " << *in << dendl;
-
-  // unpin
-  assert(in->state_test(CInode::STATE_ANCHORING));
-  in->state_clear(CInode::STATE_ANCHORING);
-  in->put(CInode::PIN_ANCHORING);
-  in->auth_unpin();
-  
-  // apply update to cache
-  in->pop_and_dirty_projected_inode(ls);
-  
-  // tell the anchortable we've committed
-  mds->anchorclient->commit(atid, ls);
-
-  // trigger waiters
-  in->finish_waiting(CInode::WAIT_ANCHORED, 0);
-}
-
-
-// DESTROY
-
-class C_MDC_AnchorDestroyPrepared : public Context {
-  MDCache *cache;
-  CInode *in;
-public:
-  version_t atid;
-  C_MDC_AnchorDestroyPrepared(MDCache *c, CInode *i) : cache(c), in(i) {}
-  void finish(int r) {
-    cache->_anchor_destroy_prepared(in, atid);
-  }
-};
-
 void MDCache::anchor_destroy(CInode *in, Context *onfinish)
 {
   assert(in->is_auth());
@@ -4900,61 +4832,68 @@ void MDCache::anchor_destroy(CInode *in, Context *onfinish)
   in->auth_pin();
   
   // do it
-  C_MDC_AnchorDestroyPrepared *fin = new C_MDC_AnchorDestroyPrepared(this, in);
+  C_MDC_AnchorPrepared *fin = new C_MDC_AnchorPrepared(this, in, false);
   mds->anchorclient->prepare_destroy(in->ino(), &fin->atid, fin);
 }
 
-class C_MDC_AnchorDestroyLogged : public Context {
+class C_MDC_AnchorLogged : public Context {
   MDCache *cache;
   CInode *in;
   version_t atid;
-  LogSegment *ls;
+  Mutation *mut;
 public:
-  C_MDC_AnchorDestroyLogged(MDCache *c, CInode *i, version_t t, LogSegment *l) :
-    cache(c), in(i), atid(t), ls(l) {}
+  C_MDC_AnchorLogged(MDCache *c, CInode *i, version_t t, Mutation *m) : 
+    cache(c), in(i), atid(t), mut(m) {}
   void finish(int r) {
-    cache->_anchor_destroy_logged(in, atid, ls);
+    cache->_anchor_logged(in, atid, mut);
   }
 };
 
-void MDCache::_anchor_destroy_prepared(CInode *in, version_t atid)
+void MDCache::_anchor_prepared(CInode *in, version_t atid, bool add)
 {
-  dout(10) << "_anchor_destroy_prepared " << *in << " atid " << atid << dendl;
-
-  assert(in->inode.anchored == true);
+  dout(10) << "_anchor_create_prepared " << *in << " atid " << atid << dendl;
+  assert(in->inode.anchored == false);
 
   // update the logged inode copy
   inode_t *pi = in->project_inode();
-  pi->anchored = true;
+  if (add) {
+    pi->anchored = true;
+    pi->dirstat.ranchors++;
+  } else {
+    pi->anchored = false;
+    pi->dirstat.ranchors--;
+  }
   pi->version = in->pre_dirty();
 
-  // log + wait
-  EUpdate *le = new EUpdate(mds->mdlog, "anchor_destroy");
-  le->metablob.add_dir_context(in->get_parent_dir());
+  Mutation *mut = new Mutation;
+  mut->ls = mds->mdlog->get_current_segment();
+  EUpdate *le = new EUpdate(mds->mdlog, add ? "anchor_create":"anchor_destroy");
+  mds->locker->predirty_nested(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY);
   le->metablob.add_primary_dentry(in->parent, true, 0, pi);
   le->metablob.add_anchor_transaction(atid);
-  mds->mdlog->submit_entry(le, new C_MDC_AnchorDestroyLogged(this, in, atid, mds->mdlog->get_current_segment()));
+  mds->mdlog->submit_entry(le, new C_MDC_AnchorLogged(this, in, atid, mut));
 }
 
 
-void MDCache::_anchor_destroy_logged(CInode *in, version_t atid, LogSegment *ls)
+void MDCache::_anchor_logged(CInode *in, version_t atid, Mutation *mut)
 {
-  dout(10) << "_anchor_destroy_logged on " << *in << dendl;
-  
+  dout(10) << "_anchor_logged on " << *in << dendl;
+
   // unpin
-  assert(in->state_test(CInode::STATE_UNANCHORING));
-  in->state_clear(CInode::STATE_UNANCHORING);
-  in->put(CInode::PIN_UNANCHORING);
+  assert(in->state_test(CInode::STATE_ANCHORING));
+  in->state_clear(CInode::STATE_ANCHORING);
+  in->put(CInode::PIN_ANCHORING);
   in->auth_unpin();
   
   // apply update to cache
-  in->pop_and_dirty_projected_inode(ls);
-
+  in->pop_and_dirty_projected_inode(mut->ls);
+  mut->apply();
+  
   // tell the anchortable we've committed
-  mds->anchorclient->commit(atid, ls);
+  mds->anchorclient->commit(atid, mut->ls);
 
   // trigger waiters
-  in->finish_waiting(CInode::WAIT_UNANCHORED, 0);
+  in->finish_waiting(CInode::WAIT_ANCHORED, 0);
 }
 
 
index 0049a1f3a7ddd37d9df98ac1488d9b2a58a7d14e..64359f2b72eeff2bceec6ebb5aad1b92f18d324f 100644 (file)
@@ -697,15 +697,10 @@ public:
   void anchor_create(MDRequest *mdr, CInode *in, Context *onfinish);
   void anchor_destroy(CInode *in, Context *onfinish);
 protected:
-  void _anchor_create_prepared(CInode *in, version_t atid);
-  void _anchor_create_logged(CInode *in, version_t atid, LogSegment *ls);
-  void _anchor_destroy_prepared(CInode *in, version_t atid);
-  void _anchor_destroy_logged(CInode *in, version_t atid, LogSegment *ls);
-
-  friend class C_MDC_AnchorCreatePrepared;
-  friend class C_MDC_AnchorCreateLogged;
-  friend class C_MDC_AnchorDestroyPrepared;
-  friend class C_MDC_AnchorDestroyLogged;
+  void _anchor_prepared(CInode *in, version_t atid, bool add);
+  void _anchor_logged(CInode *in, version_t atid, Mutation *mut);
+  friend class C_MDC_AnchorPrepared;
+  friend class C_MDC_AnchorLogged;
 
   // -- stray --
 public: