From: Sage Weil Date: Wed, 3 Nov 2010 20:08:06 +0000 (-0700) Subject: mds: use helper for scatter dirfrag update; use on local dirfrags X-Git-Tag: v0.23~43^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0e079bc85dcbd5c0b506fb884fb61d1db7ac43bd;p=ceph.git mds: use helper for scatter dirfrag update; use on local dirfrags 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 --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 7f35a54ef7cf..368a1530c2b6 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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 diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 5ca8bf3d430a..b1e6ac9dc6eb 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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);