From f87f7774e00a2f8aff61a4c6cbf3a3d28c162d38 Mon Sep 17 00:00:00 2001 From: pooka Date: Mon, 9 Aug 2010 17:20:57 +0000 Subject: [PATCH] Add -G, which turns consistency check errors in warnings. The current testing purpose is to create a file system with block size > MAXPHYS. (the check doesn't make that much sense anyway in these days of mobile file systems, since we're interested in MAXPHYS where we attempt to mount the file system, not where we happen to create it) --- sbin/newfs/Makefile | 3 ++- sbin/newfs/mkfs.c | 50 ++++++++++++++++++++++++++++----------------- sbin/newfs/newfs.8 | 10 ++++++--- sbin/newfs/newfs.c | 36 ++++++++++++++++++++++++-------- 4 files changed, 67 insertions(+), 32 deletions(-) diff --git a/sbin/newfs/Makefile b/sbin/newfs/Makefile index aa4b22fc601a..072b0b7a749d 100644 --- a/sbin/newfs/Makefile +++ b/sbin/newfs/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.35 2009/12/20 15:21:13 dsl Exp $ +# $NetBSD: Makefile,v 1.36 2010/08/09 17:20:57 pooka Exp $ # @(#)Makefile 8.2 (Berkeley) 3/27/94 .include @@ -12,6 +12,7 @@ DISKLABEL=${NETBSDSRCDIR}/sbin/disklabel FSCK=${NETBSDSRCDIR}/sbin/fsck MOUNT=${NETBSDSRCDIR}/sbin/mount CPPFLAGS+=-DMFS -I${.CURDIR} -I${DISKLABEL} -I${FSCK} -I${MOUNT} +CPPFLAGS+=-DGARBAGE DPADD+= ${LIBUTIL} LDADD+= -lutil diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index f1c314e71171..546274c57382 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: mkfs.c,v 1.107 2010/01/31 16:04:34 mlelstv Exp $ */ +/* $NetBSD: mkfs.c,v 1.108 2010/08/09 17:20:57 pooka Exp $ */ /* * Copyright (c) 1980, 1989, 1993 @@ -73,7 +73,7 @@ #if 0 static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95"; #else -__RCSID("$NetBSD: mkfs.c,v 1.107 2010/01/31 16:04:34 mlelstv Exp $"); +__RCSID("$NetBSD: mkfs.c,v 1.108 2010/08/09 17:20:57 pooka Exp $"); #endif #endif /* not lint */ @@ -157,6 +157,18 @@ int iobuf_memsize; /* Actual buffer size */ int fsi, fso; +static void +fserr(int num) +{ +#ifdef GARBAGE + extern int Gflag; + + if (Gflag) + return; +#endif + exit(num); +} + void mkfs(const char *fsys, int fi, int fo, mode_t mfsmode, uid_t mfsuid, gid_t mfsgid) @@ -207,12 +219,12 @@ mkfs(const char *fsys, int fi, int fo, if (sblock.fs_avgfilesize <= 0) { printf("illegal expected average file size %d\n", sblock.fs_avgfilesize); - exit(14); + fserr(14); } if (sblock.fs_avgfpdir <= 0) { printf("illegal expected number of files per directory %d\n", sblock.fs_avgfpdir); - exit(15); + fserr(15); } /* * collect and verify the block and fragment sizes @@ -222,32 +234,32 @@ mkfs(const char *fsys, int fi, int fo, if (!powerof2(sblock.fs_bsize)) { printf("block size must be a power of 2, not %d\n", sblock.fs_bsize); - exit(16); + fserr(16); } if (!powerof2(sblock.fs_fsize)) { printf("fragment size must be a power of 2, not %d\n", sblock.fs_fsize); - exit(17); + fserr(17); } if (sblock.fs_fsize < sectorsize) { printf("fragment size %d is too small, minimum is %d\n", sblock.fs_fsize, sectorsize); - exit(18); + fserr(18); } if (sblock.fs_bsize < MINBSIZE) { printf("block size %d is too small, minimum is %d\n", sblock.fs_bsize, MINBSIZE); - exit(19); + fserr(19); } if (sblock.fs_bsize > MAXBSIZE) { printf("block size %d is too large, maximum is %d\n", sblock.fs_bsize, MAXBSIZE); - exit(19); + fserr(19); } if (sblock.fs_bsize < sblock.fs_fsize) { printf("block size (%d) cannot be smaller than fragment size (%d)\n", sblock.fs_bsize, sblock.fs_fsize); - exit(20); + fserr(20); } if (maxbsize < bsize || !powerof2(maxbsize)) { @@ -282,7 +294,7 @@ mkfs(const char *fsys, int fi, int fo, "minimum with block size %d is %d\n", sblock.fs_fsize, sblock.fs_bsize, sblock.fs_bsize / MAXFRAG); - exit(21); + fserr(21); } sblock.fs_fsbtodb = ilog2(sblock.fs_fsize / sectorsize); sblock.fs_size = dbtofsb(&sblock, fssize); @@ -290,7 +302,7 @@ mkfs(const char *fsys, int fi, int fo, if ((uint64_t)sblock.fs_size >= 1ull << 31) { printf("Too many fragments (0x%" PRIx64 ") for a FFSv1 filesystem\n", sblock.fs_size); - exit(22); + fserr(22); } sblock.fs_magic = FS_UFS1_MAGIC; sblock.fs_sblockloc = SBLOCK_UFS1; @@ -353,7 +365,7 @@ mkfs(const char *fsys, int fi, int fo, if (sblock.fs_size < sblock.fs_iblkno + 3 * sblock.fs_frag) { printf("Filesystem size %lld < minimum size of %d\n", (long long)sblock.fs_size, sblock.fs_iblkno + 3 * sblock.fs_frag); - exit(23); + fserr(23); } if (num_inodes != 0) inodeblks = howmany(num_inodes, INOPB(&sblock)); @@ -420,7 +432,7 @@ mkfs(const char *fsys, int fi, int fo, if ((int)CGSIZE(&sblock) > sblock.fs_bsize) { printf("CGSIZE miscalculated %d > %d\n", (int)CGSIZE(&sblock), sblock.fs_bsize); - exit(24); + fserr(24); } sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); @@ -574,7 +586,7 @@ mkfs(const char *fsys, int fi, int fo, */ if (fssize <= 0) { printf("preposterous size %lld\n", (long long)fssize); - exit(13); + fserr(13); } wtfs(fssize - 1, sectorsize, iobuf); @@ -756,7 +768,7 @@ initcg(int cylno, const struct timeval *tv) if (dupper >= cgstart(&sblock, cylno + 1)) { printf("\rToo many cylinder groups to fit summary " "information into first cylinder group\n"); - exit(40); + fserr(40); } } memset(&acg, 0, sblock.fs_cgsize); @@ -809,7 +821,7 @@ initcg(int cylno, const struct timeval *tv) } if (acg.cg_nextfreeoff > sblock.fs_cgsize) { printf("Panic: cylinder group too big\n"); - exit(37); + fserr(37); } acg.cg_cs.cs_nifree += sblock.fs_ipg; if (cylno == 0) @@ -1228,7 +1240,7 @@ iput(union dinode *ip, ino_t ino) ffs_cg_swap(&acg, &acg, &sblock); if (acg.cg_magic != CG_MAGIC) { printf("cg 0: bad magic number\n"); - exit(31); + fserr(31); } acg.cg_cs.cs_nifree--; setbit(cg_inosused(&acg, 0), ino); @@ -1241,7 +1253,7 @@ iput(union dinode *ip, ino_t ino) if (ino >= (ino_t)(sblock.fs_ipg * sblock.fs_ncg)) { printf("fsinit: inode value out of range (%llu).\n", (unsigned long long)ino); - exit(32); + fserr(32); } d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino)); rdfs(d, sblock.fs_bsize, (char *)iobuf); diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index d8ea842c8641..aecaceb19f60 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: newfs.8,v 1.77 2010/02/21 13:26:46 wiz Exp $ +.\" $NetBSD: newfs.8,v 1.78 2010/08/09 17:20:57 pooka Exp $ .\" .\" Copyright (c) 1983, 1987, 1991, 1993, 1994 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 .\" -.Dd December 1, 2009 +.Dd August 9, 2010 .Dt NEWFS 8 .Os .Sh NAME @@ -37,7 +37,7 @@ .Nd construct a new file system .Sh SYNOPSIS .Nm -.Op Fl FINZ +.Op Fl FGINZ .Op Fl a Ar maxcontig .Op Fl B Ar byte-order .Op Fl b Ar block-size @@ -157,6 +157,10 @@ The default size depends upon the size of the file system: .El .It Fl g Ar avgfilesize The expected average file size for the file system. +.It Fl G +Treat garbage parameters as non-fatal. +Using this option may result in a file system which causes a kernel +panic and should only be used for testing. .It Fl h Ar avgfpdir The expected average number of files per directory on the file system. .It Fl I diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index 037ca6956382..7023f2bcbb00 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: newfs.c,v 1.106 2009/12/20 15:21:13 dsl Exp $ */ +/* $NetBSD: newfs.c,v 1.107 2010/08/09 17:20:57 pooka Exp $ */ /* * Copyright (c) 1983, 1989, 1993, 1994 @@ -78,7 +78,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1993, 1994\ #if 0 static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95"; #else -__RCSID("$NetBSD: newfs.c,v 1.106 2009/12/20 15:21:13 dsl Exp $"); +__RCSID("$NetBSD: newfs.c,v 1.107 2010/08/09 17:20:57 pooka Exp $"); #endif #endif /* not lint */ @@ -200,6 +200,7 @@ const char lmsg[] = "%s: can't read disk label"; int mfs; /* run as the memory based filesystem */ +int Gflag; /* allow garbage parameters (for testing) */ int Nflag; /* run without writing file system */ int Oflag = 1; /* format as an 4.3BSD file system */ int verbosity; /* amount of printf() output */ @@ -269,7 +270,7 @@ main(int argc, char *argv[]) opstring = mfs ? "NT:V:a:b:d:e:f:g:h:i:m:n:o:p:s:u:" : - "B:FINO:S:T:V:Za:b:d:e:f:g:h:i:l:m:n:o:r:s:v:"; + "B:FGINO:S:T:V:Za:b:d:e:f:g:h:i:l:m:n:o:r:s:v:"; while ((ch = getopt(argc, argv, opstring)) != -1) switch (ch) { case 'B': @@ -287,6 +288,11 @@ main(int argc, char *argv[]) case 'F': Fflag = 1; break; + case 'G': + fprintf(stderr, "WARNING: -G may create file systems " + "which cause kernel panics\n"); + Gflag = 1; + break; case 'I': Iflag = 1; break; @@ -781,12 +787,24 @@ strsuftoi64(const char *desc, const char *arg, int64_t min, int64_t max, int *nu result = r1 << shift; if (errno == ERANGE || result >> shift != r1) errx(1, "%s `%s' is too large to convert.", desc, arg); - if (result < min) - errx(1, "%s `%s' (%" PRId64 ") is less than the minimum (%" PRId64 ").", - desc, arg, result, min); - if (result > max) - errx(1, "%s `%s' (%" PRId64 ") is greater than the maximum (%" PRId64 ").", - desc, arg, result, max); + if (result < min) { + if (Gflag) { + warnx("%s `%s' (%" PRId64 ") is less than the " + "minimum (%" PRId64 ").", desc, arg, result, min); + } else { + errx(1, "%s `%s' (%" PRId64 ") is less than the " + "minimum (%" PRId64 ").", desc, arg, result, min); + } + } + if (result > max) { + if (Gflag) { + warnx("%s `%s' (%" PRId64 ") is greater than the " + "maximum (%" PRId64 ").", desc, arg, result, max); + } else { + errx(1, "%s `%s' (%" PRId64 ") is greater than the " + "maximum (%" PRId64 ").", desc, arg, result, max); + } + } return result; }