From 7f83e3df62d57fa83e6da019d68acb33949b0ebd Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 28 Jan 2016 20:59:58 +0800 Subject: [PATCH] mds: report dirfrag stats error found by scrub Signed-off-by: Yan, Zheng --- src/mds/CDir.cc | 13 ++++++++----- src/mds/CDir.h | 7 +++++-- src/mds/CInode.cc | 11 +++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 045e5b3e0b4..f216da465d3 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -3074,6 +3074,7 @@ void CDir::scrub_maybe_delete_info() !scrub_infop->directory_scrubbing && !scrub_infop->need_scrub_local && !scrub_infop->last_scrub_dirty && + !scrub_infop->pending_scrub_error && scrub_infop->dirty_scrub_stamps.empty()) { delete scrub_infop; scrub_infop = NULL; @@ -3085,15 +3086,17 @@ bool CDir::scrub_local() assert(is_complete()); bool rval = check_rstats(true); + scrub_info(); if (rval) { - scrub_info(); scrub_infop->last_local.time = ceph_clock_now(g_ceph_context); scrub_infop->last_local.version = get_projected_version(); + scrub_infop->pending_scrub_error = false; scrub_infop->last_scrub_dirty = true; - } else if (scrub_infop && - scrub_infop->header && - scrub_infop->header->repair) { - cache->repair_dirfrag_stats(this, NULL); + } else { + scrub_infop->pending_scrub_error = true; + if (scrub_infop->header && + scrub_infop->header->repair) + cache->repair_dirfrag_stats(this, NULL); } return rval; } diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 81a1fa89d8a..386d0d8ca67 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -255,6 +255,7 @@ public: bool directory_scrubbing; /// safety check bool need_scrub_local; bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode? + bool pending_scrub_error; /// these are lists of children in each stage of scrubbing set directories_to_scrub; @@ -267,8 +268,10 @@ public: ScrubHeaderRefConst header; scrub_info_t() : - directory_scrubbing(false), need_scrub_local(false), - last_scrub_dirty(false) {} + directory_scrubbing(false), + need_scrub_local(false), + last_scrub_dirty(false), + pending_scrub_error(false) {} }; /** * Call to start this CDir on a new scrub. diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 966fa7ded64..08135a093d2 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3913,6 +3913,7 @@ next: } bool _dirfrags(int rval) { + int frags_errors = 0; // basic reporting setup results->raw_stats.checked = true; results->raw_stats.ondisk_read_retval = rval; @@ -3935,6 +3936,13 @@ next: assert(dir->get_version() > 0); nest_info.add(dir->fnode.accounted_rstat); dir_info.add(dir->fnode.accounted_fragstat); + if (dir->scrub_infop && + dir->scrub_infop->pending_scrub_error) { + dir->scrub_infop->pending_scrub_error = false; + results->raw_stats.error_str + << "dirfrag(" << p->first << ") has bad stats; "; + frags_errors++; + } } nest_info.rsubdirs++; // it gets one to account for self // ...and that their sum matches our inode settings @@ -3948,6 +3956,9 @@ next: in->mdcache->repair_inode_stats(in, NULL); goto next; } + if (frags_errors > 0) + goto next; + results->raw_stats.passed = true; next: return true;