diff options
author | peter <peter@FreeBSD.org> | 1997-03-11 11:59:39 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1997-03-11 11:59:39 +0000 |
commit | 5e2372f7211e467141b4939f21d1f81da257c059 (patch) | |
tree | e8158ebc8b78a9fecf4669c3f4f70905fd33f736 /sbin/fsck | |
parent | e0e06d68d52707cbac25844a417ab6919613e9eb (diff) | |
download | FreeBSD-src-5e2372f7211e467141b4939f21d1f81da257c059.zip FreeBSD-src-5e2372f7211e467141b4939f21d1f81da257c059.tar.gz |
Import some CSRG 4.4BSD-Lite2 components for sbin onto vendor branch.
(note that some of these have already been imported, this is a no-op)
Diffstat (limited to 'sbin/fsck')
-rw-r--r-- | sbin/fsck/Makefile | 3 | ||||
-rw-r--r-- | sbin/fsck/dir.c | 128 | ||||
-rw-r--r-- | sbin/fsck/fsck.8 | 16 | ||||
-rw-r--r-- | sbin/fsck/fsck.h | 119 | ||||
-rw-r--r-- | sbin/fsck/inode.c | 73 | ||||
-rw-r--r-- | sbin/fsck/main.c | 80 | ||||
-rw-r--r-- | sbin/fsck/pass1.c | 52 | ||||
-rw-r--r-- | sbin/fsck/pass1b.c | 13 | ||||
-rw-r--r-- | sbin/fsck/pass2.c | 83 | ||||
-rw-r--r-- | sbin/fsck/pass3.c | 5 | ||||
-rw-r--r-- | sbin/fsck/pass4.c | 17 | ||||
-rw-r--r-- | sbin/fsck/pass5.c | 73 | ||||
-rw-r--r-- | sbin/fsck/preen.c | 90 | ||||
-rw-r--r-- | sbin/fsck/setup.c | 96 | ||||
-rw-r--r-- | sbin/fsck/utilities.c | 178 |
15 files changed, 680 insertions, 346 deletions
diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile index 224f6b2..7186560 100644 --- a/sbin/fsck/Makefile +++ b/sbin/fsck/Makefile @@ -1,9 +1,10 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 +# @(#)Makefile 8.2 (Berkeley) 4/27/95 PROG= fsck MAN8= fsck.0 SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c +CFLAGS+=-W .PATH: ${.CURDIR}/../../sys/ufs/ffs .include <bsd.prog.mk> diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c index ee5d095..f9b8b63 100644 --- a/sbin/fsck/dir.c +++ b/sbin/fsck/dir.c @@ -32,16 +32,19 @@ */ #ifndef lint -static char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> -#include <stdlib.h> + +#include <err.h> #include <string.h> + #include "fsck.h" char *lfname = "lost+found"; @@ -56,12 +59,19 @@ struct odirtemplate odirhead = { 0, DIRBLKSIZ - 12, 2, ".." }; -struct direct *fsck_readdir(); -struct bufarea *getdirblk(); +static int chgino __P((struct inodesc *)); +static int dircheck __P((struct inodesc *, struct direct *)); +static int expanddir __P((struct dinode *dp, char *name)); +static void freedir __P((ino_t ino, ino_t parent)); +static struct direct *fsck_readdir __P((struct inodesc *)); +static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size)); +static int lftempname __P((char *bufp, ino_t ino)); +static int mkentry __P((struct inodesc *)); /* * Propagate connected state through the tree. */ +void propagate() { register struct inoinfo **inpp, *inp; @@ -87,6 +97,7 @@ propagate() /* * Scan each entry in a directory block. */ +int dirscan(idesc) register struct inodesc *idesc; { @@ -97,7 +108,7 @@ dirscan(idesc) char dbuf[DIRBLKSIZ]; if (idesc->id_type != DATA) - errexit("wrong type to dirscan %d\n", idesc->id_type); + errx(EEXIT, "wrong type to dirscan %d", idesc->id_type); if (idesc->id_entryno == 0 && (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0) idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ); @@ -109,7 +120,7 @@ dirscan(idesc) idesc->id_loc = 0; for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { dsize = dp->d_reclen; - bcopy((char *)dp, dbuf, (size_t)dsize); + memmove(dbuf, dp, (size_t)dsize); # if (BYTE_ORDER == LITTLE_ENDIAN) if (!newinofmt) { struct direct *tdp = (struct direct *)dbuf; @@ -134,7 +145,7 @@ dirscan(idesc) } # endif bp = getdirblk(idesc->id_blkno, blksiz); - bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize, + memmove(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf, (size_t)dsize); dirty(bp); sbdirty(); @@ -148,7 +159,7 @@ dirscan(idesc) /* * get next entry in a directory. */ -struct direct * +static struct direct * fsck_readdir(idesc) register struct inodesc *idesc; { @@ -163,6 +174,8 @@ fsck_readdir(idesc) dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); if (dircheck(idesc, dp)) goto dpok; + if (idesc->id_fix == IGNORE) + return (0); fix = dofix(idesc, "DIRECTORY CORRUPTED"); bp = getdirblk(idesc->id_blkno, blksiz); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); @@ -192,6 +205,8 @@ dpok: size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); idesc->id_loc += size; idesc->id_filesize -= size; + if (idesc->id_fix == IGNORE) + return (0); fix = dofix(idesc, "DIRECTORY CORRUPTED"); bp = getdirblk(idesc->id_blkno, blksiz); dp = (struct direct *)(bp->b_un.b_buf + dploc); @@ -206,6 +221,7 @@ dpok: * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */ +static int dircheck(idesc, dp) struct inodesc *idesc; register struct direct *dp; @@ -215,8 +231,15 @@ dircheck(idesc, dp) u_char namlen, type; int spaceleft; - size = DIRSIZ(!newinofmt, dp); spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); + if (dp->d_ino >= maxino || + dp->d_reclen == 0 || + dp->d_reclen > spaceleft || + (dp->d_reclen & 0x3) != 0) + return (0); + if (dp->d_ino == 0) + return (1); + size = DIRSIZ(!newinofmt, dp); # if (BYTE_ORDER == LITTLE_ENDIAN) if (!newinofmt) { type = dp->d_namlen; @@ -229,25 +252,20 @@ dircheck(idesc, dp) namlen = dp->d_namlen; type = dp->d_type; # endif - if (dp->d_ino < maxino && - dp->d_reclen != 0 && - dp->d_reclen <= spaceleft && - (dp->d_reclen & 0x3) == 0 && - dp->d_reclen >= size && - idesc->id_filesize >= size && - namlen <= MAXNAMLEN && - type <= 15) { - if (dp->d_ino == 0) - return (1); - for (cp = dp->d_name, size = 0; size < namlen; size++) - if (*cp == 0 || (*cp++ == '/')) - return (0); - if (*cp == 0) - return (1); - } - return (0); + if (dp->d_reclen < size || + idesc->id_filesize < size || + namlen > MAXNAMLEN || + type > 15) + return (0); + for (cp = dp->d_name, size = 0; size < namlen; size++) + if (*cp == '\0' || (*cp++ == '/')) + return (0); + if (*cp != '\0') + return (0); + return (1); } +void direrror(ino, errmesg) ino_t ino; char *errmesg; @@ -256,6 +274,7 @@ direrror(ino, errmesg) fileerror(ino, ino, errmesg); } +void fileerror(cwd, ino, errmesg) ino_t cwd, ino; char *errmesg; @@ -279,9 +298,10 @@ fileerror(cwd, ino, errmesg) pfatal("NAME=%s\n", pathbuf); } +void adjust(idesc, lcnt) register struct inodesc *idesc; - short lcnt; + int lcnt; { register struct dinode *dp; @@ -309,6 +329,7 @@ adjust(idesc, lcnt) } } +static int mkentry(idesc) struct inodesc *idesc; { @@ -328,22 +349,38 @@ mkentry(idesc) dirp->d_reclen = oldlen; dirp = (struct direct *)(((char *)dirp) + oldlen); dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ + dirp->d_reclen = newent.d_reclen; if (newinofmt) dirp->d_type = typemap[idesc->id_parent]; else dirp->d_type = 0; - dirp->d_reclen = newent.d_reclen; dirp->d_namlen = newent.d_namlen; - bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1); + memmove(dirp->d_name, idesc->id_name, (size_t)newent.d_namlen + 1); +# if (BYTE_ORDER == LITTLE_ENDIAN) + /* + * If the entry was split, dirscan() will only reverse the byte + * order of the original entry, and not the new one, before + * writing it back out. So, we reverse the byte order here if + * necessary. + */ + if (oldlen != 0 && !newinofmt && !doinglevel2) { + u_char tmp; + + tmp = dirp->d_namlen; + dirp->d_namlen = dirp->d_type; + dirp->d_type = tmp; + } +# endif return (ALTERED|STOP); } +static int chgino(idesc) struct inodesc *idesc; { register struct direct *dirp = idesc->id_dirp; - if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1)) + if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1)) return (KEEPON); dirp->d_ino = idesc->id_parent; if (newinofmt) @@ -353,6 +390,7 @@ chgino(idesc) return (ALTERED|STOP); } +int linkup(orphan, parentdir) ino_t orphan; ino_t parentdir; @@ -364,7 +402,7 @@ linkup(orphan, parentdir) char tempname[BUFSIZ]; extern int pass4check(); - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); dp = ginode(orphan); lostdir = (dp->di_mode & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); @@ -460,6 +498,7 @@ linkup(orphan, parentdir) /* * fix an entry in a directory. */ +int changeino(dir, name, newnum) ino_t dir; char *name; @@ -467,7 +506,7 @@ changeino(dir, name, newnum) { struct inodesc idesc; - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = DATA; idesc.id_func = chgino; idesc.id_number = dir; @@ -480,6 +519,7 @@ changeino(dir, name, newnum) /* * make an entry in a directory */ +int makeentry(parent, ino, name) ino_t parent, ino; char *name; @@ -491,7 +531,7 @@ makeentry(parent, ino, name) if (parent < ROOTINO || parent >= maxino || ino < ROOTINO || ino >= maxino) return (0); - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = DATA; idesc.id_func = mkentry; idesc.id_number = parent; @@ -515,11 +555,12 @@ makeentry(parent, ino, name) /* * Attempt to expand the size of a directory */ +static int expanddir(dp, name) register struct dinode *dp; char *name; { - daddr_t lastbn, newblk; + ufs_daddr_t lastbn, newblk; register struct bufarea *bp; char *cp, firstblk[DIRBLKSIZ]; @@ -536,21 +577,21 @@ expanddir(dp, name) (long)dblksize(&sblock, dp, lastbn + 1)); if (bp->b_errs) goto bad; - bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ); + memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ); bp = getdirblk(newblk, sblock.fs_bsize); if (bp->b_errs) goto bad; - bcopy(firstblk, bp->b_un.b_buf, DIRBLKSIZ); + memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ); for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp += DIRBLKSIZ) - bcopy((char *)&emptydir, cp, sizeof emptydir); + memmove(cp, &emptydir, sizeof emptydir); dirty(bp); bp = getdirblk(dp->di_db[lastbn + 1], (long)dblksize(&sblock, dp, lastbn + 1)); if (bp->b_errs) goto bad; - bcopy((char *)&emptydir, bp->b_un.b_buf, sizeof emptydir); + memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir); pwarn("NO SPACE LEFT IN %s", name); if (preen) printf(" (EXPANDED)\n"); @@ -571,6 +612,7 @@ bad: /* * allocate a new directory */ +ino_t allocdir(parent, request, mode) ino_t parent, request; int mode; @@ -594,11 +636,11 @@ allocdir(parent, request, mode) freeino(ino); return (0); } - bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate)); + memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate)); for (cp = &bp->b_un.b_buf[DIRBLKSIZ]; cp < &bp->b_un.b_buf[sblock.fs_fsize]; cp += DIRBLKSIZ) - bcopy((char *)&emptydir, cp, sizeof emptydir); + memmove(cp, &emptydir, sizeof emptydir); dirty(bp); dp->di_nlink = 2; inodirty(); @@ -626,6 +668,7 @@ allocdir(parent, request, mode) /* * free a directory inode */ +static void freedir(ino, parent) ino_t ino, parent; { @@ -642,6 +685,7 @@ freedir(ino, parent) /* * generate a temporary name for the lost+found directory. */ +static int lftempname(bufp, ino) char *bufp; ino_t ino; @@ -668,9 +712,9 @@ lftempname(bufp, ino) * Get a directory block. * Insure that it is held until another is requested. */ -struct bufarea * +static struct bufarea * getdirblk(blkno, size) - daddr_t blkno; + ufs_daddr_t blkno; long size; { diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8 index cf8c499..fd3ff07 100644 --- a/sbin/fsck/fsck.8 +++ b/sbin/fsck/fsck.8 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 +.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 .\" -.Dd December 11, 1993 +.Dd May 9, 1995 .Dt FSCK 8 .Os BSD 4 .Sh NAME @@ -71,6 +71,12 @@ running one process per disk drive. The disk drive containing each filesystem is inferred from the longest prefix of the device name that ends in a digit; the remaining characters are assumed to be the partition designator. +In preening mode, +filesystems that are marked clean are skipped. +Filesystems are marked clean when they are unmounted, +when they have been mounted read-only, or when +.Nm fsck +runs on them successfully. .Pp The kernel takes care that only a restricted class of innocuous filesystem inconsistencies can happen unless hardware or software failures intervene. @@ -181,7 +187,7 @@ do not open the filesystem for writing. Convert the filesystem to the specified level. Note that the level of a filesystem can only be raised. .Bl -tag -width indent -There are currently three levels defined: +There are currently four levels defined: .It 0 The filesystem is in the old (static table) format. .It 1 @@ -190,6 +196,10 @@ The filesystem is in the new (dynamic table) format. The filesystem supports 32-bit uid's and gid's, short symbolic links are stored in the inode, and directories have an added field showing the file type. +.It 3 +If maxcontig is greater than one, +build the free segment maps to aid in finding contiguous sets of blocks. +If maxcontig is equal to one, delete any existing segment maps. .El .Pp In interactive mode, diff --git a/sbin/fsck/fsck.h b/sbin/fsck/fsck.h index 7fa831f..21b3658 100644 --- a/sbin/fsck/fsck.h +++ b/sbin/fsck/fsck.h @@ -30,9 +30,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)fsck.h 8.1 (Berkeley) 6/5/93 + * @(#)fsck.h 8.4 (Berkeley) 5/9/95 */ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + #define MAXDUP 10 /* limit on dup blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ @@ -53,20 +57,20 @@ * buffer cache structure. */ struct bufarea { - struct bufarea *b_next; /* free list queue */ - struct bufarea *b_prev; /* free list queue */ - daddr_t b_bno; - int b_size; - int b_errs; - int b_flags; + struct bufarea *b_next; /* free list queue */ + struct bufarea *b_prev; /* free list queue */ + ufs_daddr_t b_bno; + int b_size; + int b_errs; + int b_flags; union { - char *b_buf; /* buffer space */ - daddr_t *b_indir; /* indirect block */ - struct fs *b_fs; /* super block */ - struct cg *b_cg; /* cylinder group */ - struct dinode *b_dinode; /* inode block */ + char *b_buf; /* buffer space */ + ufs_daddr_t *b_indir; /* indirect block */ + struct fs *b_fs; /* super block */ + struct cg *b_cg; /* cylinder group */ + struct dinode *b_dinode; /* inode block */ } b_un; - char b_dirty; + char b_dirty; }; #define B_INUSE 1 @@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */ struct bufarea cgblk; /* cylinder group blocks */ struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pbp; /* current inode block */ -struct bufarea *getdatablk(); #define dirty(bp) (bp)->b_dirty = 1 #define initbarea(bp) \ (bp)->b_dirty = 0; \ - (bp)->b_bno = (daddr_t)-1; \ + (bp)->b_bno = (ufs_daddr_t)-1; \ (bp)->b_flags = 0; #define sbdirty() sblk.b_dirty = 1 @@ -97,7 +100,7 @@ struct inodesc { int (*id_func)(); /* function to be applied to blocks of inode */ ino_t id_number; /* inode number described */ ino_t id_parent; /* for DATA nodes, their parent */ - daddr_t id_blkno; /* current block number being examined */ + ufs_daddr_t id_blkno; /* current block number being examined */ int id_numfrags; /* number of frags contained in block */ quad_t id_filesize; /* for DATA nodes, the size of the directory */ int id_loc; /* for DATA nodes, current location in dir */ @@ -133,7 +136,7 @@ struct inodesc { */ struct dups { struct dups *next; - daddr_t dup; + ufs_daddr_t dup; }; struct dups *duplist; /* head of dup list */ struct dups *muldup; /* end of unique duplicate dup block numbers */ @@ -157,7 +160,7 @@ struct inoinfo { ino_t i_dotdot; /* inode number of `..' */ size_t i_isize; /* size of inode */ u_int i_numblks; /* size of block array in bytes */ - daddr_t i_blks[1]; /* actually longer */ + ufs_daddr_t i_blks[1]; /* actually longer */ } **inphead, **inpsort; long numdirs, listmax, inplast; @@ -179,20 +182,20 @@ int fsmodified; /* 1 => write done to file system */ int fsreadfd; /* file descriptor for reading file system */ int fswritefd; /* file descriptor for writing file system */ -daddr_t maxfsblock; /* number of blocks in the file system */ +ufs_daddr_t maxfsblock; /* number of blocks in the file system */ char *blockmap; /* ptr to primary blk allocation map */ ino_t maxino; /* number of inodes in file system */ ino_t lastino; /* last inode in use */ char *statemap; /* ptr to inode state table */ -char *typemap; /* ptr to inode type table */ +u_char *typemap; /* ptr to inode type table */ short *lncntp; /* ptr to link count table */ ino_t lfdir; /* lost & found directory inode number */ char *lfname; /* lost & found directory name */ int lfmode; /* lost & found directory creation mode */ -daddr_t n_blks; /* number of blocks in use */ -daddr_t n_files; /* number of files in use */ +ufs_daddr_t n_blks; /* number of blocks in use */ +ufs_daddr_t n_files; /* number of files in use */ #define clearinode(dp) (*(dp) = zino) struct dinode zino; @@ -207,9 +210,69 @@ struct dinode zino; #define ALTERED 0x08 #define FOUND 0x10 -time_t time(); -struct dinode *ginode(); -struct inoinfo *getinoinfo(); -void getblk(); -ino_t allocino(); -int findino(); +#define EEXIT 8 /* Standard error exit. */ + +struct fstab; + +void adjust __P((struct inodesc *, int lcnt)); +ufs_daddr_t allocblk __P((long frags)); +ino_t allocdir __P((ino_t parent, ino_t request, int mode)); +ino_t allocino __P((ino_t request, int type)); +void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk)); +char *blockcheck __P((char *name)); +int bread __P((int fd, char *buf, ufs_daddr_t blk, long size)); +void bufinit __P((void)); +void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size)); +void cacheino __P((struct dinode *dp, ino_t inumber)); +void catch __P((int)); +void catchquit __P((int)); +int changeino __P((ino_t dir, char *name, ino_t newnum)); +int checkfstab __P((int preen, int maxrun, + int (*docheck)(struct fstab *), + int (*chkit)(char *, char *, long, int))); +int chkrange __P((ufs_daddr_t blk, int cnt)); +void ckfini __P((int markclean)); +int ckinode __P((struct dinode *dp, struct inodesc *)); +void clri __P((struct inodesc *, char *type, int flag)); +void direrror __P((ino_t ino, char *errmesg)); +int dirscan __P((struct inodesc *)); +int dofix __P((struct inodesc *, char *msg)); +void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t)); +void ffs_fragacct __P((struct fs *, int, int32_t [], int)); +int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t)); +void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t)); +void fileerror __P((ino_t cwd, ino_t ino, char *errmesg)); +int findino __P((struct inodesc *)); +int findname __P((struct inodesc *)); +void flush __P((int fd, struct bufarea *bp)); +void freeblk __P((ufs_daddr_t blkno, long frags)); +void freeino __P((ino_t ino)); +void freeinodebuf __P((void)); +int ftypeok __P((struct dinode *dp)); +void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size)); +struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size)); +struct inoinfo *getinoinfo __P((ino_t inumber)); +struct dinode *getnextinode __P((ino_t inumber)); +void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); +struct dinode *ginode __P((ino_t inumber)); +void inocleanup __P((void)); +void inodirty __P((void)); +int linkup __P((ino_t orphan, ino_t parentdir)); +int makeentry __P((ino_t parent, ino_t ino, char *name)); +void panic __P((const char *fmt, ...)); +void pass1 __P((void)); +void pass1b __P((void)); +int pass1check __P((struct inodesc *)); +void pass2 __P((void)); +void pass3 __P((void)); +void pass4 __P((void)); +int pass4check __P((struct inodesc *)); +void pass5 __P((void)); +void pfatal __P((const char *fmt, ...)); +void pinode __P((ino_t ino)); +void propagate __P((void)); +void pwarn __P((const char *fmt, ...)); +int reply __P((char *question)); +void resetinodebuf __P((void)); +int setup __P((char *dev)); +void voidquit __P((int)); diff --git a/sbin/fsck/inode.c b/sbin/fsck/inode.c index f1c1758..1d40761 100644 --- a/sbin/fsck/inode.c +++ b/sbin/fsck/inode.c @@ -32,26 +32,32 @@ */ #ifndef lint -static char sccsid[] = "@(#)inode.c 8.4 (Berkeley) 4/18/94"; +static char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> + +#include <err.h> #include <pwd.h> -#include <stdlib.h> #include <string.h> + #include "fsck.h" static ino_t startinum; +static int iblock __P((struct inodesc *, long ilevel, quad_t isize)); + +int ckinode(dp, idesc) struct dinode *dp; register struct inodesc *idesc; { - register daddr_t *ap; + ufs_daddr_t *ap; long ret, n, ndb, offset; struct dinode dino; quad_t remsize, sizepb; @@ -99,18 +105,18 @@ ckinode(dp, idesc) return (KEEPON); } +static int iblock(idesc, ilevel, isize) struct inodesc *idesc; long ilevel; quad_t isize; { - register daddr_t *ap; - register daddr_t *aplim; - register struct bufarea *bp; + ufs_daddr_t *ap; + ufs_daddr_t *aplim; + struct bufarea *bp; int i, n, (*func)(), nif; quad_t sizepb; char buf[BUFSIZ]; - extern int dirscan(), pass1check(); if (idesc->id_type == ADDR) { func = idesc->id_func; @@ -164,8 +170,9 @@ iblock(idesc, ilevel, isize) * Check that a block in a legal block number. * Return 0 if in range, 1 if out of range. */ +int chkrange(blk, cnt) - daddr_t blk; + ufs_daddr_t blk; int cnt; { register int c; @@ -204,10 +211,10 @@ struct dinode * ginode(inumber) ino_t inumber; { - daddr_t iblk; + ufs_daddr_t iblk; if (inumber < ROOTINO || inumber > maxino) - errexit("bad inode number %d to ginode\n", inumber); + errx(EEXIT, "bad inode number %d to ginode", inumber); if (startinum == 0 || inumber < startinum || inumber >= startinum + INOPB(&sblock)) { iblk = ino_to_fsba(&sblock, inumber); @@ -232,11 +239,11 @@ getnextinode(inumber) ino_t inumber; { long size; - daddr_t dblk; + ufs_daddr_t dblk; static struct dinode *dp; if (inumber != nextino++ || inumber > maxino) - errexit("bad inode number %d to nextinode\n", inumber); + errx(EEXIT, "bad inode number %d to nextinode", inumber); if (inumber >= lastinum) { readcnt++; dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); @@ -253,6 +260,7 @@ getnextinode(inumber) return (dp++); } +void resetinodebuf() { @@ -273,11 +281,12 @@ resetinodebuf() } if (inodebuf == NULL && (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL) - errexit("Cannot allocate space for inode buffer\n"); + errx(EEXIT, "Cannot allocate space for inode buffer"); while (nextino < ROOTINO) (void)getnextinode(nextino); } +void freeinodebuf() { @@ -293,6 +302,7 @@ freeinodebuf() * * Enter inodes into the cache. */ +void cacheino(dp, inumber) register struct dinode *dp; ino_t inumber; @@ -305,25 +315,27 @@ cacheino(dp, inumber) if (blks > NDADDR) blks = NDADDR + NIADDR; inp = (struct inoinfo *) - malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t)); + malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t)); if (inp == NULL) return; inpp = &inphead[inumber % numdirs]; inp->i_nexthash = *inpp; *inpp = inp; - inp->i_parent = (ino_t)0; + if (inumber == ROOTINO) + inp->i_parent = ROOTINO; + else + inp->i_parent = (ino_t)0; inp->i_dotdot = (ino_t)0; inp->i_number = inumber; inp->i_isize = dp->di_size; - inp->i_numblks = blks * sizeof(daddr_t); - bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0], - (size_t)inp->i_numblks); + inp->i_numblks = blks * sizeof(ufs_daddr_t); + memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks); if (inplast == listmax) { listmax += 100; inpsort = (struct inoinfo **)realloc((char *)inpsort, (unsigned)listmax * sizeof(struct inoinfo *)); if (inpsort == NULL) - errexit("cannot increase directory list"); + errx(EEXIT, "cannot increase directory list"); } inpsort[inplast++] = inp; } @@ -342,13 +354,14 @@ getinoinfo(inumber) continue; return (inp); } - errexit("cannot find inode %d\n", inumber); + errx(EEXIT, "cannot find inode %d", inumber); return ((struct inoinfo *)0); } /* * Clean up all the inode cache structure. */ +void inocleanup() { register struct inoinfo **inpp; @@ -362,12 +375,14 @@ inocleanup() inphead = inpsort = NULL; } +void inodirty() { dirty(pbp); } +void clri(idesc, type, flag) register struct inodesc *idesc; char *type; @@ -392,6 +407,7 @@ clri(idesc, type, flag) } } +int findname(idesc) struct inodesc *idesc; { @@ -399,10 +415,11 @@ findname(idesc) if (dirp->d_ino != idesc->id_parent) return (KEEPON); - bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1); + memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1); return (STOP|FOUND); } +int findino(idesc) struct inodesc *idesc; { @@ -418,6 +435,7 @@ findino(idesc) return (KEEPON); } +void pinode(ino) ino_t ino; { @@ -439,14 +457,15 @@ pinode(ino) if (preen) printf("%s: ", cdevname); printf("SIZE=%qu ", dp->di_size); - p = ctime(&dp->di_mtime.ts_sec); + p = ctime(&dp->di_mtime); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); } +void blkerror(ino, type, blk) ino_t ino; char *type; - daddr_t blk; + ufs_daddr_t blk; { pfatal("%ld %s I=%lu", blk, type, ino); @@ -466,7 +485,7 @@ blkerror(ino, type, blk) return; default: - errexit("BAD STATE %d TO BLKERR", statemap[ino]); + errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]); /* NOTREACHED */ } } @@ -509,7 +528,7 @@ allocino(request, type) return (0); } dp->di_mode = type; - (void)time(&dp->di_atime.ts_sec); + (void)time(&dp->di_atime); dp->di_mtime = dp->di_ctime = dp->di_atime; dp->di_size = sblock.fs_fsize; dp->di_blocks = btodb(sblock.fs_fsize); @@ -523,14 +542,14 @@ allocino(request, type) /* * deallocate an inode */ +void freeino(ino) ino_t ino; { struct inodesc idesc; - extern int pass4check(); struct dinode *dp; - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass4check; idesc.id_number = ino; diff --git a/sbin/fsck/main.c b/sbin/fsck/main.c index 2e69715..f719ac9 100644 --- a/sbin/fsck/main.c +++ b/sbin/fsck/main.c @@ -38,32 +38,40 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; +static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> #include <sys/mount.h> + #include <ufs/ufs/dinode.h> +#include <ufs/ufs/ufsmount.h> #include <ufs/ffs/fs.h> + +#include <ctype.h> +#include <err.h> #include <fstab.h> -#include <stdlib.h> #include <string.h> -#include <ctype.h> -#include <stdio.h> + #include "fsck.h" -void catch(), catchquit(), voidquit(); int returntosingle; +static int argtoi __P((int flag, char *req, char *str, int base)); +static int docheck __P((struct fstab *fsp)); +static int checkfilesys __P((char *filesys, char *mntpt, long auxdata, + int child)); +void main __P((int argc, char *argv[])); + +void main(argc, argv) int argc; char *argv[]; { int ch; int ret, maxrun = 0; - extern int docheck(), checkfilesys(); - extern char *optarg, *blockcheck(); + extern char *optarg; extern int optind; sync(); @@ -93,7 +101,7 @@ main(argc, argv) case 'm': lfmode = argtoi('m', "mode", optarg, 8); if (lfmode &~ 07777) - errexit("bad mode to -m: %o\n", lfmode); + errx(EEXIT, "bad mode to -m: %o", lfmode); printf("** lost+found creation mode %o\n", lfmode); break; @@ -110,7 +118,7 @@ main(argc, argv) break; default: - errexit("%c option?\n", ch); + errx(EEXIT, "%c option?", ch); } } argc -= optind; @@ -130,6 +138,7 @@ main(argc, argv) exit(ret); } +static int argtoi(flag, req, str, base) int flag; char *req, *str; @@ -140,13 +149,14 @@ argtoi(flag, req, str, base) ret = (int)strtol(str, &cp, base); if (cp == str || *cp) - errexit("-%c flag requires a %s\n", flag, req); + errx(EEXIT, "-%c flag requires a %s", flag, req); return (ret); } /* * Determine whether a filesystem should be checked. */ +static int docheck(fsp) register struct fstab *fsp; { @@ -163,23 +173,28 @@ docheck(fsp) * Check the specified filesystem. */ /* ARGSUSED */ +static int checkfilesys(filesys, mntpt, auxdata, child) char *filesys, *mntpt; long auxdata; + int child; { - daddr_t n_ffree, n_bfree; + ufs_daddr_t n_ffree, n_bfree; struct dups *dp; struct zlncnt *zlnp; - int cylno; + int cylno, flags; if (preen && child) (void)signal(SIGQUIT, voidquit); cdevname = filesys; if (debug && preen) pwarn("starting\n"); - if (setup(filesys) == 0) { + switch (setup(filesys)) { + case 0: if (preen) pfatal("CAN'T CHECK FILE SYSTEM."); + /* fall through */ + case -1: return (0); } /* @@ -280,7 +295,19 @@ checkfilesys(filesys, mntpt, auxdata, child) bwrite(fswritefd, (char *)&sblock, fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); } - ckfini(); + if (!hotroot) { + ckfini(1); + } else { + struct statfs stfs_buf; + /* + * Check to see if root is mounted read-write. + */ + if (statfs("/", &stfs_buf) == 0) + flags = stfs_buf.f_flags; + else + flags = 0; + ckfini(flags & MNT_RDONLY); + } free(blockmap); free(statemap); free((char *)lncntp); @@ -289,25 +316,20 @@ checkfilesys(filesys, mntpt, auxdata, child) if (!preen) printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); if (hotroot) { - struct statfs stfs_buf; + struct ufs_args args; + int ret; /* * We modified the root. Do a mount update on * it, unless it is read-write, so we can continue. */ - if (statfs("/", &stfs_buf) == 0) { - long flags = stfs_buf.f_flags; - struct ufs_args args; - int ret; - - if (flags & MNT_RDONLY) { - args.fspec = 0; - args.export.ex_flags = 0; - args.export.ex_root = 0; - flags |= MNT_UPDATE | MNT_RELOAD; - ret = mount(MOUNT_UFS, "/", flags, &args); - if (ret == 0) - return(0); - } + if (flags & MNT_RDONLY) { + args.fspec = 0; + args.export.ex_flags = 0; + args.export.ex_root = 0; + flags |= MNT_UPDATE | MNT_RELOAD; + ret = mount("ufs", "/", flags, &args); + if (ret == 0) + return (0); } if (!preen) printf("\n***** REBOOT NOW *****\n"); diff --git a/sbin/fsck/pass1.c b/sbin/fsck/pass1.c index ca255fe..1169adb 100644 --- a/sbin/fsck/pass1.c +++ b/sbin/fsck/pass1.c @@ -32,23 +32,26 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> -#include <stdlib.h> + +#include <err.h> #include <string.h> + #include "fsck.h" -static daddr_t badblk; -static daddr_t dupblk; -int pass1check(); -struct dinode *getnextinode(); +static ufs_daddr_t badblk; +static ufs_daddr_t dupblk; +static void checkinode __P((ino_t inumber, struct inodesc *)); +void pass1() { ino_t inumber; @@ -71,7 +74,7 @@ pass1() /* * Find all allocated blocks. */ - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass1check; inumber = 0; @@ -87,6 +90,7 @@ pass1() freeinodebuf(); } +static void checkinode(inumber, idesc) ino_t inumber; register struct inodesc *idesc; @@ -95,15 +99,15 @@ checkinode(inumber, idesc) struct zlncnt *zlnp; int ndb, j; mode_t mode; - char symbuf[MAXSYMLINKLEN]; + char *symbuf; dp = getnextinode(inumber); mode = dp->di_mode & IFMT; if (mode == 0) { - if (bcmp((char *)dp->di_db, (char *)zino.di_db, - NDADDR * sizeof(daddr_t)) || - bcmp((char *)dp->di_ib, (char *)zino.di_ib, - NIADDR * sizeof(daddr_t)) || + if (memcmp(dp->di_db, zino.di_db, + NDADDR * sizeof(ufs_daddr_t)) || + memcmp(dp->di_ib, zino.di_ib, + NIADDR * sizeof(ufs_daddr_t)) || dp->di_mode || dp->di_size) { pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); if (reply("CLEAR") == 1) { @@ -117,7 +121,8 @@ checkinode(inumber, idesc) } lastino = inumber; if (/* dp->di_size < 0 || */ - dp->di_size + sblock.fs_bsize - 1 < dp->di_size) { + dp->di_size + sblock.fs_bsize - 1 < dp->di_size || + (mode == IFDIR && dp->di_size > MAXDIRSIZE)) { if (debug) printf("bad size %qu:", dp->di_size); goto unknown; @@ -141,18 +146,18 @@ checkinode(inumber, idesc) if (doinglevel2 && dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && dp->di_blocks != 0) { + symbuf = alloca(secsize); if (bread(fsreadfd, symbuf, fsbtodb(&sblock, dp->di_db[0]), - (long)dp->di_size) != 0) - errexit("cannot read symlink"); + (long)secsize) != 0) + errx(EEXIT, "cannot read symlink"); if (debug) { symbuf[dp->di_size] = 0; printf("convert symlink %d(%s) of size %d\n", inumber, symbuf, (long)dp->di_size); } dp = ginode(inumber); - bcopy(symbuf, (caddr_t)dp->di_shortlink, - (long)dp->di_size); + memmove(dp->di_shortlink, symbuf, (long)dp->di_size); dp->di_blocks = 0; inodirty(); } @@ -161,7 +166,7 @@ checkinode(inumber, idesc) * will detect any garbage after symlink string. */ if (dp->di_size < sblock.fs_maxsymlinklen) { - ndb = howmany(dp->di_size, sizeof(daddr_t)); + ndb = howmany(dp->di_size, sizeof(ufs_daddr_t)); if (ndb > NDADDR) { j = ndb - NDADDR; for (ndb = 1; j > 1; j--) @@ -194,7 +199,7 @@ checkinode(inumber, idesc) if (zlnp == NULL) { pfatal("LINK COUNT TABLE OVERFLOW"); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); } else { zlnp->zlncnt = inumber; zlnp->next = zlnhead; @@ -246,12 +251,13 @@ unknown: } } +int pass1check(idesc) register struct inodesc *idesc; { int res = KEEPON; int anyout, nfrags; - daddr_t blkno = idesc->id_blkno; + ufs_daddr_t blkno = idesc->id_blkno; register struct dups *dlp; struct dups *new; @@ -263,7 +269,7 @@ pass1check(idesc) if (preen) printf(" (SKIPPING)\n"); else if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } } @@ -281,14 +287,14 @@ pass1check(idesc) if (preen) printf(" (SKIPPING)\n"); else if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } new = (struct dups *)malloc(sizeof(struct dups)); if (new == NULL) { pfatal("DUP TABLE OVERFLOW."); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } new->dup = blkno; diff --git a/sbin/fsck/pass1b.c b/sbin/fsck/pass1b.c index 27b2dfd..203fb53 100644 --- a/sbin/fsck/pass1b.c +++ b/sbin/fsck/pass1b.c @@ -32,19 +32,23 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> + #include <string.h> + #include "fsck.h" -int pass1bcheck(); static struct dups *duphead; +static int pass1bcheck __P((struct inodesc *)); +void pass1b() { register int c, i; @@ -52,7 +56,7 @@ pass1b() struct inodesc idesc; ino_t inumber; - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass1bcheck; duphead = duplist; @@ -72,12 +76,13 @@ pass1b() } } +static int pass1bcheck(idesc) register struct inodesc *idesc; { register struct dups *dlp; int nfrags, res = KEEPON; - daddr_t blkno = idesc->id_blkno; + ufs_daddr_t blkno = idesc->id_blkno; for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { if (chkrange(blkno, 1)) diff --git a/sbin/fsck/pass2.c b/sbin/fsck/pass2.c index 6314751..27490fe 100644 --- a/sbin/fsck/pass2.c +++ b/sbin/fsck/pass2.c @@ -32,22 +32,27 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94"; +static char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> -#include <stdlib.h> + +#include <err.h> #include <string.h> + #include "fsck.h" #define MINDIRSIZE (sizeof (struct dirtemplate)) -int pass2check(), blksort(); +static int blksort __P((const void *, const void *)); +static int pass2check __P((struct inodesc *)); +void pass2() { register struct dinode *dp; @@ -62,9 +67,9 @@ pass2() case USTATE: pfatal("ROOT INODE UNALLOCATED"); if (reply("ALLOCATE") == 0) - errexit(""); + exit(EEXIT); if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE\n"); + errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); break; case DCLEAR: @@ -72,11 +77,11 @@ pass2() if (reply("REALLOCATE")) { freeino(ROOTINO); if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE\n"); + errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); break; } if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); break; case FSTATE: @@ -85,11 +90,11 @@ pass2() if (reply("REALLOCATE")) { freeino(ROOTINO); if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) - errexit("CANNOT ALLOCATE ROOT INODE\n"); + errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); break; } if (reply("FIX") == 0) - errexit(""); + exit(EEXIT); dp = ginode(ROOTINO); dp->di_mode &= ~IFMT; dp->di_mode |= IFDIR; @@ -100,9 +105,13 @@ pass2() break; default: - errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); + errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); } statemap[ROOTINO] = DFOUND; + if (newinofmt) { + statemap[WINO] = FSTATE; + typemap[WINO] = DT_WHT; + } /* * Sort the directory list into disk block order. */ @@ -110,7 +119,7 @@ pass2() /* * Check the integrity of each directory. */ - bzero((char *)&curino, sizeof(struct inodesc)); + memset(&curino, 0, sizeof(struct inodesc)); curino.id_type = DATA; curino.id_func = pass2check; dp = &dino; @@ -142,11 +151,10 @@ pass2() dp = &dino; } } - bzero((char *)&dino, sizeof(struct dinode)); + memset(&dino, 0, sizeof(struct dinode)); dino.di_mode = IFDIR; dp->di_size = inp->i_isize; - bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0], - (size_t)inp->i_numblks); + memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks); curino.id_number = inp->i_number; curino.id_parent = inp->i_parent; (void)ckinode(dp, &curino); @@ -189,6 +197,7 @@ pass2() propagate(); } +static int pass2check(idesc) struct inodesc *idesc; { @@ -236,6 +245,15 @@ pass2check(idesc) proto.d_type = 0; proto.d_namlen = 1; (void)strcpy(proto.d_name, "."); +# if BYTE_ORDER == LITTLE_ENDIAN + if (!newinofmt) { + u_char tmp; + + tmp = proto.d_type; + proto.d_type = proto.d_namlen; + proto.d_namlen = tmp; + } +# endif entrysize = DIRSIZ(0, &proto); if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", @@ -244,17 +262,17 @@ pass2check(idesc) pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); } else if (dirp->d_reclen < 2 * entrysize) { proto.d_reclen = dirp->d_reclen; - bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); + memmove(dirp, &proto, (size_t)entrysize); if (reply("FIX") == 1) ret |= ALTERED; } else { n = dirp->d_reclen - entrysize; proto.d_reclen = entrysize; - bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); + memmove(dirp, &proto, (size_t)entrysize); idesc->id_entryno++; lncntp[dirp->d_ino]--; dirp = (struct direct *)((char *)(dirp) + entrysize); - bzero((char *)dirp, (size_t)n); + memset(dirp, 0, (size_t)n); dirp->d_reclen = n; if (reply("FIX") == 1) ret |= ALTERED; @@ -270,6 +288,15 @@ chk1: proto.d_type = 0; proto.d_namlen = 2; (void)strcpy(proto.d_name, ".."); +# if BYTE_ORDER == LITTLE_ENDIAN + if (!newinofmt) { + u_char tmp; + + tmp = proto.d_type; + proto.d_type = proto.d_namlen; + proto.d_namlen = tmp; + } +# endif entrysize = DIRSIZ(0, &proto); if (idesc->id_entryno == 0) { n = DIRSIZ(0, dirp); @@ -280,7 +307,7 @@ chk1: idesc->id_entryno++; lncntp[dirp->d_ino]--; dirp = (struct direct *)((char *)(dirp) + n); - bzero((char *)dirp, (size_t)proto.d_reclen); + memset(dirp, 0, (size_t)proto.d_reclen); dirp->d_reclen = proto.d_reclen; } if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { @@ -309,7 +336,7 @@ chk1: inp->i_dotdot = inp->i_parent; fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); proto.d_reclen = dirp->d_reclen; - bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); + memmove(dirp, &proto, (size_t)entrysize); if (reply("FIX") == 1) ret |= ALTERED; } @@ -343,6 +370,14 @@ chk2: if (dirp->d_ino > maxino) { fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); n = reply("REMOVE"); + } else if (newinofmt && + ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) || + (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) { + fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY"); + dirp->d_ino = WINO; + dirp->d_type = DT_WHT; + if (reply("FIX") == 1) + ret |= ALTERED; } else { again: switch (statemap[dirp->d_ino]) { @@ -409,7 +444,7 @@ again: break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[dirp->d_ino], dirp->d_ino); } } @@ -422,9 +457,11 @@ again: /* * Routine to sort disk blocks. */ -blksort(inpp1, inpp2) - struct inoinfo **inpp1, **inpp2; +static int +blksort(arg1, arg2) + const void *arg1, *arg2; { - return ((*inpp1)->i_blks[0] - (*inpp2)->i_blks[0]); + return ((*(struct inoinfo **)arg1)->i_blks[0] - + (*(struct inoinfo **)arg2)->i_blks[0]); } diff --git a/sbin/fsck/pass3.c b/sbin/fsck/pass3.c index 5c6f09d..e8c9446 100644 --- a/sbin/fsck/pass3.c +++ b/sbin/fsck/pass3.c @@ -32,15 +32,18 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> + #include "fsck.h" +void pass3() { register struct inoinfo **inpp, *inp; diff --git a/sbin/fsck/pass4.c b/sbin/fsck/pass4.c index 7450530..97bc7d0 100644 --- a/sbin/fsck/pass4.c +++ b/sbin/fsck/pass4.c @@ -32,19 +32,21 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> -#include <stdlib.h> + +#include <err.h> #include <string.h> -#include "fsck.h" -int pass4check(); +#include "fsck.h" +void pass4() { register ino_t inumber; @@ -53,7 +55,7 @@ pass4() struct inodesc idesc; int n; - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass4check; for (inumber = ROOTINO; inumber <= lastino; inumber++) { @@ -97,18 +99,19 @@ pass4() break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[inumber], inumber); } } } +int pass4check(idesc) register struct inodesc *idesc; { register struct dups *dlp; int nfrags, res = KEEPON; - daddr_t blkno = idesc->id_blkno; + ufs_daddr_t blkno = idesc->id_blkno; for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { if (chkrange(blkno, 1)) { diff --git a/sbin/fsck/pass5.c b/sbin/fsck/pass5.c index 2e98f96..27509d3 100644 --- a/sbin/fsck/pass5.c +++ b/sbin/fsck/pass5.c @@ -32,24 +32,29 @@ */ #ifndef lint -static char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; +static char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> + +#include <err.h> #include <string.h> + #include "fsck.h" +void pass5() { int c, blk, frags, basesize, sumsize, mapsize, savednrpos; - register struct fs *fs = &sblock; - register struct cg *cg = &cgrp; - daddr_t dbase, dmax; - register daddr_t d; - register long i, j; + struct fs *fs = &sblock; + struct cg *cg = &cgrp; + ufs_daddr_t dbase, dmax; + ufs_daddr_t d; + long i, j; struct csum *cs; struct csum cstotal; struct inodesc idesc[3]; @@ -57,9 +62,10 @@ pass5() register struct cg *newcg = (struct cg *)buf; struct ocg *ocg = (struct ocg *)buf; - bzero((char *)newcg, (size_t)fs->fs_cgsize); + statemap[WINO] = USTATE; + memset(newcg, 0, (size_t)fs->fs_cgsize); newcg->cg_niblk = fs->fs_ipg; - if (cvtlevel > 3) { + if (cvtlevel >= 3) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (preen) pwarn("DELETING CLUSTERING MAPS\n"); @@ -101,8 +107,9 @@ pass5() switch ((int)fs->fs_postblformat) { case FS_42POSTBLFMT: - basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); - sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); + basesize = (char *)(&ocg->cg_btot[0]) - + (char *)(&ocg->cg_firstfield); + sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]); mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - (u_char *)&ocg->cg_iused[0]; ocg->cg_magic = CG_MAGIC; @@ -112,7 +119,7 @@ pass5() case FS_DYNAMICPOSTBLFMT: newcg->cg_btotoff = - &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); + &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); newcg->cg_boff = newcg->cg_btotoff + fs->fs_cpg * sizeof(long); newcg->cg_iusedoff = newcg->cg_boff + @@ -134,22 +141,24 @@ pass5() howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); } newcg->cg_magic = CG_MAGIC; - basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); + basesize = &newcg->cg_space[0] - + (u_char *)(&newcg->cg_firstfield); sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; break; default: - errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", + sumsize = 0; /* keep lint happy */ + errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d", fs->fs_postblformat); } - bzero((char *)&idesc[0], sizeof idesc); + memset(&idesc[0], 0, sizeof idesc); for (i = 0; i < 3; i++) { idesc[i].id_type = ADDR; if (doinglevel2) idesc[i].id_fix = FIX; } - bzero((char *)&cstotal, sizeof(struct csum)); + memset(&cstotal, 0, sizeof(struct csum)); j = blknum(fs, fs->fs_size + fs->fs_frag - 1); for (i = fs->fs_size; i < j; i++) setbmap(i); @@ -186,8 +195,8 @@ pass5() newcg->cg_irotor = cg->cg_irotor; else newcg->cg_irotor = 0; - bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); - bzero((char *)&cg_blktot(newcg)[0], + memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum); + memset(&cg_blktot(newcg)[0], 0, (size_t)(sumsize + mapsize)); if (fs->fs_postblformat == FS_42POSTBLFMT) ocg->cg_magic = CG_MAGIC; @@ -213,7 +222,7 @@ pass5() default: if (j < ROOTINO) break; - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[j], j); } } @@ -247,7 +256,7 @@ pass5() } } if (fs->fs_contigsumsize > 0) { - long *sump = cg_clustersum(newcg); + int32_t *sump = cg_clustersum(newcg); u_char *mapp = cg_clustersfree(newcg); int map = *mapp++; int bit = 1; @@ -280,38 +289,38 @@ pass5() cstotal.cs_nifree += newcg->cg_cs.cs_nifree; cstotal.cs_ndir += newcg->cg_cs.cs_ndir; cs = &fs->fs_cs(fs, c); - if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && + if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { - bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); + memmove(cs, &newcg->cg_cs, sizeof *cs); sbdirty(); } if (doinglevel1) { - bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); + memmove(cg, newcg, (size_t)fs->fs_cgsize); cgdirty(); continue; } - if (bcmp(cg_inosused(newcg), + if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { - bcopy(cg_inosused(newcg), cg_inosused(cg), + memmove(cg_inosused(cg), cg_inosused(newcg), (size_t)mapsize); cgdirty(); } - if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || - bcmp((char *)&cg_blktot(newcg)[0], - (char *)&cg_blktot(cg)[0], sumsize) != 0) && + if ((memcmp(newcg, cg, basesize) != 0 || + memcmp(&cg_blktot(newcg)[0], + &cg_blktot(cg)[0], sumsize) != 0) && dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { - bcopy((char *)newcg, (char *)cg, (size_t)basesize); - bcopy((char *)&cg_blktot(newcg)[0], - (char *)&cg_blktot(cg)[0], (size_t)sumsize); + memmove(cg, newcg, (size_t)basesize); + memmove(&cg_blktot(cg)[0], + &cg_blktot(newcg)[0], (size_t)sumsize); cgdirty(); } } if (fs->fs_postblformat == FS_42POSTBLFMT) fs->fs_nrpos = savednrpos; - if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 + if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { - bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); + memmove(&fs->fs_cstotal, &cstotal, sizeof *cs); fs->fs_ronly = 0; fs->fs_fmod = 0; sbdirty(); diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c index 005a65d..b5fae6b 100644 --- a/sbin/fsck/preen.c +++ b/sbin/fsck/preen.c @@ -32,19 +32,20 @@ */ #ifndef lint -static char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/stat.h> #include <sys/wait.h> + +#include <ufs/ufs/dinode.h> + +#include <ctype.h> #include <fstab.h> #include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -char *rawname(), *unrawname(), *blockcheck(); +#include "fsck.h" struct part { struct part *next; /* forward link of partitions on disk */ @@ -63,9 +64,19 @@ struct disk { int nrun, ndisks; char hotroot; +static void addpart __P((char *name, char *fsname, long auxdata)); +static struct disk *finddisk __P((char *name)); +static char *rawname __P((char *name)); +static int startdisk __P((struct disk *dk, + int (*checkit)(char *, char *, long, int))); +static char *unrawname __P((char *name)); + +int checkfstab(preen, maxrun, docheck, chkit) - int preen, maxrun; - int (*docheck)(), (*chkit)(); + int preen; + int maxrun; + int (*docheck)(struct fstab *); + int (*chkit)(char *, char *, long, int); { register struct fstab *fsp; register struct disk *dk, *nextdisk; @@ -84,10 +95,11 @@ checkfstab(preen, maxrun, docheck, chkit) while ((fsp = getfsent()) != 0) { if ((auxdata = (*docheck)(fsp)) == 0) continue; - if (preen == 0 || passno == 1 && fsp->fs_passno == 1) { - if (name = blockcheck(fsp->fs_spec)) { - if (sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0)) + if (preen == 0 || + (passno == 1 && fsp->fs_passno == 1)) { + if ((name = blockcheck(fsp->fs_spec)) != 0) { + if ((sumstatus = (*chkit)(name, + fsp->fs_file, auxdata, 0)) != 0) return (sumstatus); } else if (preen) return (8); @@ -111,7 +123,7 @@ checkfstab(preen, maxrun, docheck, chkit) maxrun = ndisks; nextdisk = disks; for (passno = 0; passno < maxrun; ++passno) { - while (ret = startdisk(nextdisk, chkit) && nrun > 0) + while ((ret = startdisk(nextdisk, chkit)) && nrun > 0) sleep(10); if (ret) return (ret); @@ -150,7 +162,7 @@ checkfstab(preen, maxrun, docheck, chkit) if (nextdisk == NULL) { if (dk->part) { - while (ret = startdisk(dk, chkit) && + while ((ret = startdisk(dk, chkit)) && nrun > 0) sleep(10); if (ret) @@ -164,7 +176,7 @@ checkfstab(preen, maxrun, docheck, chkit) nextdisk->pid == 0) break; } - while (ret = startdisk(nextdisk, chkit) && + while ((ret = startdisk(nextdisk, chkit)) && nrun > 0) sleep(10); if (ret) @@ -186,7 +198,7 @@ checkfstab(preen, maxrun, docheck, chkit) return (0); } -struct disk * +static struct disk * finddisk(name) char *name; { @@ -194,13 +206,11 @@ finddisk(name) register char *p; size_t len; - for (p = name + strlen(name) - 1; p >= name; --p) + for (len = strlen(name), p = name + len - 1; p >= name; --p) if (isdigit(*p)) { len = p - name + 1; break; } - if (p < name) - len = strlen(name); for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { if (strncmp(dk->name, name, len) == 0 && @@ -225,6 +235,7 @@ finddisk(name) return (dk); } +static void addpart(name, fsname, auxdata) char *name, *fsname; long auxdata; @@ -256,9 +267,10 @@ addpart(name, fsname, auxdata) pt->auxdata = auxdata; } +static int startdisk(dk, checkit) register struct disk *dk; - int (*checkit)(); + int (*checkit)(char *, char *, long, int); { register struct part *pt = dk->part; @@ -274,57 +286,61 @@ startdisk(dk, checkit) } char * -blockcheck(name) - char *name; +blockcheck(origname) + char *origname; { struct stat stslash, stblock, stchar; - char *raw; + char *newname, *raw; int retried = 0; hotroot = 0; if (stat("/", &stslash) < 0) { perror("/"); printf("Can't stat root\n"); - return (0); + return (origname); } + newname = origname; retry: - if (stat(name, &stblock) < 0) { - perror(name); - printf("Can't stat %s\n", name); - return (0); + if (stat(newname, &stblock) < 0) { + perror(newname); + printf("Can't stat %s\n", newname); + return (origname); } if ((stblock.st_mode & S_IFMT) == S_IFBLK) { if (stslash.st_dev == stblock.st_rdev) hotroot++; - raw = rawname(name); + raw = rawname(newname); if (stat(raw, &stchar) < 0) { perror(raw); printf("Can't stat %s\n", raw); - return (name); + return (origname); } if ((stchar.st_mode & S_IFMT) == S_IFCHR) { return (raw); } else { printf("%s is not a character device\n", raw); - return (name); + return (origname); } } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { - name = unrawname(name); + newname = unrawname(newname); retried++; goto retry; } - printf("Can't make sense out of name %s\n", name); - return (0); + /* + * Not a block or character device, just return name and + * let the user decide whether to use it. + */ + return (origname); } -char * +static char * unrawname(name) char *name; { char *dp; struct stat stb; - if ((dp = rindex(name, '/')) == 0) + if ((dp = strrchr(name, '/')) == 0) return (name); if (stat(name, &stb) < 0) return (name); @@ -336,14 +352,14 @@ unrawname(name) return (name); } -char * +static char * rawname(name) char *name; { static char rawbuf[32]; char *dp; - if ((dp = rindex(name, '/')) == 0) + if ((dp = strrchr(name, '/')) == 0) return (0); *dp = 0; (void)strcpy(rawbuf, name); diff --git a/sbin/fsck/setup.c b/sbin/fsck/setup.c index a32b23c..a9ab994 100644 --- a/sbin/fsck/setup.c +++ b/sbin/fsck/setup.c @@ -32,35 +32,47 @@ */ #ifndef lint -static char sccsid[] = "@(#)setup.c 8.2 (Berkeley) 2/21/94"; +static char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95"; #endif /* not lint */ #define DKTYPENAMES #include <sys/param.h> #include <sys/time.h> -#include <ufs/ufs/dinode.h> -#include <ufs/ffs/fs.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/disklabel.h> #include <sys/file.h> + +#include <ufs/ufs/dinode.h> +#include <ufs/ffs/fs.h> + +#include <ctype.h> +#include <err.h> #include <errno.h> -#include <stdlib.h> #include <string.h> -#include <ctype.h> + #include "fsck.h" struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -struct disklabel *getdisklabel(); +static void badsb __P((int listerr, char *s)); +static int calcsb __P((char *dev, int devfd, struct fs *fs)); +static struct disklabel *getdisklabel __P((char *s, int fd)); +static int readsb __P((int listerr)); +/* + * Read in a superblock finding an alternate if necessary. + * Return 1 if successful, 0 if unsuccessful, -1 if filesystem + * is already clean (preen mode only). + */ +int setup(dev) char *dev; { long cg, size, asked, i, j; - long bmapsize; + long skipclean, bmapsize; struct disklabel *lp; off_t sizepb; struct stat statb; @@ -68,6 +80,7 @@ setup(dev) havesb = 0; fswritefd = -1; + skipclean = preen; if (stat(dev, &statb) < 0) { printf("Can't stat %s: %s\n", dev, strerror(errno)); return (0); @@ -98,8 +111,8 @@ setup(dev) sblk.b_un.b_buf = malloc(SBSIZE); asblk.b_un.b_buf = malloc(SBSIZE); if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) - errexit("cannot allocate space for superblock\n"); - if (lp = getdisklabel((char *)NULL, fsreadfd)) + errx(EEXIT, "cannot allocate space for superblock"); + if (lp = getdisklabel(NULL, fsreadfd)) dev_bsize = secsize = lp->d_secsize; else dev_bsize = secsize = DEV_BSIZE; @@ -107,6 +120,7 @@ setup(dev) * Read in the superblock, looking for alternates if necessary */ if (readsb(1) == 0) { + skipclean = 0; if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) return(0); if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) @@ -128,6 +142,10 @@ setup(dev) } pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); } + if (skipclean && sblock.fs_clean) { + pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); + return (-1); + } maxfsblock = sblock.fs_size; maxino = sblock.fs_ncg * sblock.fs_ipg; /* @@ -214,17 +232,16 @@ setup(dev) sblock.fs_nrpos = 8; sblock.fs_postbloff = (char *)(&sblock.fs_opostbl[0][0]) - - (char *)(&sblock.fs_link); + (char *)(&sblock.fs_firstfield); sblock.fs_rotbloff = &sblock.fs_space[0] - - (u_char *)(&sblock.fs_link); + (u_char *)(&sblock.fs_firstfield); sblock.fs_cgsize = fragroundup(&sblock, CGSIZE(&sblock)); sbdirty(); dirty(&asblk); } - if (asblk.b_dirty) { - bcopy((char *)&sblock, (char *)&altsblock, - (size_t)sblock.fs_sbsize); + if (asblk.b_dirty && !bflag) { + memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize); flush(fswritefd, &asblk); } /* @@ -240,7 +257,7 @@ setup(dev) size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); asked++; } } @@ -288,17 +305,18 @@ setup(dev) return (1); badsb: - ckfini(); + ckfini(0); return (0); } /* * Read in the super block and its summary info. */ +static int readsb(listerr) int listerr; { - daddr_t super = bflag ? bflag : SBOFF / dev_bsize; + ufs_daddr_t super = bflag ? bflag : SBOFF / dev_bsize; if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0) return (0); @@ -338,8 +356,8 @@ readsb(listerr) getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); if (asblk.b_errs) return (0); - altsblock.fs_link = sblock.fs_link; - altsblock.fs_rlink = sblock.fs_rlink; + altsblock.fs_firstfield = sblock.fs_firstfield; + altsblock.fs_unused_1 = sblock.fs_unused_1; altsblock.fs_time = sblock.fs_time; altsblock.fs_cstotal = sblock.fs_cstotal; altsblock.fs_cgrotor = sblock.fs_cgrotor; @@ -352,12 +370,11 @@ readsb(listerr) altsblock.fs_optim = sblock.fs_optim; altsblock.fs_rotdelay = sblock.fs_rotdelay; altsblock.fs_maxbpg = sblock.fs_maxbpg; - bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, - sizeof sblock.fs_csp); - bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, - sizeof sblock.fs_fsmnt); - bcopy((char *)sblock.fs_sparecon, (char *)altsblock.fs_sparecon, - sizeof sblock.fs_sparecon); + memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp); + altsblock.fs_maxcluster = sblock.fs_maxcluster; + memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt); + memmove(altsblock.fs_sparecon, + sblock.fs_sparecon, sizeof sblock.fs_sparecon); /* * The following should not have to be copied. */ @@ -365,11 +382,26 @@ 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)) { + if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) { + if (debug) { + long *nlp, *olp, *endlp; + + printf("superblock mismatches\n"); + nlp = (long *)&altsblock; + olp = (long *)&sblock; + endlp = olp + (sblock.fs_sbsize / sizeof *olp); + for ( ; olp < endlp; olp++, nlp++) { + if (*olp == *nlp) + continue; + printf("offset %d, original %d, alternate %d\n", + olp - (long *)&sblock, *olp, *nlp); + } + } badsb(listerr, "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); return (0); @@ -378,6 +410,7 @@ readsb(listerr) return (1); } +static void badsb(listerr, s) int listerr; char *s; @@ -396,6 +429,7 @@ badsb(listerr, s) * can be used. Do NOT attempt to use other macros without verifying that * their needed information is available! */ +static int calcsb(dev, devfd, fs) char *dev; int devfd; @@ -406,8 +440,8 @@ calcsb(dev, devfd, fs) register char *cp; int i; - cp = index(dev, '\0') - 1; - if (cp == (char *)-1 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) { + cp = strchr(dev, '\0') - 1; + if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) { pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); return (0); } @@ -422,7 +456,7 @@ calcsb(dev, devfd, fs) fstypenames[pp->p_fstype] : "unknown"); return (0); } - bzero((char *)fs, sizeof(struct fs)); + memset(fs, 0, sizeof(struct fs)); fs->fs_fsize = pp->p_fsize; fs->fs_frag = pp->p_frag; fs->fs_cpg = pp->p_cpg; @@ -449,7 +483,7 @@ calcsb(dev, devfd, fs) return (1); } -struct disklabel * +static struct disklabel * getdisklabel(s, fd) char *s; int fd; @@ -460,7 +494,7 @@ getdisklabel(s, fd) if (s == NULL) return ((struct disklabel *)NULL); pwarn("ioctl (GCINFO): %s\n", strerror(errno)); - errexit("%s: can't read disk label\n", s); + errx(EEXIT, "%s: can't read disk label", s); } return (&lab); } diff --git a/sbin/fsck/utilities.c b/sbin/fsck/utilities.c index 64a4cac..a5c56da 100644 --- a/sbin/fsck/utilities.c +++ b/sbin/fsck/utilities.c @@ -32,22 +32,27 @@ */ #ifndef lint -static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; +static char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> + #include <ctype.h> +#include <err.h> +#include <string.h> + #include "fsck.h" long diskreads, totalreads; /* Disk cache statistics */ +static void rwerror __P((char *mesg, ufs_daddr_t blk)); + +int ftypeok(dp) struct dinode *dp; { @@ -69,6 +74,7 @@ ftypeok(dp) } } +int reply(question) char *question; { @@ -104,6 +110,7 @@ reply(question) /* * Malloc buffers and set up cache. */ +void bufinit() { register struct bufarea *bp; @@ -113,7 +120,7 @@ bufinit() pbp = pdirbp = (struct bufarea *)0; bufp = malloc((unsigned int)sblock.fs_bsize); if (bufp == 0) - errexit("cannot allocate buffer pool\n"); + errx(EEXIT, "cannot allocate buffer pool"); cgblk.b_un.b_buf = bufp; initbarea(&cgblk); bufhead.b_next = bufhead.b_prev = &bufhead; @@ -126,7 +133,7 @@ bufinit() if (bp == NULL || bufp == NULL) { if (i >= MINBUFS) break; - errexit("cannot allocate buffer pool\n"); + errx(EEXIT, "cannot allocate buffer pool"); } bp->b_un.b_buf = bufp; bp->b_prev = &bufhead; @@ -143,7 +150,7 @@ bufinit() */ struct bufarea * getdatablk(blkno, size) - daddr_t blkno; + ufs_daddr_t blkno; long size; { register struct bufarea *bp; @@ -155,7 +162,7 @@ getdatablk(blkno, size) if ((bp->b_flags & B_INUSE) == 0) break; if (bp == &bufhead) - errexit("deadlocked buffer pool\n"); + errx(EEXIT, "deadlocked buffer pool"); getblk(bp, blkno, size); /* fall through */ foundit: @@ -173,10 +180,10 @@ foundit: void getblk(bp, blk, size) register struct bufarea *bp; - daddr_t blk; + ufs_daddr_t blk; long size; { - daddr_t dblk; + ufs_daddr_t dblk; dblk = fsbtodb(&sblock, blk); if (bp->b_bno != dblk) { @@ -188,6 +195,7 @@ getblk(bp, blk, size) } } +void flush(fd, bp) int fd; register struct bufarea *bp; @@ -213,22 +221,25 @@ flush(fd, bp) } } +static void rwerror(mesg, blk) char *mesg; - daddr_t blk; + ufs_daddr_t blk; { if (preen == 0) printf("\n"); pfatal("CANNOT %s: BLK %ld", mesg, blk); if (reply("CONTINUE") == 0) - errexit("Program terminated\n"); + exit(EEXIT); } -ckfini() +void +ckfini(markclean) + int markclean; { register struct bufarea *bp, *nbp; - int cnt = 0; + int ofsmodified, cnt = 0; if (fswritefd < 0) { (void)close(fsreadfd); @@ -251,8 +262,17 @@ ckfini() free((char *)bp); } if (bufhead.b_size != cnt) - errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt); + errx(EEXIT, "Panic: lost %d buffers", bufhead.b_size - cnt); pbp = pdirbp = (struct bufarea *)0; + if (markclean && sblock.fs_clean == 0) { + sblock.fs_clean = 1; + sbdirty(); + ofsmodified = fsmodified; + flush(fswritefd, &sblk); + fsmodified = ofsmodified; + if (!preen) + printf("\n***** FILE SYSTEM MARKED CLEAN *****\n"); + } if (debug) printf("cache missed %ld of %ld (%d%%)\n", diskreads, totalreads, (int)(diskreads * 100 / totalreads)); @@ -260,10 +280,11 @@ ckfini() (void)close(fswritefd); } +int bread(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { char *cp; @@ -280,7 +301,7 @@ bread(fd, buf, blk, size) if (lseek(fd, offset, 0) < 0) rwerror("SEEK", blk); errs = 0; - bzero(buf, (size_t)size); + memset(buf, 0, (size_t)size); printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { if (read(fd, cp, (int)secsize) != secsize) { @@ -298,10 +319,11 @@ bread(fd, buf, blk, size) return (errs); } +void bwrite(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { int i; @@ -334,6 +356,7 @@ bwrite(fd, buf, blk, size) /* * allocate a data block with the specified number of fragments */ +ufs_daddr_t allocblk(frags) long frags; { @@ -364,8 +387,9 @@ allocblk(frags) /* * Free a previously allocated block */ +void freeblk(blkno, frags) - daddr_t blkno; + ufs_daddr_t blkno; long frags; { struct inodesc idesc; @@ -378,6 +402,7 @@ freeblk(blkno, frags) /* * Find a pathname */ +void getpathname(namebuf, curdir, ino) char *namebuf; ino_t curdir, ino; @@ -398,7 +423,7 @@ getpathname(namebuf, curdir, ino) return; } busy = 1; - bzero((char *)&idesc, sizeof(struct inodesc)); + memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = DATA; idesc.id_fix = IGNORE; cp = &namebuf[MAXPATHLEN - 1]; @@ -422,7 +447,7 @@ getpathname(namebuf, curdir, ino) break; len = strlen(namebuf); cp -= len; - bcopy(namebuf, cp, (size_t)len); + memmove(cp, namebuf, (size_t)len); *--cp = '/'; if (cp < &namebuf[MAXNAMLEN]) break; @@ -431,14 +456,15 @@ getpathname(namebuf, curdir, ino) busy = 0; if (ino != ROOTINO) *--cp = '?'; - bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp)); + memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp)); } void -catch() +catch(sig) + int sig; { if (!doinglevel2) - ckfini(); + ckfini(0); exit(12); } @@ -448,7 +474,8 @@ catch() * so that reboot sequence may be interrupted. */ void -catchquit() +catchquit(sig) + int sig; { extern returntosingle; @@ -462,7 +489,8 @@ catchquit() * Used by child processes in preen. */ void -voidquit() +voidquit(sig) + int sig; { sleep(1); @@ -473,6 +501,7 @@ voidquit() /* * determine whether an inode should be fixed. */ +int dofix(idesc, msg) register struct inodesc *idesc; char *msg; @@ -505,62 +534,95 @@ dofix(idesc, msg) return (0); default: - errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); + errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix); } /* NOTREACHED */ + return (0); } -/* VARARGS1 */ -errexit(s1, s2, s3, s4) - char *s1; -{ - printf(s1, s2, s3, s4); - exit(8); -} +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif /* * An unexpected inconsistency occured. * Die if preening, otherwise just print message and continue. */ -/* VARARGS1 */ -pfatal(s, a1, a2, a3) - char *s; +void +#if __STDC__ +pfatal(const char *fmt, ...) +#else +pfatal(fmt, va_alist) + char *fmt; + va_dcl +#endif { - - if (preen) { - printf("%s: ", cdevname); - printf(s, a1, a2, a3); - printf("\n"); - printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", - cdevname); - exit(8); + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (!preen) { + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + return; } - printf(s, a1, a2, a3); + (void)fprintf(stderr, "%s: ", cdevname); + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, + "\n%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", + cdevname); + exit(EEXIT); } /* * Pwarn just prints a message when not preening, * or a warning (preceded by filename) when preening. */ -/* VARARGS1 */ -pwarn(s, a1, a2, a3, a4, a5, a6) - char *s; +void +#if __STDC__ +pwarn(const char *fmt, ...) +#else +pwarn(fmt, va_alist) + char *fmt; + va_dcl +#endif { - + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif if (preen) - printf("%s: ", cdevname); - printf(s, a1, a2, a3, a4, a5, a6); + (void)fprintf(stderr, "%s: ", cdevname); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); } -#ifndef lint /* * Stub for routines from kernel. */ -panic(s) - char *s; +void +#if __STDC__ +panic(const char *fmt, ...) +#else +panic(fmt, va_alist) + char *fmt; + va_dcl +#endif { - + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif pfatal("INTERNAL INCONSISTENCY:"); - errexit(s); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EEXIT); } -#endif |