mds: fix replay of EFragment rollback

Remove from the uncommitted list.

Also, make uncommitted list updated unconditional: we need to do it even
if the inode wasn't already in our cache.

Also, journal the rollback with the same signedness as the prepare, so that
the descriptor/map key matches up.  Adjust signs accordingly.

Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
Sage Weil 2011-04-29 17:23:58 -07:00
parent a09eb0c33f
commit 9e4e345261
2 changed files with 26 additions and 17 deletions

View File

@ -9758,7 +9758,7 @@ void MDCache::rollback_uncommitted_fragments()
if (g_conf.mds_debug_frag)
diri->verify_dirfrags();
EFragment *le = new EFragment(mds->mdlog, EFragment::OP_ROLLBACK, diri->ino(), p->first.frag, -p->second);
EFragment *le = new EFragment(mds->mdlog, EFragment::OP_ROLLBACK, diri->ino(), p->first.frag, p->second);
mds->mdlog->start_submit_entry(le);
}
uncommitted_fragments.clear();

View File

@ -1100,28 +1100,37 @@ void ESubtreeMap::replay(MDS *mds)
void EFragment::replay(MDS *mds)
{
dout(10) << "EFragment.replay " << op_name(op) << " " << ino << " " << basefrag << " by " << bits << dendl;
list<CDir*> resultfrags;
list<Context*> waiters;
pair<dirfrag_t,int> desc(dirfrag_t(ino,basefrag), bits);
// in may be NULL if it wasn't in our cache yet. if it's a prepare
// it will be once we replay the metablob , but first we need to
// refragment anything we already have in the cache.
CInode *in = mds->mdcache->get_inode(ino);
if (in) {
list<CDir*> resultfrags;
list<Context*> waiters;
pair<dirfrag_t,int> desc(dirfrag_t(ino,basefrag), bits);
switch (op) {
case OP_PREPARE:
mds->mdcache->uncommitted_fragments.insert(desc);
case OP_ONESHOT:
switch (op) {
case OP_PREPARE:
mds->mdcache->uncommitted_fragments.insert(desc);
case OP_ONESHOT:
if (in)
mds->mdcache->adjust_dir_fragments(in, basefrag, bits, resultfrags, waiters, true);
break;
break;
case OP_COMMIT:
case OP_COMMIT:
mds->mdcache->uncommitted_fragments.erase(desc);
break;
case OP_ROLLBACK:
if (mds->mdcache->uncommitted_fragments.count(desc)) {
mds->mdcache->uncommitted_fragments.erase(desc);
break;
case OP_ROLLBACK:
mds->mdcache->adjust_dir_fragments(in, basefrag, bits, resultfrags, waiters, true);
break;
assert(in);
mds->mdcache->adjust_dir_fragments(in, basefrag, -bits, resultfrags, waiters, true);
} else {
dout(10) << " no record of prepare for " << desc << dendl;
}
break;
}
metablob.replay(mds, _segment);
if (in && g_conf.mds_debug_frag)