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; }