diff options
Diffstat (limited to 'usr.sbin/makefs/ffs/mkfs.c')
-rw-r--r-- | usr.sbin/makefs/ffs/mkfs.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/usr.sbin/makefs/ffs/mkfs.c b/usr.sbin/makefs/ffs/mkfs.c index 0f8b040d6997..81e3da5725c8 100644 --- a/usr.sbin/makefs/ffs/mkfs.c +++ b/usr.sbin/makefs/ffs/mkfs.c @@ -40,9 +40,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/time.h> #include <sys/resource.h> @@ -80,6 +77,23 @@ static int count_digits(int); #define UMASK 0755 #define POWEROF2(num) (((num) & ((num) - 1)) == 0) +/* + * The definition of "struct cg" used to contain an extra field at the end + * to represent the variable-length data that followed the fixed structure. + * This had the effect of artificially limiting the number of blocks that + * newfs would put in a CG, since newfs thought that the fixed-size header + * was bigger than it really was. When we started validating that the CG + * header data actually fit into one fs block, the placeholder field caused + * a problem because it caused struct cg to be a different size depending on + * platform. The placeholder field was later removed, but this caused a + * backward compatibility problem with older binaries that still thought + * struct cg was larger, and a new file system could fail validation if + * viewed by the older binaries. To avoid this compatibility problem, we + * now artificially reduce the amount of space that the variable-length data + * can use such that new file systems will pass validation by older binaries. + */ +#define CGSIZEFUDGE 8 + static union { struct fs fs; char pad[SBLOCKSIZE]; @@ -347,7 +361,8 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp) sblock.fs_fpg = minfpg; sblock.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode), INOPB(&sblock)); - if (CGSIZE(&sblock) < (unsigned long)sblock.fs_bsize) + if (CGSIZE(&sblock) < (unsigned long)sblock.fs_bsize - + CGSIZEFUDGE) break; density -= sblock.fs_fsize; } @@ -366,9 +381,11 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp) INOPB(&sblock)); if (sblock.fs_size / sblock.fs_fpg < 1) break; - if (CGSIZE(&sblock) < (unsigned long)sblock.fs_bsize) + if (CGSIZE(&sblock) < (unsigned long)sblock.fs_bsize - + CGSIZEFUDGE) continue; - if (CGSIZE(&sblock) == (unsigned long)sblock.fs_bsize) + if (CGSIZE(&sblock) == (unsigned long)sblock.fs_bsize - + CGSIZEFUDGE) break; sblock.fs_fpg -= sblock.fs_frag; sblock.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode), @@ -529,8 +546,9 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp) initcg(cylno, tstamp, fsopts); if (cylno % nprintcols == 0) printf("\n"); - printf(" %*lld,", printcolwidth, - (long long)fsbtodb(&sblock, cgsblock(&sblock, cylno))); + printf(" %*lld%s", printcolwidth, + (long long)fsbtodb(&sblock, cgsblock(&sblock, cylno)), + cylno == sblock.fs_ncg - 1 ? "" : ","); fflush(stdout); } printf("\n"); @@ -561,13 +579,21 @@ ffs_write_superblock(struct fs *fs, const fsinfo_t *fsopts) { int size, blks, i, saveflag; uint32_t cylno; - void *space; + void *info, *space; char *wrbuf; saveflag = fs->fs_flags & FS_INTERNAL; fs->fs_flags &= ~FS_INTERNAL; - memcpy(writebuf, &sblock, sbsize); + /* + * Write out the superblock. Blank out the summary info field, as it's + * a random pointer that would make the resulting image unreproducible. + */ + info = fs->fs_si; + fs->fs_si = NULL; + memcpy(writebuf, fs, sbsize); + fs->fs_si = info; + if (fsopts->needswap) ffs_sb_swap(fs, (struct fs*)writebuf); ffs_wtfs(fs->fs_sblockloc / sectorsize, sbsize, writebuf, fsopts); @@ -633,7 +659,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 { |