git: 62dc21b10731 - main - Additional validity checking in newfs(8).

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Sun, 30 Apr 2023 00:01:42 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=62dc21b10731bdba26dafeb51640c2048a3344a0

commit 62dc21b10731bdba26dafeb51640c2048a3344a0
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2023-04-29 19:49:50 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2023-04-30 00:01:18 +0000

    Additional validity checking in newfs(8).
    
    A check in the superblock validity code verifies that the computed
    size of the filesystem cylinder groups (CGSIZE macro) does not
    exceed the filesystem block size (fs_bsize).
    
    A report was received that a filesystem had been flagged as failing
    this check. We were unable to determine how the reported filesystem
    could have been created. This commit adds a check at the end of the
    newfs(8) command to verify that the the cylinder group size is valid.
    If an oversize cylinder group is found newfs(8) prints a diagnostic
    output and rebuilds the filesystem to make it compiliant.
    
    MFC after:   1 week
---
 sbin/newfs/mkfs.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index 16508305aa57..5af121104821 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -332,6 +332,7 @@ restart:
 	 * can put into each cylinder group. If this is too big, we reduce
 	 * the density until it fits.
 	 */
+retry:
 	maxinum = (((int64_t)(1)) << 32) - INOPB(&sblock);
 	minfragsperinode = 1 + fssize / maxinum;
 	if (density == 0) {
@@ -666,6 +667,21 @@ restart:
 		pp->p_frag = sblock.fs_frag;
 		pp->p_cpg = sblock.fs_fpg;
 	}
+	/*
+	 * This should NOT happen. If it does complain loudly and
+	 * take evasive action.
+	 */
+	if ((int32_t)CGSIZE(&sblock) > sblock.fs_bsize) {
+		printf("INTERNAL ERROR: ipg %d, fpg %d, contigsumsize %d, ",
+		    sblock.fs_ipg, sblock.fs_fpg, sblock.fs_contigsumsize);
+		printf("old_cpg %d, size_cg %jd, CGSIZE %jd\n",
+		    sblock.fs_old_cpg, sizeof(struct cg), CGSIZE(&sblock));
+		printf("Please file a FreeBSD bug report and include this "
+		    "output\n");
+		maxblkspercg = fragstoblks(&sblock, sblock.fs_fpg) - 1;
+		density = 0;
+		goto retry;
+	}
 }
 
 /*