git: 495b1baac327 - main - Provide better diagnostic messages for bad cylinder groups.

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Fri, 26 Aug 2022 06:58:17 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=495b1baac32774e00a9a975d4cedd2aa9f7d81b2

commit 495b1baac32774e00a9a975d4cedd2aa9f7d81b2
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2022-08-26 06:56:31 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2022-08-26 06:57:56 +0000

    Provide better diagnostic messages for bad cylinder groups.
    
    Like the detailed diagnostics produced when a bad superblock
    is read, provide similar detailed diagnostics when bad
    cylinder groups are read.
    
    Reported by:  Peter Holm
    Tested by:    Peter Holm
    Sponsored by: The FreeBSD Foundation
---
 sbin/fsck_ffs/fsutil.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 57853abe5442..7d6a936c90a9 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -949,12 +949,21 @@ blzero(int fd, ufs2_daddr_t blk, long size)
  * Verify cylinder group's magic number and other parameters.  If the
  * test fails, offer an option to rebuild the whole cylinder group.
  */
+#undef CHK
+#define CHK(lhs, op, rhs, fmt)						\
+	if (lhs op rhs) {						\
+		pwarn("UFS%d superblock failed: %s (" #fmt ") %s %s ("	\
+		    #fmt ")\n", sblock.fs_magic == FS_UFS1_MAGIC ? 1 :	\
+		    2, #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs);	\
+		error = 1;						\
+	}
 int
 check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
 {
 	struct cg *cgp = cgbp->b_un.b_cg;
 	uint32_t cghash, calchash;
 	static int prevfailcg = -1;
+	int error;
 
 	/*
 	 * Extended cylinder group checks.
@@ -967,19 +976,20 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
 		calchash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
 		cgp->cg_ckhash = cghash;
 	}
-	if (cgp->cg_ckhash == calchash &&
-	    cg_chkmagic(cgp) &&
-	    cgp->cg_cgx == cg &&
-	    ((sblock.fs_magic == FS_UFS1_MAGIC &&
-	      cgp->cg_old_niblk == sblock.fs_ipg &&
-	      cgp->cg_ndblk <= sblock.fs_fpg &&
-	      cgp->cg_old_ncyl <= sblock.fs_old_cpg) ||
-	     (sblock.fs_magic == FS_UFS2_MAGIC &&
-	      cgp->cg_niblk == sblock.fs_ipg &&
-	      cgp->cg_ndblk <= sblock.fs_fpg &&
-	      cgp->cg_initediblk <= sblock.fs_ipg))) {
-		return (1);
+	error = 0;
+	CHK(cgp->cg_ckhash, !=, calchash, "%jd");
+	CHK(cg_chkmagic(cgp), ==, 0, "%jd");
+	CHK(cgp->cg_cgx, !=, cg, "%jd");
+	CHK(cgp->cg_ndblk, >, sblock.fs_fpg, "%jd");
+	if (sblock.fs_magic == FS_UFS1_MAGIC) {
+		CHK(cgp->cg_old_niblk, !=, sblock.fs_ipg, "%jd");
+		CHK(cgp->cg_old_ncyl, >, sblock.fs_old_cpg, "%jd");
+	} else if (sblock.fs_magic == FS_UFS2_MAGIC) {
+		CHK(cgp->cg_niblk, !=, sblock.fs_ipg, "%jd");
+		CHK(cgp->cg_initediblk, >, sblock.fs_ipg, "%jd");
 	}
+	if (error == 0)
+		return (1);
 	if (prevfailcg == cg)
 		return (0);
 	prevfailcg = cg;
@@ -1030,6 +1040,7 @@ check_cgmagic(int cg, struct bufarea *cgbp, int request_rebuild)
 		cgp->cg_nextfreeoff = cgp->cg_clusteroff +
 		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
 	}
+	cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
 	cgdirty(cgbp);
 	return (0);
 }