From: Yan, Zheng Date: Fri, 20 Nov 2015 08:36:55 +0000 (+0800) Subject: mds: check dirfrag rstat when dirfrag is fetched X-Git-Tag: v10.1.0~176^2~1^2~28 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f29091b5c56b28c61760262168cca191071d9f83;p=ceph.git mds: check dirfrag rstat when dirfrag is fetched This avoids the problem that dirfrag becomes imcomplete before ValidationContinuation::_dirfrags() get called; Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index e0a06ef4965..5721cbaa3db 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1857,6 +1857,11 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map& omap, mark_complete(); state_clear(STATE_FETCHING); + if (scrub_infop && scrub_infop->need_scrub_local) { + scrub_infop->need_scrub_local = false; + scrub_local(); + } + // open & force frags while (!undef_inodes.empty()) { CInode *in = undef_inodes.front(); @@ -3059,6 +3064,7 @@ void CDir::scrub_maybe_delete_info() { if (scrub_infop && !scrub_infop->directory_scrubbing && + !scrub_infop->need_scrub_local && !scrub_infop->last_scrub_dirty && scrub_infop->dirty_scrub_stamps.empty()) { delete scrub_infop; diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 44034b8d475..857eb385168 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -253,6 +253,7 @@ public: scrub_stamps last_local; // when we last did a local scrub bool directory_scrubbing; /// safety check + bool need_scrub_local; bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode? /// these are lists of children in each stage of scrubbing @@ -263,7 +264,9 @@ public: set others_scrubbing; set others_scrubbed; - scrub_info_t() : directory_scrubbing(false), last_scrub_dirty(false) {} + scrub_info_t() : + directory_scrubbing(false), need_scrub_local(false), + last_scrub_dirty(false) {} }; /** * Call to start this CDir on a new scrub. diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index e79d5c381e7..fd8cf8485ed 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3864,7 +3864,7 @@ void CInode::validate_disk_state(CInode::validated_data *results, shadow_in->fetch(get_internal_callback(INODE)); return false; } else { - return fetch_dirfrag_rstats(); + return check_dirfrag_rstats(); } } @@ -3891,19 +3891,24 @@ void CInode::validate_disk_state(CInode::validated_data *results, return true; } } - return fetch_dirfrag_rstats(); + return check_dirfrag_rstats(); } - bool fetch_dirfrag_rstats() { + bool check_dirfrag_rstats() { MDSGatherBuilder gather(g_ceph_context); std::list frags; in->dirfragtree.get_leaves(frags); for (list::iterator p = frags.begin(); p != frags.end(); ++p) { - CDir *dirfrag = in->get_or_open_dirfrag(in->mdcache, *p); - if (!dirfrag->is_complete()) - dirfrag->fetch(gather.new_sub(), false); + CDir *dir = in->get_or_open_dirfrag(in->mdcache, *p); + if (dir->is_complete()) { + dir->scrub_local(); + } else { + dir->scrub_info(); + dir->scrub_infop->need_scrub_local = true; + dir->fetch(gather.new_sub(), false); + } } if (gather.has_subs()) { gather.set_finisher(get_internal_callback(DIRFRAGS)); @@ -3929,13 +3934,9 @@ void CInode::validate_disk_state(CInode::validated_data *results, for (compact_map::iterator p = in->dirfrags.begin(); p != in->dirfrags.end(); ++p) { - if (!p->second->is_complete()) { - results->raw_rstats.error_str << "dirfrag is INCOMPLETE despite fetching; probably too large compared to MDS cache size?\n"; - return true; - } - // FIXME!!! Don't assert out on damage! - assert(p->second->scrub_local()); - sub_info.add(p->second->fnode.accounted_rstat); + CDir *dir = p->second; + assert(dir->get_version() > 0); + sub_info.add(dir->fnode.accounted_rstat); } // ...and that their sum matches our inode settings results->raw_rstats.memory_value = in->inode.rstat;