From 6e013cd675125e1d3e3992b3c286b1dce83e6965 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 15 Jan 2014 11:12:43 +0800 Subject: [PATCH] mds: properly set COMPLETE flag when merging dirfrags don't keep the COMPLETE flag when merging dirfrags during journal replay, because it's inconvenience to check if the all dirfrags under the 'basefrag' are in the cache and complete. One special case is that newly created dirfrag get fragmented, then the fragment operation get rolled back. The COMPLETE flag should be preserved in this case because the dirfrag still doesn't exist on object store. Signed-off-by: Yan, Zheng --- src/mds/CDir.cc | 5 ++++- src/mds/CDir.h | 3 +-- src/mds/MDCache.cc | 13 +++++++++++-- src/mds/MDCache.h | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index de29c6c312d..f0dc962f1f9 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -874,7 +874,7 @@ void CDir::split(int bits, list& subs, list& waiters, bool repl int n = 0; for (list::iterator p = frags.begin(); p != frags.end(); ++p) { CDir *f = new CDir(inode, *p, cache, is_auth()); - f->state_set(state & MASK_STATE_FRAGMENT_KEPT); + f->state_set(state & (MASK_STATE_FRAGMENT_KEPT | STATE_COMPLETE)); f->replica_map = replica_map; f->dir_auth = dir_auth; f->init_fragment_pins(); @@ -983,6 +983,9 @@ void CDir::merge(list& subs, list& waiters, bool replay) inode->close_dirfrag(dir->get_frag()); } + if (is_auth() && !replay) + mark_complete(); + // FIXME: merge dirty old rstat fnode.rstat.version = rstat_version; fnode.accounted_rstat = fnode.rstat; diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 3507f10b08d..30c01822f6a 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -129,8 +129,7 @@ public: |STATE_FROZENDIR |STATE_STICKY); static const unsigned MASK_STATE_FRAGMENT_KEPT = - (STATE_DIRTY | - STATE_COMPLETE | + (STATE_DIRTY| STATE_EXPORTBOUND | STATE_IMPORTBOUND); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index ee6237cd2f0..3a16ae7d548 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11572,8 +11572,15 @@ void MDCache::add_uncommitted_fragment(dirfrag_t basedirfrag, int bits, listuncommitted_fragments.insert(basedirfrag); - if (rollback) + if (rollback) { uf.rollback.swap(*rollback); + // preserve COMPLETE flag for newly created dirfrag + if (bits > 0 && basedirfrag.frag == frag_t()) { + CDir *dir = get_dirfrag(basedirfrag); + if (dir && dir->is_complete()) + uf.complete = true; + } + } } void MDCache::finish_uncommitted_fragment(dirfrag_t basedirfrag, int op) @@ -11658,6 +11665,8 @@ void MDCache::rollback_uncommitted_fragments() dir->set_version(rollback.fnode.version); dir->fnode = rollback.fnode; + if (uf.complete) + dir->mark_complete(); dir->_mark_dirty(ls); if (!(dir->fnode.rstat == dir->fnode.accounted_rstat)) { @@ -11675,7 +11684,7 @@ void MDCache::rollback_uncommitted_fragments() le->add_orig_frag(dir->get_frag()); le->metablob.add_dir_context(dir); - le->metablob.add_dir(dir, true); + le->metablob.add_dir(dir, true, uf.complete); } } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index ad0f5ff734b..6087e984742 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -942,11 +942,12 @@ private: struct ufragment { int bits; bool committed; + bool complete; LogSegment *ls; list waiters; list old_frags; bufferlist rollback; - ufragment() : bits(0), committed(false), ls(NULL) {} + ufragment() : bits(0), committed(false), complete(false), ls(NULL) {} }; map uncommitted_fragments;