diff options
Diffstat (limited to 'src/mds/journal.cc')
-rw-r--r-- | src/mds/journal.cc | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/src/mds/journal.cc b/src/mds/journal.cc index aeff07eb905..41a79f9fb38 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -119,6 +119,14 @@ void LogSegment::try_to_expire(MDS *mds, C_GatherBuilder &gather_bld) mds->mdcache->wait_for_uncommitted_master(*p, gather_bld.new_sub()); } + // uncommitted fragments + for (set<dirfrag_t>::iterator p = uncommitted_fragments.begin(); + p != uncommitted_fragments.end(); + ++p) { + dout(10) << "try_to_expire waiting for uncommitted fragment " << *p << dendl; + mds->mdcache->wait_for_uncommitted_fragment(*p, gather_bld.new_sub()); + } + // nudge scatterlocks for (elist<CInode*>::iterator p = dirty_dirfrag_dir.begin(); !p.end(); ++p) { CInode *in = *p; @@ -2381,7 +2389,7 @@ void EFragment::replay(MDS *mds) list<CDir*> resultfrags; list<Context*> waiters; - pair<dirfrag_t,int> desc(dirfrag_t(ino,basefrag), bits); + list<frag_t> old_frags; // 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 @@ -2390,45 +2398,56 @@ void EFragment::replay(MDS *mds) switch (op) { case OP_PREPARE: - mds->mdcache->uncommitted_fragments.insert(desc); + mds->mdcache->add_uncommitted_fragment(dirfrag_t(ino, basefrag), bits, orig_frags, _segment, &rollback); // fall-thru case OP_ONESHOT: if (in) mds->mdcache->adjust_dir_fragments(in, basefrag, bits, resultfrags, waiters, true); break; - 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); - assert(in); - mds->mdcache->adjust_dir_fragments(in, basefrag, -bits, resultfrags, waiters, true); - } else { - dout(10) << " no record of prepare for " << desc << dendl; + if (in) { + in->dirfragtree.get_leaves_under(basefrag, old_frags); + if (orig_frags.empty()) { + // old format EFragment + mds->mdcache->adjust_dir_fragments(in, basefrag, -bits, resultfrags, waiters, true); + } else { + for (list<frag_t>::iterator p = orig_frags.begin(); p != orig_frags.end(); ++p) + mds->mdcache->force_dir_fragment(in, *p); + } } + mds->mdcache->rollback_uncommitted_fragment(dirfrag_t(ino, basefrag), old_frags); + break; + + case OP_COMMIT: + case OP_FINISH: + mds->mdcache->finish_uncommitted_fragment(dirfrag_t(ino, basefrag), op); break; + + default: + assert(0); } + metablob.replay(mds, _segment); if (in && g_conf->mds_debug_frag) in->verify_dirfrags(); } void EFragment::encode(bufferlist &bl) const { - ENCODE_START(4, 4, bl); + ENCODE_START(5, 4, bl); ::encode(stamp, bl); ::encode(op, bl); ::encode(ino, bl); ::encode(basefrag, bl); ::encode(bits, bl); ::encode(metablob, bl); + ::encode(orig_frags, bl); + ::encode(rollback, bl); ENCODE_FINISH(bl); } void EFragment::decode(bufferlist::iterator &bl) { - DECODE_START_LEGACY_COMPAT_LEN(4, 4, 4, bl); + DECODE_START_LEGACY_COMPAT_LEN(5, 4, 4, bl); if (struct_v >= 2) ::decode(stamp, bl); if (struct_v >= 3) @@ -2439,6 +2458,10 @@ void EFragment::decode(bufferlist::iterator &bl) { ::decode(basefrag, bl); ::decode(bits, bl); ::decode(metablob, bl); + if (struct_v >= 5) { + ::decode(orig_frags, bl); + ::decode(rollback, bl); + } DECODE_FINISH(bl); } @@ -2462,7 +2485,19 @@ void EFragment::generate_test_instances(list<EFragment*>& ls) ls.back()->bits = 5; } +void dirfrag_rollback::encode(bufferlist &bl) const +{ + ENCODE_START(1, 1, bl); + ::encode(fnode, bl); + ENCODE_FINISH(bl); +} +void dirfrag_rollback::decode(bufferlist::iterator &bl) +{ + DECODE_START(1, bl); + ::decode(fnode, bl); + DECODE_FINISH(bl); +} |