]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: log when buffers fail CRC checks even if we just recompute it
authorDarrick J. Wong <djwong@kernel.org>
Sun, 2 Jun 2024 23:32:50 +0000 (16:32 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 3 Jun 2024 18:37:42 +0000 (11:37 -0700)
We should always log metadata block CRC validation errors, even if we
decide that the block contents are ok and that we'll simply recompute
the checksum.  Without this patch, xfs_repair -n won't say anything
about crc errors on these blocks.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
repair/attr_repair.c
repair/da_util.c
repair/dir2.c

index f117f9aef9ce364ac42f38cc22258140c3642363..206a97d6684ce7e22209d2266445b0faa90683f0 100644 (file)
@@ -870,8 +870,13 @@ process_leaf_attr_level(xfs_mount_t        *mp,
                 * If block looks ok but CRC didn't match, make sure to
                 * recompute it.
                 */
-               if (!no_modify && bp->b_error == -EFSBADCRC)
-                       repair++;
+               if (bp->b_error == -EFSBADCRC) {
+                       do_warn(
+ _("bad checksum for block %u in attribute fork for inode %" PRIu64 "\n"),
+                               da_bno, ino);
+                       if (!no_modify)
+                               repair++;
+               }
 
                if (repair && !no_modify) {
                        libxfs_buf_mark_dirty(bp);
@@ -1151,8 +1156,12 @@ process_longform_attr(
                return 1;
        }
 
-       if (bp->b_error == -EFSBADCRC)
+       if (bp->b_error == -EFSBADCRC) {
+               do_warn(
+ _("bad checksum for block 0 in attribute fork for inode %" PRIu64 "\n"),
+                               ino);
                (*repair)++;
+       }
 
        /* is this block sane? */
        if (__check_attr_header(mp, bp, ino)) {
index b229422c81e8c2cbb450517aad412692e2cb8e71..7f94f401206237cbba78dd5d952482d6c178a121 100644 (file)
@@ -562,7 +562,7 @@ _("can't read %s block %u for inode %" PRIu64 "\n"),
                                FORKNAME(whichfork), dabno, cursor->ino);
                        return 1;
                }
-               if (bp->b_error == -EFSCORRUPTED || bp->b_error == -EFSBADCRC) {
+               if (bp->b_error == -EFSCORRUPTED) {
                        do_warn(
 _("corrupt %s tree block %u for inode %" PRIu64 "\n"),
                                FORKNAME(whichfork), dabno, cursor->ino);
@@ -625,9 +625,13 @@ _("bad level %d in %s block %u for inode %" PRIu64 "\n"),
                 * If block looks ok but CRC didn't match, make sure to
                 * recompute it.
                 */
-               if (!no_modify &&
-                   cursor->level[this_level].bp->b_error == -EFSBADCRC)
-                       cursor->level[this_level].dirty = 1;
+               if (cursor->level[this_level].bp->b_error == -EFSBADCRC) {
+                       do_warn(
+ _("bad checksum in %s tree block %u for inode %" PRIu64 "\n"),
+                               FORKNAME(whichfork), dabno, cursor->ino);
+                       if (!no_modify)
+                               cursor->level[this_level].dirty = 1;
+               }
 
                if (cursor->level[this_level].dirty && !no_modify) {
                        libxfs_buf_mark_dirty(cursor->level[this_level].bp);
index e46ae9ae46f71146e5fa361124d2a45347149f25..bfeaddd07d205806a4ee2645c1c4d1239eba3a4e 100644 (file)
@@ -1031,8 +1031,13 @@ _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 "\n
        rval = process_dir2_data(mp, ino, dip, ino_discovery, dirname, parent,
                bp, dot, dotdot, mp->m_dir_geo->datablk, (char *)blp, &dirty);
        /* If block looks ok but CRC didn't match, make sure to recompute it. */
-       if (!rval && bp->b_error == -EFSBADCRC)
-               dirty = 1;
+       if (bp->b_error == -EFSBADCRC) {
+               do_warn(
+ _("corrupt directory block %u for inode %" PRIu64 "\n"),
+                               mp->m_dir_geo->datablk, ino);
+               if (!rval)
+                       dirty = 1;
+       }
        if (dirty && !no_modify) {
                *repair = 1;
                libxfs_buf_mark_dirty(bp);
@@ -1208,8 +1213,14 @@ _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"),
                 * If block looks ok but CRC didn't match, make sure to
                 * recompute it.
                 */
-               if (!no_modify && bp->b_error == -EFSBADCRC)
-                       buf_dirty = 1;
+               if (bp->b_error == -EFSBADCRC) {
+                       do_warn(
+ _("bad checksum for directory leafn block %u for inode %" PRIu64 "\n"),
+                               da_bno, ino);
+                       if (!no_modify)
+                               buf_dirty = 1;
+               }
+
                ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify));
                if (buf_dirty && !no_modify) {
                        *repair = 1;
@@ -1372,10 +1383,13 @@ _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" P
                i = process_dir2_data(mp, ino, dip, ino_discovery, dirname,
                        parent, bp, dot, dotdot, (xfs_dablk_t)dbno,
                        (char *)data + mp->m_dir_geo->blksize, &dirty);
-               if (i == 0) {
+               if (i == 0)
                        good++;
-                       /* Maybe just CRC is wrong. Make sure we correct it. */
-                       if (bp->b_error == -EFSBADCRC)
+               if (bp->b_error == -EFSBADCRC) {
+                       do_warn(
+ _("bad checksum in directory data block %" PRIu64 " for inode %" PRIu64 "\n"),
+                               dbno, ino);
+                       if (i == 0)
                                dirty = 1;
                }
                if (dirty && !no_modify) {