From: Sage Weil Date: Tue, 27 May 2008 15:03:43 +0000 (-0700) Subject: mds: recursive counts for anchors X-Git-Tag: v0.3~170^2~44 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c42e6f44fa1377e8b06cee70a9bf2c3cb05697aa;p=ceph.git mds: recursive counts for anchors --- diff --git a/src/include/types.h b/src/include/types.h index c9d40d899ecb..802b0f8fede3 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -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 << ")"; } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 4b7cd3efee0f..dbe467d89c49 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -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; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 272cde55aa66..1826b07fdf12 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -4753,16 +4753,15 @@ for (int i=0; i_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); } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 0049a1f3a7dd..64359f2b72ee 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -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: