]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/scrub: background scrub error fixes 40520/head
authorMilind Changire <mchangir@redhat.com>
Thu, 1 Apr 2021 09:24:10 +0000 (14:54 +0530)
committerMilind Changire <mchangir@redhat.com>
Thu, 1 Apr 2021 09:24:10 +0000 (14:54 +0530)
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 <mchangir@redhat.com>
src/mds/CInode.cc

index 6e84809ba6ee78f956b6cfcff5d1b55a41c9ef17..550de651f5e62101c84d9c30c830eb8239cf57f0 100644 (file)
@@ -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());
     }