X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/fe32782c0e77e3c3a489fe5e57cbab92e904ecdc..6c3d0366855a5aca3ddcfb4315750899d4094b7c:/usr/src/sbin/fsck/setup.c diff --git a/usr/src/sbin/fsck/setup.c b/usr/src/sbin/fsck/setup.c index 824494df89..fa6899f8da 100644 --- a/usr/src/sbin/fsck/setup.c +++ b/usr/src/sbin/fsck/setup.c @@ -1,33 +1,26 @@ /* - * Copyright (c) 1980, 1986 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1980, 1986, 1993 + * The Regents of the University of California. All rights reserved. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * %sccs.include.redist.c% */ #ifndef lint -static char sccsid[] = "@(#)setup.c 5.25 (Berkeley) %G%"; +static char sccsid[] = "@(#)setup.c 8.4 (Berkeley) %G%"; #endif /* not lint */ #define DKTYPENAMES #include -#include -#include +#include +#include +#include #include #include #include #include -#include +#include +#include +#include #include #include "fsck.h" @@ -35,51 +28,31 @@ struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -/* - * The size of a cylinder group is calculated by CGSIZE. The maximum size - * is limited by the fact that cylinder groups are at most one block. - * Its size is derived from the size of the maps maintained in the - * cylinder group and the (struct cg) size. - */ -#define CGSIZE(fs) \ - /* base cg */ (sizeof(struct cg) + \ - /* blktot size */ (fs)->fs_cpg * sizeof(long) + \ - /* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \ - /* inode map */ howmany((fs)->fs_ipg, NBBY) + \ - /* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY)) - -char *malloc(), *calloc(); -char *index(); struct disklabel *getdisklabel(); setup(dev) char *dev; { - dev_t rootdev; long cg, size, asked, i, j; long bmapsize; struct disklabel *lp; + off_t sizepb; struct stat statb; struct fs proto; havesb = 0; - if (stat("/", &statb) < 0) - errexit("Can't stat root\n"); - rootdev = statb.st_dev; + fswritefd = -1; if (stat(dev, &statb) < 0) { - perror(dev); - printf("Can't stat %s\n", dev); + printf("Can't stat %s: %s\n", dev, strerror(errno)); return (0); } - if ((statb.st_mode & S_IFMT) != S_IFBLK && - (statb.st_mode & S_IFMT) != S_IFCHR && - reply("file is not a block or character device; OK") == 0) - return (0); - if (rootdev == statb.st_rdev) - hotroot++; + if ((statb.st_mode & S_IFMT) != S_IFCHR) { + pfatal("%s is not a character device", dev); + if (reply("CONTINUE") == 0) + return (0); + } if ((fsreadfd = open(dev, O_RDONLY)) < 0) { - perror(dev); - printf("Can't open %s\n", dev); + printf("Can't open %s: %s\n", dev, strerror(errno)); return (0); } if (preen == 0) @@ -149,82 +122,75 @@ setup(dev) sbdirty(); } } - if (sblock.fs_interleave < 1) { + if (sblock.fs_interleave < 1 || + sblock.fs_interleave > sblock.fs_nsect) { sblock.fs_interleave); sblock.fs_interleave = 1; sbdirty(); dirty(&asblk); } } - if (sblock.fs_npsect < sblock.fs_nsect) { + if (sblock.fs_npsect < sblock.fs_nsect || + sblock.fs_npsect > sblock.fs_nsect*2) { sblock.fs_npsect); sblock.fs_npsect = sblock.fs_nsect; sbdirty(); dirty(&asblk); } } - if (cvtflag) { - if (sblock.fs_postblformat == FS_42POSTBLFMT) { - /* - * Requested to convert from old format to new format - */ - if (preen) - pwarn("CONVERTING TO NEW FILE SYSTEM FORMAT\n"); - else if (!reply("CONVERT TO NEW FILE SYSTEM FORMAT")) - return(0); - sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT; - sblock.fs_nrpos = 8; - sblock.fs_postbloff = - (char *)(&sblock.fs_opostbl[0][0]) - - (char *)(&sblock.fs_link); - sblock.fs_rotbloff = &sblock.fs_space[0] - - (u_char *)(&sblock.fs_link); - sblock.fs_cgsize = - fragroundup(&sblock, CGSIZE(&sblock)); - /* - * Planning now for future expansion. - */ -# if (BYTE_ORDER == BIG_ENDIAN) - sblock.fs_qbmask.val[0] = 0; - sblock.fs_qbmask.val[1] = ~sblock.fs_bmask; - sblock.fs_qfmask.val[0] = 0; - sblock.fs_qfmask.val[1] = ~sblock.fs_fmask; -# endif /* BIG_ENDIAN */ -# if (BYTE_ORDER == LITTLE_ENDIAN) - sblock.fs_qbmask.val[0] = ~sblock.fs_bmask; - sblock.fs_qbmask.val[1] = 0; - sblock.fs_qfmask.val[0] = ~sblock.fs_fmask; - sblock.fs_qfmask.val[1] = 0; -# endif /* LITTLE_ENDIAN */ - sbdirty(); - dirty(&asblk); - } else if (sblock.fs_postblformat == FS_DYNAMICPOSTBLFMT) { - /* - * Requested to convert from new format to old format - */ - if (sblock.fs_nrpos != 8 || sblock.fs_ipg > 2048 || - sblock.fs_cpg > 32 || sblock.fs_cpc > 16) { - printf( - "PARAMETERS OF CURRENT FILE SYSTEM DO NOT\n\t"); - errexit( - "ALLOW CONVERSION TO OLD FILE SYSTEM FORMAT\n"); - } - if (preen) - pwarn("CONVERTING TO OLD FILE SYSTEM FORMAT\n"); - else if (!reply("CONVERT TO OLD FILE SYSTEM FORMAT")) - return(0); - sblock.fs_postblformat = FS_42POSTBLFMT; - sblock.fs_cgsize = fragroundup(&sblock, - sizeof(struct ocg) + howmany(sblock.fs_fpg, NBBY)); - sbdirty(); - dirty(&asblk); - } else { - errexit("UNKNOWN FILE SYSTEM FORMAT\n"); + if (sblock.fs_inodefmt >= FS_44INODEFMT) { + newinofmt = 1; + } else { + sblock.fs_qbmask = ~sblock.fs_bmask; + sblock.fs_qfmask = ~sblock.fs_fmask; + newinofmt = 0; + } + /* + * Convert to new inode format. + */ + if (cvtlevel >= 2 && sblock.fs_inodefmt < FS_44INODEFMT) { + if (preen) + pwarn("CONVERTING TO NEW INODE FORMAT\n"); + else if (!reply("CONVERT TO NEW INODE FORMAT")) + return(0); + doinglevel2++; + sblock.fs_inodefmt = FS_44INODEFMT; + sizepb = sblock.fs_bsize; + sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1; + for (i = 0; i < NIADDR; i++) { + sizepb *= NINDIR(&sblock); + sblock.fs_maxfilesize += sizepb; } + sblock.fs_maxsymlinklen = MAXSYMLINKLEN; + sblock.fs_qbmask = ~sblock.fs_bmask; + sblock.fs_qfmask = ~sblock.fs_fmask; + sbdirty(); + dirty(&asblk); + } + /* + * Convert to new cylinder group format. + */ + if (cvtlevel >= 1 && sblock.fs_postblformat == FS_42POSTBLFMT) { + if (preen) + pwarn("CONVERTING TO NEW CYLINDER GROUP FORMAT\n"); + else if (!reply("CONVERT TO NEW CYLINDER GROUP FORMAT")) + return(0); + doinglevel1++; + sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT; + sblock.fs_nrpos = 8; + sblock.fs_postbloff = + (char *)(&sblock.fs_opostbl[0][0]) - + (char *)(&sblock.fs_firstfield); + sblock.fs_rotbloff = &sblock.fs_space[0] - + (u_char *)(&sblock.fs_firstfield); + sblock.fs_cgsize = + fragroundup(&sblock, CGSIZE(&sblock)); + sbdirty(); + dirty(&asblk); } if (asblk.b_dirty) { bcopy((char *)&sblock, (char *)&altsblock, - (int)sblock.fs_sbsize); + (size_t)sblock.fs_sbsize); flush(fswritefd, &asblk); } /* @@ -250,21 +216,40 @@ setup(dev) bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(short)); blockmap = calloc((unsigned)bmapsize, sizeof (char)); if (blockmap == NULL) { - printf("cannot alloc %d bytes for blockmap\n", bmapsize); + printf("cannot alloc %u bytes for blockmap\n", + (unsigned)bmapsize); goto badsb; } statemap = calloc((unsigned)(maxino + 1), sizeof(char)); if (statemap == NULL) { - printf("cannot alloc %d bytes for statemap\n", maxino + 1); + printf("cannot alloc %u bytes for statemap\n", + (unsigned)(maxino + 1)); + goto badsb; + } + typemap = calloc((unsigned)(maxino + 1), sizeof(char)); + if (typemap == NULL) { + printf("cannot alloc %u bytes for typemap\n", + (unsigned)(maxino + 1)); goto badsb; } lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short)); if (lncntp == NULL) { - printf("cannot alloc %d bytes for lncntp\n", - (maxino + 1) * sizeof(short)); + printf("cannot alloc %u bytes for lncntp\n", + (unsigned)(maxino + 1) * sizeof(short)); + goto badsb; + } + numdirs = sblock.fs_cstotal.cs_ndir; + inplast = 0; + listmax = numdirs + 10; + inpsort = (struct inoinfo **)calloc((unsigned)listmax, + sizeof(struct inoinfo *)); + inphead = (struct inoinfo **)calloc((unsigned)numdirs, + sizeof(struct inoinfo *)); + if (inpsort == NULL || inphead == NULL) { + printf("cannot alloc %u bytes for inphead\n", + (unsigned)numdirs * sizeof(struct inoinfo *)); goto badsb; } - bufinit(); return (1); @@ -307,6 +292,10 @@ readsb(listerr) super *= dev_bsize; dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); sblk.b_bno = super / dev_bsize; + if (bflag) { + havesb = 1; + return (1); + } /* * Set all possible fields that could differ, then do check * of whole super block against an alternate super block. @@ -315,12 +304,6 @@ readsb(listerr) getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); if (asblk.b_errs) return (0); - if (bflag) { - havesb = 1; - return (1); - } - altsblock.fs_link = sblock.fs_link; - altsblock.fs_rlink = sblock.fs_rlink; altsblock.fs_time = sblock.fs_time; altsblock.fs_cstotal = sblock.fs_cstotal; altsblock.fs_cgrotor = sblock.fs_cgrotor; @@ -346,6 +329,11 @@ readsb(listerr) altsblock.fs_interleave = sblock.fs_interleave; altsblock.fs_npsect = sblock.fs_npsect; altsblock.fs_nrpos = sblock.fs_nrpos; + altsblock.fs_state = sblock.fs_state; + altsblock.fs_qbmask = sblock.fs_qbmask; + altsblock.fs_qfmask = sblock.fs_qfmask; + altsblock.fs_state = sblock.fs_state; + altsblock.fs_maxfilesize = sblock.fs_maxfilesize; if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) { badsb(listerr, "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); @@ -363,7 +351,7 @@ badsb(listerr, s) if (!listerr) return; if (preen) - printf("%s: ", devname); + printf("%s: ", cdevname); pfatal("BAD SUPER BLOCK: %s\n", s); } @@ -436,9 +424,8 @@ getdisklabel(s, fd) if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { if (s == NULL) return ((struct disklabel *)NULL); - pwarn(""); - perror("ioctl (GDINFO)"); - errexit("%s: can't read disk label", s); + pwarn("ioctl (GCINFO): %s\n", strerror(errno)); + errexit("%s: can't read disk label\n", s); } return (&lab); }