From 4748053249d8b7b319ca3b36ec5a222ba6b9acef Mon Sep 17 00:00:00 2001 From: Milind Changire Date: Thu, 1 Apr 2021 14:54:10 +0530 Subject: [PATCH] mds/scrub: background scrub error fixes Accommodate new files and raw stats errors for dirty inodes and declare scrub as passed. Fixes: https://tracker.ceph.com/issues/48805 Signed-off-by: Milind Changire --- src/mds/CInode.cc | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 6e84809ba6ee7..550de651f5e62 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -4685,8 +4685,10 @@ void CInode::validate_disk_state(CInode::validated_data *results, results->backtrace.error_str << "failed to read off disk; see retval"; // we probably have a new unwritten file! // so skip the backtrace scrub for this entry and say that all's well - if (in->is_dirty_parent()) + if (in->is_dirty_parent()) { + dout(20) << "forcing backtrace as passed since inode is dirty parent" << dendl; results->backtrace.passed = true; + } goto next; } @@ -4707,8 +4709,11 @@ void CInode::validate_disk_state(CInode::validated_data *results, << bl.length() << " bytes)!"; // we probably have a new unwritten file! // so skip the backtrace scrub for this entry and say that all's well - if (in->is_dirty_parent()) + if (in->is_dirty_parent()) { + dout(20) << "decode failed; forcing backtrace as passed since " + "inode is dirty parent" << dendl; results->backtrace.passed = true; + } goto next; } @@ -4719,10 +4724,16 @@ void CInode::validate_disk_state(CInode::validated_data *results, if (divergent || memory_newer < 0) { // we're divergent, or on-disk version is newer results->backtrace.error_str << "On-disk backtrace is divergent or newer"; - // we probably have a new unwritten file! - // so skip the backtrace scrub for this entry and say that all's well - if (divergent && in->is_dirty_parent()) + /* if the backtraces are divergent and the link count is 0, then + * most likely its a stray entry that's being purged and things are + * well and there's no reason for alarm + */ + if (divergent && (in->is_dirty_parent() || in->get_inode()->nlink == 0)) { results->backtrace.passed = true; + dout(20) << "divergent backtraces are acceptable when dn " + "is being purged or has been renamed or moved to a " + "different directory " << *in << dendl; + } } else { results->backtrace.passed = true; } @@ -4879,10 +4890,24 @@ next: results->raw_stats.error_str << "freshly-calculated rstats don't match existing ones"; } + if (in->is_dirty()) { + MDCache *mdcache = in->mdcache; // for dout() + auto ino = [this]() { return in->ino(); }; // for dout() + dout(20) << "raw stats most likely wont match since inode is dirty; " + "please rerun scrub when system is stable; " + "assuming passed for now;" << dendl; + results->raw_stats.passed = true; + } goto next; } results->raw_stats.passed = true; + { + MDCache *mdcache = in->mdcache; // for dout() + auto ino = [this]() { return in->ino(); }; // for dout() + dout(20) << "raw stats check passed on " << *in << dendl; + } + next: return true; } @@ -4937,7 +4962,7 @@ void CInode::validated_data::dump(Formatter *f) const f->dump_int("read_ret_val", raw_stats.ondisk_read_retval); f->dump_stream("ondisk_value.dirstat") << raw_stats.ondisk_value.dirstat; f->dump_stream("ondisk_value.rstat") << raw_stats.ondisk_value.rstat; - f->dump_stream("memory_value.dirrstat") << raw_stats.memory_value.dirstat; + f->dump_stream("memory_value.dirstat") << raw_stats.memory_value.dirstat; f->dump_stream("memory_value.rstat") << raw_stats.memory_value.rstat; f->dump_string("error_str", raw_stats.error_str.str()); } -- 2.39.5