git: 0a6e34e950cd - main - Fix size differences between architectures of the UFS/FFS CGSIZE macro value.

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Mon, 15 May 2023 19:57:27 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=0a6e34e950cd5889122a199c34519b67569be9cc

commit 0a6e34e950cd5889122a199c34519b67569be9cc
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2023-05-15 19:56:27 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2023-05-15 19:57:15 +0000

    Fix size differences between architectures of the UFS/FFS CGSIZE macro value.
    
    The cylinder group header structure ended with `u_int8_t cg_space[1]'
    representing the beginning of the inode bitmap array. Some architectures
    like the i386 rounded this up to a 4-byte boundry while other
    architectures like the amd64 rounded it up to an 8-byte boundry.
    Thus sizeof(struct cg) was four bytes bigger on an amd64 machine
    than on an i386 machine. If a filesystem created on an i386 machine
    was moved to an amd64 machine, the size of the cylinder group
    calculated by the CGSIZE macro would appear to grow by four bytes.
    Filesystems whose cylinder groups were exactly equal to the block
    size on an i386 machine would appear to have a cylinder group that
    was four bytes too big when moved to an amd64 machine. Note that
    although the structure appears to be too big, it in fact is fine.
    It is just the calaculation of its size that is in error.
    
    The fix is to remove the cg_space element from the cylinder-group
    structure so that the calculated size of the structure is the same
    size on all architectures.
    
    Reported by:  Tijl Coosemans
    Tested by:    Tijl Coosemans and Peter Holm
    MFC after:    1 week
    Sponsored by: The FreeBSD Foundation
---
 sbin/fsck_ffs/fsutil.c     | 4 ++--
 sbin/fsck_ffs/pass5.c      | 4 ++--
 sbin/growfs/growfs.c       | 2 +-
 sbin/newfs/mkfs.c          | 5 +++--
 sys/ufs/ffs/fs.h           | 7 +++----
 usr.sbin/makefs/ffs/mkfs.c | 2 +-
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index 48810954ba94..5e60aecf1826 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -1038,7 +1038,7 @@ check_cgmagic(int cg, struct bufarea *cgbp)
 		CHK(cgp->cg_ndblk, !=, sblock.fs_size - cgbase(&sblock, cg),
 		    "%jd");
 	}
-	start = &cgp->cg_space[0] - (u_char *)(&cgp->cg_firstfield);
+	start = sizeof(*cgp);
 	if (sblock.fs_magic == FS_UFS2_MAGIC) {
 		CHK(cgp->cg_iusedoff, !=, start, "%jd");
 	} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
@@ -1098,7 +1098,7 @@ rebuild_cg(int cg, struct bufarea *cgbp)
 		cgp->cg_ndblk = sblock.fs_fpg;
 	else
 		cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
-	start = &cgp->cg_space[0] - (u_char *)(&cgp->cg_firstfield);
+	start = sizeof(*cgp);
 	if (sblock.fs_magic == FS_UFS2_MAGIC) {
 		cgp->cg_iusedoff = start;
 	} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 61be54ed54ed..58143a0e8211 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -116,7 +116,7 @@ pass5(void)
 			}
 		}
 	}
-	basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
+	basesize = sizeof(*newcg);
 	if (sblock.fs_magic == FS_UFS2_MAGIC) {
 		newcg->cg_iusedoff = basesize;
 	} else {
@@ -131,7 +131,7 @@ pass5(void)
 		    fs->fs_old_cpg * sizeof(int32_t);
 		newcg->cg_iusedoff = newcg->cg_old_boff +
 		    fs->fs_old_cpg * fs->fs_old_nrpos * sizeof(u_int16_t);
-		memset(&newcg->cg_space[0], 0, newcg->cg_iusedoff - basesize);
+		memset(&newcg[1], 0, newcg->cg_iusedoff - basesize);
 	}
 	inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
 	newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize;
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 93a51d03b18d..51bf997406d0 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -338,7 +338,7 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
 	acg.cg_ndblk = dmax - cbase;
 	if (sblock.fs_contigsumsize > 0)
 		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
-	start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
+	start = sizeof(acg);
 	if (sblock.fs_magic == FS_UFS2_MAGIC) {
 		acg.cg_iusedoff = start;
 	} else {
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index d8580a789b1d..adc64f47cac6 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -721,7 +721,7 @@ initcg(int cylno, time_t utime)
 	acg.cg_ndblk = dmax - cbase;
 	if (sblock.fs_contigsumsize > 0)
 		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
-	start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
+	start = sizeof(acg);
 	if (Oflag == 2) {
 		acg.cg_iusedoff = start;
 	} else {
@@ -749,7 +749,8 @@ initcg(int cylno, time_t utime)
 		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
 	}
 	if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
-		printf("Panic: cylinder group too big\n");
+		printf("Panic: cylinder group too big by %d bytes\n",
+		    acg.cg_nextfreeoff - (unsigned)sblock.fs_cgsize);
 		exit(37);
 	}
 	acg.cg_cs.cs_nifree += sblock.fs_ipg;
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index c2279c183fc5..7b7a1f9f2ef6 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -573,11 +573,11 @@ CTASSERT(sizeof(struct fs) == 1376);
  * cylinder group and the (struct cg) size.
  */
 #define	CGSIZE(fs) \
-    /* base cg */	(sizeof(struct cg) + sizeof(int32_t) + \
+    /* base cg */	(sizeof(struct cg) + \
     /* old btotoff */	(fs)->fs_old_cpg * sizeof(int32_t) + \
     /* old boff */	(fs)->fs_old_cpg * sizeof(u_int16_t) + \
     /* inode map */	howmany((fs)->fs_ipg, NBBY) + \
-    /* block map */	howmany((fs)->fs_fpg, NBBY) +\
+    /* block map */	howmany((fs)->fs_fpg, NBBY) + sizeof(int32_t) + \
     /* if present */	((fs)->fs_contigsumsize <= 0 ? 0 : \
     /* cluster sum */	(fs)->fs_contigsumsize * sizeof(int32_t) + \
     /* cluster map */	howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY)))
@@ -624,8 +624,7 @@ struct cg {
 	u_int32_t cg_ckhash;		/* check-hash of this cg */
 	ufs_time_t cg_time;		/* time last written */
 	int64_t	 cg_sparecon64[3];	/* reserved for future use */
-	u_int8_t cg_space[1];		/* space for cylinder group maps */
-/* actually longer */
+	/* actually longer - space used for cylinder group maps */
 };
 
 /*
diff --git a/usr.sbin/makefs/ffs/mkfs.c b/usr.sbin/makefs/ffs/mkfs.c
index ef745fe3c196..d48dc65aac68 100644
--- a/usr.sbin/makefs/ffs/mkfs.c
+++ b/usr.sbin/makefs/ffs/mkfs.c
@@ -634,7 +634,7 @@ initcg(uint32_t cylno, time_t utime, const fsinfo_t *fsopts)
 	acg.cg_ndblk = dmax - cbase;
 	if (sblock.fs_contigsumsize > 0)
 		acg.cg_nclusterblks = acg.cg_ndblk >> sblock.fs_fragshift;
-	start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
+	start = sizeof(acg);
 	if (Oflag == 2) {
 		acg.cg_iusedoff = start;
 	} else {