summaryrefslogtreecommitdiff
path: root/src/mds/journal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds/journal.cc')
-rw-r--r--src/mds/journal.cc63
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);
+}