From 780a5c1ec16f889d55914a09fbcde7ff7b2cfcca Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Tue, 11 Mar 1997 12:20:21 +0000 Subject: [PATCH] Merge from Lite2. Note that Lite2 has it's own filesystem clean check skipping code that overrides ours sooner. One should be eliminated, but for now it works. --- sbin/fsck/Makefile | 3 +- sbin/fsck/dir.c | 143 +++++++++++++++------------- sbin/fsck/fsck.8 | 19 +++- sbin/fsck/fsck.h | 190 ++++++++++++++++++-------------------- sbin/fsck/inode.c | 54 +++++------ sbin/fsck/main.c | 80 ++++++++++------ sbin/fsck/pass1.c | 44 +++++---- sbin/fsck/pass1b.c | 13 ++- sbin/fsck/pass2.c | 82 +++++++++++----- sbin/fsck/pass3.c | 4 +- sbin/fsck/pass4.c | 17 ++-- sbin/fsck/pass5.c | 73 ++++++++------- sbin/fsck/preen.c | 99 ++++++++++---------- sbin/fsck/setup.c | 93 ++++++++++++------- sbin/fsck/utilities.c | 163 +++++++++++++++++++------------- sbin/fsck_ffs/Makefile | 3 +- sbin/fsck_ffs/dir.c | 143 +++++++++++++++------------- sbin/fsck_ffs/fsck.h | 190 ++++++++++++++++++-------------------- sbin/fsck_ffs/fsck_ffs.8 | 19 +++- sbin/fsck_ffs/inode.c | 54 +++++------ sbin/fsck_ffs/main.c | 80 ++++++++++------ sbin/fsck_ffs/pass1.c | 44 +++++---- sbin/fsck_ffs/pass1b.c | 13 ++- sbin/fsck_ffs/pass2.c | 82 +++++++++++----- sbin/fsck_ffs/pass3.c | 4 +- sbin/fsck_ffs/pass4.c | 17 ++-- sbin/fsck_ffs/pass5.c | 73 ++++++++------- sbin/fsck_ffs/preen.c | 99 ++++++++++---------- sbin/fsck_ffs/setup.c | 93 ++++++++++++------- sbin/fsck_ffs/utilities.c | 163 +++++++++++++++++++------------- sbin/fsck_ifs/Makefile | 3 +- sbin/fsck_ifs/dir.c | 143 +++++++++++++++------------- sbin/fsck_ifs/fsck.h | 190 ++++++++++++++++++-------------------- sbin/fsck_ifs/fsck_ifs.8 | 19 +++- sbin/fsck_ifs/inode.c | 54 +++++------ sbin/fsck_ifs/main.c | 80 ++++++++++------ sbin/fsck_ifs/pass1.c | 44 +++++---- sbin/fsck_ifs/pass1b.c | 13 ++- sbin/fsck_ifs/pass2.c | 82 +++++++++++----- sbin/fsck_ifs/pass3.c | 4 +- sbin/fsck_ifs/pass4.c | 17 ++-- sbin/fsck_ifs/pass5.c | 73 ++++++++------- sbin/fsck_ifs/preen.c | 99 ++++++++++---------- sbin/fsck_ifs/setup.c | 93 ++++++++++++------- sbin/fsck_ifs/utilities.c | 163 +++++++++++++++++++------------- sbin/quotacheck/preen.c | 99 ++++++++++---------- 46 files changed, 1890 insertions(+), 1440 deletions(-) diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile index e31e9928824f..3155b1a466ea 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.8 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 diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c index 9a2b9239a99f..5662b6e4fee1 100644 --- a/sbin/fsck/dir.c +++ b/sbin/fsck/dir.c @@ -32,17 +32,20 @@ */ #ifndef lint -static const char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #include "fsck.h" char *lfname = "lost+found"; @@ -57,15 +60,14 @@ struct odirtemplate odirhead = { 0, DIRBLKSIZ - 12, 2, ".." }; - -static int chgino __P((struct inodesc *idesc)); -static int dircheck __P((struct inodesc *idesc, struct direct *dp)); -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 *idesc)); -static struct bufarea * getdirblk __P((daddr_t blkno, long size)); -static int lftempname __P((char *bufp, ino_t ino)); -static int mkentry __P((struct inodesc *idesc)); +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. @@ -107,7 +109,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); @@ -119,7 +121,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; @@ -144,7 +146,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(); @@ -158,7 +160,7 @@ dirscan(idesc) /* * get next entry in a directory. */ -struct direct * +static struct direct * fsck_readdir(idesc) register struct inodesc *idesc; { @@ -173,6 +175,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); @@ -202,6 +206,8 @@ fsck_readdir(idesc) 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); @@ -216,7 +222,7 @@ fsck_readdir(idesc) * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */ -int +static int dircheck(idesc, dp) struct inodesc *idesc; register struct direct *dp; @@ -226,8 +232,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; @@ -240,23 +253,17 @@ 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 @@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg) void adjust(idesc, lcnt) register struct inodesc *idesc; - short lcnt; + int lcnt; { register struct dinode *dp; @@ -323,7 +330,7 @@ adjust(idesc, lcnt) } } -int +static int mkentry(idesc) struct inodesc *idesc; { @@ -343,30 +350,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 */ - if (newinofmt) { - dirp->d_type = typemap[idesc->id_parent]; - dirp->d_namlen = newent.d_namlen; - } else { -# if (BYTE_ORDER == LITTLE_ENDIAN) - dirp->d_type = newent.d_namlen; - dirp->d_namlen = 0; -# else - dirp->d_type = 0; - dirp->d_namlen = newent.d_namlen; -# endif - } dirp->d_reclen = newent.d_reclen; - bcopy(idesc->id_name, dirp->d_name, (size_t)newent.d_namlen + 1); + if (newinofmt) + dirp->d_type = typemap[idesc->id_parent]; + else + dirp->d_type = 0; + dirp->d_namlen = newent.d_namlen; + 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); } -int +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) @@ -387,7 +402,7 @@ linkup(orphan, parentdir) struct inodesc idesc; char tempname[BUFSIZ]; - 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"); @@ -501,7 +516,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; @@ -526,7 +541,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; @@ -550,12 +565,12 @@ makeentry(parent, ino, name) /* * Attempt to expand the size of a directory */ -int +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]; @@ -572,21 +587,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"); @@ -631,11 +646,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(); @@ -680,7 +695,7 @@ freedir(ino, parent) /* * generate a temporary name for the lost+found directory. */ -int +static int lftempname(bufp, ino) char *bufp; ino_t ino; @@ -707,9 +722,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 db91f329c571..ee0f7780ed2a 100644 --- a/sbin/fsck/fsck.8 +++ b/sbin/fsck/fsck.8 @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 -.|' $Id$ +.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 +.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $ .\" -.Dd December 11, 1993 +.Dd May 9, 1995 .Dt FSCK 8 .Os BSD 4 .Sh NAME @@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed to be the partition designator. .Pp The clean flag of each filesystem's superblock is examined and only those filesystems that -are not marked clean are checked. If the +are not marked clean are checked. +Filesystems are marked clean when they are unmounted, +when they have been mounted read-only, or when +.Nm fsck +runs on them successfully. +If the .Fl f option is specified, the filesystems will be checked regardless of the state of their clean flag. @@ -189,7 +194,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 @@ -198,6 +203,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 57cb17a02096..1967691e989c 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 +#include +#include + #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; @@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */ int returntosingle; /* return to single user mode */ int rerun; /* rerun fsck. Only used in non-preen mode */ -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 */ -unsigned 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; @@ -210,84 +213,69 @@ struct dinode zino; #define ALTERED 0x08 #define FOUND 0x10 -/* dir.c */ -void adjust __P((struct inodesc *idesc, short lcnt)); -ino_t allocdir __P((ino_t parent, ino_t request, int mode)); -int changeino __P((ino_t dir, char *name, ino_t newnum)); -void direrror __P((ino_t ino, char *errmesg)); -int dirscan __P((struct inodesc *idesc)); -void fileerror __P((ino_t cwd, ino_t ino, char *errmesg)); -int linkup __P((ino_t orphan, ino_t parentdir)); -int makeentry __P((ino_t parent, ino_t ino, char *name)); -void propagate __P((void)); +#define EEXIT 8 /* Standard error exit. */ -/* ffs_subr.c */ -void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt)); +struct fstab; -/* inode.c */ -ino_t allocino __P((ino_t request, int type)); -void blkerror __P((ino_t ino, char *type, daddr_t blk)); -void cacheino __P((struct dinode *dp, ino_t inumber)); -int chkrange __P((daddr_t blk, int cnt)); -int ckinode __P((struct dinode *dp, struct inodesc *idesc)); -void clri __P((struct inodesc *idesc, char *type, int flag)); -int findino __P((struct inodesc *idesc)); -void freeino __P((ino_t ino)); -void freeinodebuf __P((void)); -struct dinode * ginode __P((ino_t inumber)); -struct inoinfo * getinoinfo __P((ino_t inumber)); -struct dinode * getnextinode __P((ino_t inumber)); -void inodirty __P((void)); -void inocleanup __P((void)); -void pinode __P((ino_t ino)); -void resetinodebuf __P((void)); -int findname __P((struct inodesc *idesc)); - -/* pass1.c */ -void pass1 __P((void)); -int pass1check __P((struct inodesc *idesc)); - -/* pass1b.c */ -void pass1b __P((void)); - -/* pass2.c */ -void pass2 __P((void)); - -/* pass3.c */ -void pass3 __P((void)); - -/* pass4.c */ -void pass4 __P((void)); -int pass4check __P((struct inodesc *idesc)); - -/* pass5.c */ -void pass5 __P((void)); - -/* preen.c */ -char *blockcheck __P((char *name)); -int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); - -/* setup.c */ -int setup __P((char *dev)); - -/* utilities.c */ -int allocblk __P((long frags)); -int bread __P((int fd, char *buf, daddr_t blk, long size)); -void bufinit __P((void)); -void bwrite __P((int fd, char *buf, daddr_t blk, long size)); -void catch __P((int)); -void catchquit __P((int)); -void ckfini __P((void)); -int dofix __P((struct inodesc *idesc, char *msg)); -void errexit __P((const char *s1, ...)) __dead2; -void flush __P((int fd, struct bufarea *bp)); -void freeblk __P((daddr_t blkno, long frags)); -int ftypeok __P((struct dinode *dp)); -void getblk __P((struct bufarea *bp, daddr_t blk, long size)); -struct bufarea * getdatablk __P((daddr_t blkno, long size)); -void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); -void panic __P((const char *, ...)) __dead2; -void pfatal __P((const char *s1, ...)); -void pwarn __P((const char *s1, ...)); -int reply __P((char *question)); -void voidquit __P((int)); +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 5adac75f0832..9e22bdcca72d 100644 --- a/sbin/fsck/inode.c +++ b/sbin/fsck/inode.c @@ -32,32 +32,35 @@ */ #ifndef lint -static const char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; +static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + +#include #include #include #include #include + #include "fsck.h" static ino_t startinum; -static int iblock __P((struct inodesc *idesc, long ilevel, quad_t isize)); +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; - int ret; - long n, ndb, offset; + ufs_daddr_t *ap; + long ret, n, ndb, offset; struct dinode dino; quad_t remsize, sizepb; mode_t mode; @@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize) 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]; @@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize) */ int chkrange(blk, cnt) - daddr_t blk; + ufs_daddr_t blk; int cnt; { register int c; @@ -268,10 +271,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); @@ -296,11 +299,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)); @@ -338,7 +341,7 @@ 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); } @@ -372,7 +375,7 @@ 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]; @@ -385,15 +388,14 @@ cacheino(dp, inumber) 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; } @@ -412,7 +414,7 @@ getinoinfo(inumber) continue; return (inp); } - errexit("cannot find inode %d\n", inumber); + errx(EEXIT, "cannot find inode %d", inumber); return ((struct inoinfo *)0); } @@ -472,7 +474,7 @@ 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); } @@ -514,7 +516,7 @@ pinode(ino) if (preen) printf("%s: ", cdevname); printf("SIZE=%qu ", dp->di_size); - p = ctime(&dp->di_mtime.tv_sec); + p = ctime(&dp->di_mtime); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); } @@ -522,7 +524,7 @@ 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); @@ -542,7 +544,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 */ } } @@ -585,7 +587,7 @@ allocino(request, type) return (0); } dp->di_mode = type; - (void)time(&dp->di_atime.tv_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); @@ -606,7 +608,7 @@ freeino(ino) struct inodesc idesc; 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 363bba76ee78..b6588310ca11 100644 --- a/sbin/fsck/main.c +++ b/sbin/fsck/main.c @@ -38,25 +38,35 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; +static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; #endif /* not lint */ #include #include #include #include + #include +#include #include + +#include +#include #include #include #include #include #include + #include "fsck.h" -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)); + +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)); +int main __P((int argc, char *argv[])); int main(argc, argv) @@ -99,7 +109,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; @@ -116,7 +126,7 @@ main(argc, argv) break; default: - errexit("%c option?\n", ch); + errx(EEXIT, "%c option?", ch); } } argc -= optind; @@ -136,7 +146,7 @@ main(argc, argv) exit(ret); } -int +static int argtoi(flag, req, str, base) int flag; char *req, *str; @@ -147,14 +157,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. */ -int +static int docheck(fsp) register struct fstab *fsp; { @@ -171,25 +181,28 @@ docheck(fsp) * Check the specified filesystem. */ /* ARGSUSED */ -int +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); } @@ -302,7 +315,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); @@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child) if (rerun) printf("\n***** PLEASE RERUN FSCK *****\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 3fec63adc0d8..0114c5e85ec1 100644 --- a/sbin/fsck/pass1.c +++ b/sbin/fsck/pass1.c @@ -32,23 +32,27 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + #include #include +#include #include + #include "fsck.h" -static daddr_t badblk; -static daddr_t dupblk; +static ufs_daddr_t badblk; +static ufs_daddr_t dupblk; -static void checkinode __P((ino_t inumber, struct inodesc *idesc)); +static void checkinode __P((ino_t inumber, struct inodesc *)); void pass1() @@ -73,7 +77,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; @@ -89,7 +93,7 @@ pass1() freeinodebuf(); } -void +static void checkinode(inumber, idesc) ino_t inumber; register struct inodesc *idesc; @@ -103,10 +107,10 @@ checkinode(inumber, idesc) 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) { @@ -120,7 +124,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; @@ -148,15 +153,14 @@ checkinode(inumber, idesc) if (bread(fsreadfd, symbuf, fsbtodb(&sblock, dp->di_db[0]), (long)secsize) != 0) - errexit("cannot read symlink"); + errx(EEXIT, "cannot read symlink"); if (debug) { symbuf[dp->di_size] = 0; printf("convert symlink %ld(%s) of size %ld\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(); } @@ -165,7 +169,7 @@ checkinode(inumber, idesc) * will detect any garbage after symlink string. */ if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { - 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--) @@ -198,7 +202,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; @@ -256,7 +260,7 @@ pass1check(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; @@ -268,7 +272,7 @@ pass1check(idesc) if (preen) printf(" (SKIPPING)\n"); else if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } } @@ -286,14 +290,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 1450bd80e0a3..e5036c7e8806 100644 --- a/sbin/fsck/pass1b.c +++ b/sbin/fsck/pass1b.c @@ -32,18 +32,21 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include + #include + #include "fsck.h" -int pass1bcheck(); static struct dups *duphead; +static int pass1bcheck __P((struct inodesc *)); void pass1b() @@ -53,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; @@ -73,13 +76,13 @@ pass1b() } } -int +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 382207e9602c..6c9eb8b120da 100644 --- a/sbin/fsck/pass2.c +++ b/sbin/fsck/pass2.c @@ -32,22 +32,26 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94"; +static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #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() @@ -64,9 +68,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: @@ -74,11 +78,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: @@ -87,11 +91,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; @@ -102,9 +106,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. */ @@ -112,7 +120,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; @@ -144,11 +152,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); @@ -191,7 +198,7 @@ pass2() propagate(); } -int +static int pass2check(idesc) struct inodesc *idesc; { @@ -239,6 +246,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", @@ -247,17 +263,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; @@ -273,6 +289,15 @@ pass2check(idesc) 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); @@ -283,7 +308,7 @@ pass2check(idesc) 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) { @@ -312,7 +337,7 @@ pass2check(idesc) 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; } @@ -346,6 +371,14 @@ pass2check(idesc) 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]) { @@ -412,7 +445,7 @@ pass2check(idesc) 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); } } @@ -425,10 +458,11 @@ pass2check(idesc) /* * Routine to sort disk blocks. */ -int -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 963c41a28c5c..89aff79958fa 100644 --- a/sbin/fsck/pass3.c +++ b/sbin/fsck/pass3.c @@ -32,13 +32,15 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; #endif /* not lint */ #include #include + #include #include + #include "fsck.h" void diff --git a/sbin/fsck/pass4.c b/sbin/fsck/pass4.c index df8f72247186..e20f6fa30372 100644 --- a/sbin/fsck/pass4.c +++ b/sbin/fsck/pass4.c @@ -32,18 +32,19 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include -#include -#include -#include "fsck.h" -int pass4check(); +#include +#include + +#include "fsck.h" void pass4() @@ -54,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++) { @@ -98,7 +99,7 @@ pass4() break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[inumber], inumber); } } @@ -110,7 +111,7 @@ pass4check(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 a6ed6a1b39d5..1ea122bf3e46 100644 --- a/sbin/fsck/pass5.c +++ b/sbin/fsck/pass5.c @@ -32,26 +32,29 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; +static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include +#include #include + #include "fsck.h" void pass5() { - int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; - register struct fs *fs = &sblock; - register struct cg *cg = &cgrp; - daddr_t dbase, dmax; - register daddr_t d; - register long i, j; + int c, blk, frags, basesize, sumsize, mapsize, savednrpos; + 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]; @@ -59,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"); @@ -103,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; @@ -114,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 + @@ -136,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); @@ -188,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; @@ -215,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); } } @@ -249,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; @@ -282,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; sbdirty(); } diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c index b5608617c18d..09b47c37e9df 100644 --- a/sbin/fsck/preen.c +++ b/sbin/fsck/preen.c @@ -32,7 +32,7 @@ */ #ifndef lint -static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; #include #include #include -#include + #include "fsck.h" struct part { @@ -62,19 +62,22 @@ struct disk { int pid; /* If != 0, pid of proc working on */ } *disks; -static void addpart __P((char *name, char *fsname, long auxdata)); -static int startdisk __P((struct disk *dk, int (*checkit)())); -static struct disk *finddisk __P((char *name)); -static char *unrawname __P((char *name)); -static char *rawname __P((char *name)); - 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; @@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit) while ((fsp = getfsent()) != 0) { if ((auxdata = (*docheck)(fsp)) == 0) continue; - if (!preen || (passno == 1 && fsp->fs_passno == 1)) { - name = blockcheck(fsp->fs_spec); - if (name) { - sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0); - if (sumstatus) + 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); @@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit) return (0); } -struct disk * +static struct disk * finddisk(name) char *name; { @@ -206,13 +208,11 @@ finddisk(name) register char *p; size_t len = 0; - 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 && @@ -237,7 +237,7 @@ finddisk(name) return (dk); } -void +static void addpart(name, fsname, auxdata) char *name, *fsname; long auxdata; @@ -269,10 +269,10 @@ addpart(name, fsname, auxdata) pt->auxdata = auxdata; } -int +static int startdisk(dk, checkit) register struct disk *dk; - int (*checkit)(); + int (*checkit)(char *, char *, long, int); { register struct part *pt = dk->part; @@ -288,11 +288,11 @@ startdisk(dk, checkit) } char * -blockcheck(name) - char *name; +blockcheck(origname) + char *origname; { struct stat stslash, stblock, stchar; - char *raw; + char *newname, *raw; struct fstab *fsinfo; int retried = 0, l; @@ -300,60 +300,63 @@ blockcheck(name) 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(origname); retried++; goto retry; } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { - l = strlen(name) - 1; - if (l > 0 && name[l] == '/') + l = strlen(origname) - 1; + if (l > 0 && origname[l] == '/') /* remove trailing slash */ - name[l] = '\0'; - if(!(fsinfo=getfsfile(name))) { + origname[l] = '\0'; + if(!(fsinfo=getfsfile(origname))) { printf("Can't resolve %s to character special device", - name); + origname); return (0); } - name = fsinfo->fs_spec; + newname = fsinfo->fs_spec; retried++; goto retry; } - printf("Warning: Can't find blockdevice corresponding to name %s\n", - name); - return (name); + /* + * 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); @@ -365,14 +368,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 5fb5697e3035..2d25ff6bf9bc 100644 --- a/sbin/fsck/setup.c +++ b/sbin/fsck/setup.c @@ -32,41 +32,49 @@ */ #ifndef lint -static const char sccsid[] = "@(#)setup.c 8.2 (Berkeley) 2/21/94"; +static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95"; #endif /* not lint */ #define DKTYPENAMES #include #include -#include -#include #include #include #include #include + +#include +#include + +#include +#include #include #include #include #include -#include + #include "fsck.h" struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -static int readsb __P((int listerr)); -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 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; @@ -74,6 +82,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); @@ -104,7 +113,7 @@ 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"); + errx(EEXIT, "cannot allocate space for superblock"); lp = getdisklabel((char *)NULL, fsreadfd); if (lp) dev_bsize = secsize = lp->d_secsize; @@ -114,6 +123,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) @@ -137,6 +147,10 @@ setup(dev) pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); bflag = 0; } + if (skipclean && sblock.fs_clean) { + pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); + return (-1); + } maxfsblock = sblock.fs_size; maxino = sblock.fs_ncg * sblock.fs_ipg; /* @@ -223,17 +237,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); } /* @@ -249,7 +262,7 @@ setup(dev) size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); asked++; } } @@ -297,7 +310,7 @@ setup(dev) return (1); badsb: - ckfini(); + ckfini(0); return (0); } @@ -308,7 +321,7 @@ 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); @@ -348,8 +361,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; @@ -362,12 +375,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. */ @@ -375,11 +387,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); @@ -407,7 +434,7 @@ badsb(listerr, s) * can be used. Do NOT attempt to use other macros without verifying that * their needed information is available! */ -int +static int calcsb(dev, devfd, fs) char *dev; int devfd; @@ -418,7 +445,7 @@ calcsb(dev, devfd, fs) register char *cp; int i; - cp = index(dev, '\0') - 1; + 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); @@ -434,7 +461,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; @@ -461,7 +488,7 @@ calcsb(dev, devfd, fs) return (1); } -struct disklabel * +static struct disklabel * getdisklabel(s, fd) char *s; int fd; @@ -472,7 +499,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 d0c91faa6090..badb70348851 100644 --- a/sbin/fsck/utilities.c +++ b/sbin/fsck/utilities.c @@ -32,11 +32,12 @@ */ #ifndef lint -static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; #endif /* not lint */ #include #include + #include #include #include @@ -45,11 +46,14 @@ static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #include #include #include +#include +#include + #include "fsck.h" long diskreads, totalreads; /* Disk cache statistics */ -static void rwerror __P((char *mesg, daddr_t blk)); +static void rwerror __P((char *mesg, ufs_daddr_t blk)); int ftypeok(dp) @@ -119,7 +123,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; @@ -132,7 +136,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; @@ -149,7 +153,7 @@ bufinit() */ struct bufarea * getdatablk(blkno, size) - daddr_t blkno; + ufs_daddr_t blkno; long size; { register struct bufarea *bp; @@ -161,7 +165,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: @@ -179,10 +183,10 @@ getdatablk(blkno, size) 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) { @@ -220,24 +224,25 @@ flush(fd, bp) } } -void +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); } void -ckfini() +ckfini(markclean) + int markclean; { register struct bufarea *bp, *nbp; - int cnt = 0; + int ofsmodified, cnt = 0; if (fswritefd < 0) { (void)close(fsreadfd); @@ -260,8 +265,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)); @@ -273,7 +287,7 @@ int bread(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { char *cp; @@ -290,7 +304,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) { @@ -312,7 +326,7 @@ void bwrite(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { int i; @@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size) /* * allocate a data block with the specified number of fragments */ -int +ufs_daddr_t allocblk(frags) long frags; { @@ -378,7 +392,7 @@ allocblk(frags) */ void freeblk(blkno, frags) - daddr_t blkno; + ufs_daddr_t blkno; long frags; { struct inodesc idesc; @@ -411,7 +425,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]; @@ -435,7 +449,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; @@ -444,15 +458,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(x) - int x; +catch(sig) + int sig; { if (!doinglevel2) - ckfini(); + ckfini(0); exit(12); } @@ -462,8 +476,8 @@ catch(x) * so that reboot sequence may be interrupted. */ void -catchquit(x) - int x; +catchquit(sig) + int sig; { printf("returning to single-user after filesystem check\n"); returntosingle = 1; @@ -475,8 +489,8 @@ catchquit(x) * Used by child processes in preen. */ void -voidquit(x) - int x; +voidquit(sig) + int sig; { sleep(1); @@ -520,76 +534,95 @@ dofix(idesc, msg) return (0); default: - errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); - return (0); + errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix); } /* NOTREACHED */ + return (0); } -/* VARARGS1 */ -void -errexit(const char *s1, ...) -{ - va_list ap; - va_start(ap,s1); - vfprintf(stdout, s1, ap); - va_end(ap); - exit(8); -} +#if __STDC__ +#include +#else +#include +#endif /* * An unexpected inconsistency occured. * Die if preening, otherwise just print message and continue. */ -/* VARARGS1 */ void -pfatal(const char *s, ...) +#if __STDC__ +pfatal(const char *fmt, ...) +#else +pfatal(fmt, va_alist) + char *fmt; + va_dcl +#endif { - va_list ap; - va_start(ap,s); - if (preen) { - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); - printf("\n"); - printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", - cdevname); - exit(8); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (!preen) { + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + return; } - vfprintf(stdout, s, ap); - va_end(ap); + (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 */ void -pwarn(const char *s, ...) +#if __STDC__ +pwarn(const char *fmt, ...) +#else +pwarn(fmt, va_alist) + char *fmt; + va_dcl +#endif { va_list ap; - va_start(ap,s); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif if (preen) - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); + (void)fprintf(stderr, "%s: ", cdevname); + (void)vfprintf(stderr, fmt, ap); va_end(ap); } -#ifndef lint /* * Stub for routines from kernel. */ void -#ifdef __STDC__ +#if __STDC__ panic(const char *fmt, ...) #else panic(fmt, va_alist) char *fmt; + va_dcl #endif { - - pfatal("INTERNAL INCONSISTENCY:"); - errexit(fmt); -} + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); #endif + pfatal("INTERNAL INCONSISTENCY:"); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EEXIT); +} diff --git a/sbin/fsck_ffs/Makefile b/sbin/fsck_ffs/Makefile index e31e9928824f..3155b1a466ea 100644 --- a/sbin/fsck_ffs/Makefile +++ b/sbin/fsck_ffs/Makefile @@ -1,9 +1,10 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 +# @(#)Makefile 8.2 (Berkeley) 4/27/95 PROG= fsck MAN8= fsck.8 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 diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index 9a2b9239a99f..5662b6e4fee1 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -32,17 +32,20 @@ */ #ifndef lint -static const char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #include "fsck.h" char *lfname = "lost+found"; @@ -57,15 +60,14 @@ struct odirtemplate odirhead = { 0, DIRBLKSIZ - 12, 2, ".." }; - -static int chgino __P((struct inodesc *idesc)); -static int dircheck __P((struct inodesc *idesc, struct direct *dp)); -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 *idesc)); -static struct bufarea * getdirblk __P((daddr_t blkno, long size)); -static int lftempname __P((char *bufp, ino_t ino)); -static int mkentry __P((struct inodesc *idesc)); +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. @@ -107,7 +109,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); @@ -119,7 +121,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; @@ -144,7 +146,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(); @@ -158,7 +160,7 @@ dirscan(idesc) /* * get next entry in a directory. */ -struct direct * +static struct direct * fsck_readdir(idesc) register struct inodesc *idesc; { @@ -173,6 +175,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); @@ -202,6 +206,8 @@ fsck_readdir(idesc) 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); @@ -216,7 +222,7 @@ fsck_readdir(idesc) * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */ -int +static int dircheck(idesc, dp) struct inodesc *idesc; register struct direct *dp; @@ -226,8 +232,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; @@ -240,23 +253,17 @@ 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 @@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg) void adjust(idesc, lcnt) register struct inodesc *idesc; - short lcnt; + int lcnt; { register struct dinode *dp; @@ -323,7 +330,7 @@ adjust(idesc, lcnt) } } -int +static int mkentry(idesc) struct inodesc *idesc; { @@ -343,30 +350,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 */ - if (newinofmt) { - dirp->d_type = typemap[idesc->id_parent]; - dirp->d_namlen = newent.d_namlen; - } else { -# if (BYTE_ORDER == LITTLE_ENDIAN) - dirp->d_type = newent.d_namlen; - dirp->d_namlen = 0; -# else - dirp->d_type = 0; - dirp->d_namlen = newent.d_namlen; -# endif - } dirp->d_reclen = newent.d_reclen; - bcopy(idesc->id_name, dirp->d_name, (size_t)newent.d_namlen + 1); + if (newinofmt) + dirp->d_type = typemap[idesc->id_parent]; + else + dirp->d_type = 0; + dirp->d_namlen = newent.d_namlen; + 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); } -int +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) @@ -387,7 +402,7 @@ linkup(orphan, parentdir) struct inodesc idesc; char tempname[BUFSIZ]; - 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"); @@ -501,7 +516,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; @@ -526,7 +541,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; @@ -550,12 +565,12 @@ makeentry(parent, ino, name) /* * Attempt to expand the size of a directory */ -int +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]; @@ -572,21 +587,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"); @@ -631,11 +646,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(); @@ -680,7 +695,7 @@ freedir(ino, parent) /* * generate a temporary name for the lost+found directory. */ -int +static int lftempname(bufp, ino) char *bufp; ino_t ino; @@ -707,9 +722,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_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 57cb17a02096..1967691e989c 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/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 +#include +#include + #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; @@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */ int returntosingle; /* return to single user mode */ int rerun; /* rerun fsck. Only used in non-preen mode */ -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 */ -unsigned 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; @@ -210,84 +213,69 @@ struct dinode zino; #define ALTERED 0x08 #define FOUND 0x10 -/* dir.c */ -void adjust __P((struct inodesc *idesc, short lcnt)); -ino_t allocdir __P((ino_t parent, ino_t request, int mode)); -int changeino __P((ino_t dir, char *name, ino_t newnum)); -void direrror __P((ino_t ino, char *errmesg)); -int dirscan __P((struct inodesc *idesc)); -void fileerror __P((ino_t cwd, ino_t ino, char *errmesg)); -int linkup __P((ino_t orphan, ino_t parentdir)); -int makeentry __P((ino_t parent, ino_t ino, char *name)); -void propagate __P((void)); +#define EEXIT 8 /* Standard error exit. */ -/* ffs_subr.c */ -void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt)); +struct fstab; -/* inode.c */ -ino_t allocino __P((ino_t request, int type)); -void blkerror __P((ino_t ino, char *type, daddr_t blk)); -void cacheino __P((struct dinode *dp, ino_t inumber)); -int chkrange __P((daddr_t blk, int cnt)); -int ckinode __P((struct dinode *dp, struct inodesc *idesc)); -void clri __P((struct inodesc *idesc, char *type, int flag)); -int findino __P((struct inodesc *idesc)); -void freeino __P((ino_t ino)); -void freeinodebuf __P((void)); -struct dinode * ginode __P((ino_t inumber)); -struct inoinfo * getinoinfo __P((ino_t inumber)); -struct dinode * getnextinode __P((ino_t inumber)); -void inodirty __P((void)); -void inocleanup __P((void)); -void pinode __P((ino_t ino)); -void resetinodebuf __P((void)); -int findname __P((struct inodesc *idesc)); - -/* pass1.c */ -void pass1 __P((void)); -int pass1check __P((struct inodesc *idesc)); - -/* pass1b.c */ -void pass1b __P((void)); - -/* pass2.c */ -void pass2 __P((void)); - -/* pass3.c */ -void pass3 __P((void)); - -/* pass4.c */ -void pass4 __P((void)); -int pass4check __P((struct inodesc *idesc)); - -/* pass5.c */ -void pass5 __P((void)); - -/* preen.c */ -char *blockcheck __P((char *name)); -int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); - -/* setup.c */ -int setup __P((char *dev)); - -/* utilities.c */ -int allocblk __P((long frags)); -int bread __P((int fd, char *buf, daddr_t blk, long size)); -void bufinit __P((void)); -void bwrite __P((int fd, char *buf, daddr_t blk, long size)); -void catch __P((int)); -void catchquit __P((int)); -void ckfini __P((void)); -int dofix __P((struct inodesc *idesc, char *msg)); -void errexit __P((const char *s1, ...)) __dead2; -void flush __P((int fd, struct bufarea *bp)); -void freeblk __P((daddr_t blkno, long frags)); -int ftypeok __P((struct dinode *dp)); -void getblk __P((struct bufarea *bp, daddr_t blk, long size)); -struct bufarea * getdatablk __P((daddr_t blkno, long size)); -void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); -void panic __P((const char *, ...)) __dead2; -void pfatal __P((const char *s1, ...)); -void pwarn __P((const char *s1, ...)); -int reply __P((char *question)); -void voidquit __P((int)); +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_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8 index db91f329c571..ee0f7780ed2a 100644 --- a/sbin/fsck_ffs/fsck_ffs.8 +++ b/sbin/fsck_ffs/fsck_ffs.8 @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 -.|' $Id$ +.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 +.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $ .\" -.Dd December 11, 1993 +.Dd May 9, 1995 .Dt FSCK 8 .Os BSD 4 .Sh NAME @@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed to be the partition designator. .Pp The clean flag of each filesystem's superblock is examined and only those filesystems that -are not marked clean are checked. If the +are not marked clean are checked. +Filesystems are marked clean when they are unmounted, +when they have been mounted read-only, or when +.Nm fsck +runs on them successfully. +If the .Fl f option is specified, the filesystems will be checked regardless of the state of their clean flag. @@ -189,7 +194,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 @@ -198,6 +203,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_ffs/inode.c b/sbin/fsck_ffs/inode.c index 5adac75f0832..9e22bdcca72d 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -32,32 +32,35 @@ */ #ifndef lint -static const char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; +static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + +#include #include #include #include #include + #include "fsck.h" static ino_t startinum; -static int iblock __P((struct inodesc *idesc, long ilevel, quad_t isize)); +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; - int ret; - long n, ndb, offset; + ufs_daddr_t *ap; + long ret, n, ndb, offset; struct dinode dino; quad_t remsize, sizepb; mode_t mode; @@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize) 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]; @@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize) */ int chkrange(blk, cnt) - daddr_t blk; + ufs_daddr_t blk; int cnt; { register int c; @@ -268,10 +271,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); @@ -296,11 +299,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)); @@ -338,7 +341,7 @@ 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); } @@ -372,7 +375,7 @@ 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]; @@ -385,15 +388,14 @@ cacheino(dp, inumber) 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; } @@ -412,7 +414,7 @@ getinoinfo(inumber) continue; return (inp); } - errexit("cannot find inode %d\n", inumber); + errx(EEXIT, "cannot find inode %d", inumber); return ((struct inoinfo *)0); } @@ -472,7 +474,7 @@ 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); } @@ -514,7 +516,7 @@ pinode(ino) if (preen) printf("%s: ", cdevname); printf("SIZE=%qu ", dp->di_size); - p = ctime(&dp->di_mtime.tv_sec); + p = ctime(&dp->di_mtime); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); } @@ -522,7 +524,7 @@ 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); @@ -542,7 +544,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 */ } } @@ -585,7 +587,7 @@ allocino(request, type) return (0); } dp->di_mode = type; - (void)time(&dp->di_atime.tv_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); @@ -606,7 +608,7 @@ freeino(ino) struct inodesc idesc; 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_ffs/main.c b/sbin/fsck_ffs/main.c index 363bba76ee78..b6588310ca11 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -38,25 +38,35 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; +static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; #endif /* not lint */ #include #include #include #include + #include +#include #include + +#include +#include #include #include #include #include #include + #include "fsck.h" -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)); + +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)); +int main __P((int argc, char *argv[])); int main(argc, argv) @@ -99,7 +109,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; @@ -116,7 +126,7 @@ main(argc, argv) break; default: - errexit("%c option?\n", ch); + errx(EEXIT, "%c option?", ch); } } argc -= optind; @@ -136,7 +146,7 @@ main(argc, argv) exit(ret); } -int +static int argtoi(flag, req, str, base) int flag; char *req, *str; @@ -147,14 +157,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. */ -int +static int docheck(fsp) register struct fstab *fsp; { @@ -171,25 +181,28 @@ docheck(fsp) * Check the specified filesystem. */ /* ARGSUSED */ -int +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); } @@ -302,7 +315,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); @@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child) if (rerun) printf("\n***** PLEASE RERUN FSCK *****\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_ffs/pass1.c b/sbin/fsck_ffs/pass1.c index 3fec63adc0d8..0114c5e85ec1 100644 --- a/sbin/fsck_ffs/pass1.c +++ b/sbin/fsck_ffs/pass1.c @@ -32,23 +32,27 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + #include #include +#include #include + #include "fsck.h" -static daddr_t badblk; -static daddr_t dupblk; +static ufs_daddr_t badblk; +static ufs_daddr_t dupblk; -static void checkinode __P((ino_t inumber, struct inodesc *idesc)); +static void checkinode __P((ino_t inumber, struct inodesc *)); void pass1() @@ -73,7 +77,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; @@ -89,7 +93,7 @@ pass1() freeinodebuf(); } -void +static void checkinode(inumber, idesc) ino_t inumber; register struct inodesc *idesc; @@ -103,10 +107,10 @@ checkinode(inumber, idesc) 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) { @@ -120,7 +124,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; @@ -148,15 +153,14 @@ checkinode(inumber, idesc) if (bread(fsreadfd, symbuf, fsbtodb(&sblock, dp->di_db[0]), (long)secsize) != 0) - errexit("cannot read symlink"); + errx(EEXIT, "cannot read symlink"); if (debug) { symbuf[dp->di_size] = 0; printf("convert symlink %ld(%s) of size %ld\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(); } @@ -165,7 +169,7 @@ checkinode(inumber, idesc) * will detect any garbage after symlink string. */ if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { - 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--) @@ -198,7 +202,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; @@ -256,7 +260,7 @@ pass1check(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; @@ -268,7 +272,7 @@ pass1check(idesc) if (preen) printf(" (SKIPPING)\n"); else if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } } @@ -286,14 +290,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_ffs/pass1b.c b/sbin/fsck_ffs/pass1b.c index 1450bd80e0a3..e5036c7e8806 100644 --- a/sbin/fsck_ffs/pass1b.c +++ b/sbin/fsck_ffs/pass1b.c @@ -32,18 +32,21 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include + #include + #include "fsck.h" -int pass1bcheck(); static struct dups *duphead; +static int pass1bcheck __P((struct inodesc *)); void pass1b() @@ -53,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; @@ -73,13 +76,13 @@ pass1b() } } -int +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_ffs/pass2.c b/sbin/fsck_ffs/pass2.c index 382207e9602c..6c9eb8b120da 100644 --- a/sbin/fsck_ffs/pass2.c +++ b/sbin/fsck_ffs/pass2.c @@ -32,22 +32,26 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94"; +static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #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() @@ -64,9 +68,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: @@ -74,11 +78,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: @@ -87,11 +91,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; @@ -102,9 +106,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. */ @@ -112,7 +120,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; @@ -144,11 +152,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); @@ -191,7 +198,7 @@ pass2() propagate(); } -int +static int pass2check(idesc) struct inodesc *idesc; { @@ -239,6 +246,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", @@ -247,17 +263,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; @@ -273,6 +289,15 @@ pass2check(idesc) 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); @@ -283,7 +308,7 @@ pass2check(idesc) 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) { @@ -312,7 +337,7 @@ pass2check(idesc) 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; } @@ -346,6 +371,14 @@ pass2check(idesc) 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]) { @@ -412,7 +445,7 @@ pass2check(idesc) 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); } } @@ -425,10 +458,11 @@ pass2check(idesc) /* * Routine to sort disk blocks. */ -int -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_ffs/pass3.c b/sbin/fsck_ffs/pass3.c index 963c41a28c5c..89aff79958fa 100644 --- a/sbin/fsck_ffs/pass3.c +++ b/sbin/fsck_ffs/pass3.c @@ -32,13 +32,15 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; #endif /* not lint */ #include #include + #include #include + #include "fsck.h" void diff --git a/sbin/fsck_ffs/pass4.c b/sbin/fsck_ffs/pass4.c index df8f72247186..e20f6fa30372 100644 --- a/sbin/fsck_ffs/pass4.c +++ b/sbin/fsck_ffs/pass4.c @@ -32,18 +32,19 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include -#include -#include -#include "fsck.h" -int pass4check(); +#include +#include + +#include "fsck.h" void pass4() @@ -54,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++) { @@ -98,7 +99,7 @@ pass4() break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[inumber], inumber); } } @@ -110,7 +111,7 @@ pass4check(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_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index a6ed6a1b39d5..1ea122bf3e46 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -32,26 +32,29 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; +static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include +#include #include + #include "fsck.h" void pass5() { - int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; - register struct fs *fs = &sblock; - register struct cg *cg = &cgrp; - daddr_t dbase, dmax; - register daddr_t d; - register long i, j; + int c, blk, frags, basesize, sumsize, mapsize, savednrpos; + 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]; @@ -59,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"); @@ -103,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; @@ -114,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 + @@ -136,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); @@ -188,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; @@ -215,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); } } @@ -249,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; @@ -282,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; sbdirty(); } diff --git a/sbin/fsck_ffs/preen.c b/sbin/fsck_ffs/preen.c index b5608617c18d..09b47c37e9df 100644 --- a/sbin/fsck_ffs/preen.c +++ b/sbin/fsck_ffs/preen.c @@ -32,7 +32,7 @@ */ #ifndef lint -static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; #include #include #include -#include + #include "fsck.h" struct part { @@ -62,19 +62,22 @@ struct disk { int pid; /* If != 0, pid of proc working on */ } *disks; -static void addpart __P((char *name, char *fsname, long auxdata)); -static int startdisk __P((struct disk *dk, int (*checkit)())); -static struct disk *finddisk __P((char *name)); -static char *unrawname __P((char *name)); -static char *rawname __P((char *name)); - 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; @@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit) while ((fsp = getfsent()) != 0) { if ((auxdata = (*docheck)(fsp)) == 0) continue; - if (!preen || (passno == 1 && fsp->fs_passno == 1)) { - name = blockcheck(fsp->fs_spec); - if (name) { - sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0); - if (sumstatus) + 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); @@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit) return (0); } -struct disk * +static struct disk * finddisk(name) char *name; { @@ -206,13 +208,11 @@ finddisk(name) register char *p; size_t len = 0; - 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 && @@ -237,7 +237,7 @@ finddisk(name) return (dk); } -void +static void addpart(name, fsname, auxdata) char *name, *fsname; long auxdata; @@ -269,10 +269,10 @@ addpart(name, fsname, auxdata) pt->auxdata = auxdata; } -int +static int startdisk(dk, checkit) register struct disk *dk; - int (*checkit)(); + int (*checkit)(char *, char *, long, int); { register struct part *pt = dk->part; @@ -288,11 +288,11 @@ startdisk(dk, checkit) } char * -blockcheck(name) - char *name; +blockcheck(origname) + char *origname; { struct stat stslash, stblock, stchar; - char *raw; + char *newname, *raw; struct fstab *fsinfo; int retried = 0, l; @@ -300,60 +300,63 @@ blockcheck(name) 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(origname); retried++; goto retry; } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { - l = strlen(name) - 1; - if (l > 0 && name[l] == '/') + l = strlen(origname) - 1; + if (l > 0 && origname[l] == '/') /* remove trailing slash */ - name[l] = '\0'; - if(!(fsinfo=getfsfile(name))) { + origname[l] = '\0'; + if(!(fsinfo=getfsfile(origname))) { printf("Can't resolve %s to character special device", - name); + origname); return (0); } - name = fsinfo->fs_spec; + newname = fsinfo->fs_spec; retried++; goto retry; } - printf("Warning: Can't find blockdevice corresponding to name %s\n", - name); - return (name); + /* + * 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); @@ -365,14 +368,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_ffs/setup.c b/sbin/fsck_ffs/setup.c index 5fb5697e3035..2d25ff6bf9bc 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -32,41 +32,49 @@ */ #ifndef lint -static const char sccsid[] = "@(#)setup.c 8.2 (Berkeley) 2/21/94"; +static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95"; #endif /* not lint */ #define DKTYPENAMES #include #include -#include -#include #include #include #include #include + +#include +#include + +#include +#include #include #include #include #include -#include + #include "fsck.h" struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -static int readsb __P((int listerr)); -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 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; @@ -74,6 +82,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); @@ -104,7 +113,7 @@ 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"); + errx(EEXIT, "cannot allocate space for superblock"); lp = getdisklabel((char *)NULL, fsreadfd); if (lp) dev_bsize = secsize = lp->d_secsize; @@ -114,6 +123,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) @@ -137,6 +147,10 @@ setup(dev) pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); bflag = 0; } + if (skipclean && sblock.fs_clean) { + pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); + return (-1); + } maxfsblock = sblock.fs_size; maxino = sblock.fs_ncg * sblock.fs_ipg; /* @@ -223,17 +237,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); } /* @@ -249,7 +262,7 @@ setup(dev) size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); asked++; } } @@ -297,7 +310,7 @@ setup(dev) return (1); badsb: - ckfini(); + ckfini(0); return (0); } @@ -308,7 +321,7 @@ 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); @@ -348,8 +361,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; @@ -362,12 +375,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. */ @@ -375,11 +387,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); @@ -407,7 +434,7 @@ badsb(listerr, s) * can be used. Do NOT attempt to use other macros without verifying that * their needed information is available! */ -int +static int calcsb(dev, devfd, fs) char *dev; int devfd; @@ -418,7 +445,7 @@ calcsb(dev, devfd, fs) register char *cp; int i; - cp = index(dev, '\0') - 1; + 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); @@ -434,7 +461,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; @@ -461,7 +488,7 @@ calcsb(dev, devfd, fs) return (1); } -struct disklabel * +static struct disklabel * getdisklabel(s, fd) char *s; int fd; @@ -472,7 +499,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_ffs/utilities.c b/sbin/fsck_ffs/utilities.c index d0c91faa6090..badb70348851 100644 --- a/sbin/fsck_ffs/utilities.c +++ b/sbin/fsck_ffs/utilities.c @@ -32,11 +32,12 @@ */ #ifndef lint -static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; #endif /* not lint */ #include #include + #include #include #include @@ -45,11 +46,14 @@ static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #include #include #include +#include +#include + #include "fsck.h" long diskreads, totalreads; /* Disk cache statistics */ -static void rwerror __P((char *mesg, daddr_t blk)); +static void rwerror __P((char *mesg, ufs_daddr_t blk)); int ftypeok(dp) @@ -119,7 +123,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; @@ -132,7 +136,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; @@ -149,7 +153,7 @@ bufinit() */ struct bufarea * getdatablk(blkno, size) - daddr_t blkno; + ufs_daddr_t blkno; long size; { register struct bufarea *bp; @@ -161,7 +165,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: @@ -179,10 +183,10 @@ getdatablk(blkno, size) 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) { @@ -220,24 +224,25 @@ flush(fd, bp) } } -void +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); } void -ckfini() +ckfini(markclean) + int markclean; { register struct bufarea *bp, *nbp; - int cnt = 0; + int ofsmodified, cnt = 0; if (fswritefd < 0) { (void)close(fsreadfd); @@ -260,8 +265,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)); @@ -273,7 +287,7 @@ int bread(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { char *cp; @@ -290,7 +304,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) { @@ -312,7 +326,7 @@ void bwrite(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { int i; @@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size) /* * allocate a data block with the specified number of fragments */ -int +ufs_daddr_t allocblk(frags) long frags; { @@ -378,7 +392,7 @@ allocblk(frags) */ void freeblk(blkno, frags) - daddr_t blkno; + ufs_daddr_t blkno; long frags; { struct inodesc idesc; @@ -411,7 +425,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]; @@ -435,7 +449,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; @@ -444,15 +458,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(x) - int x; +catch(sig) + int sig; { if (!doinglevel2) - ckfini(); + ckfini(0); exit(12); } @@ -462,8 +476,8 @@ catch(x) * so that reboot sequence may be interrupted. */ void -catchquit(x) - int x; +catchquit(sig) + int sig; { printf("returning to single-user after filesystem check\n"); returntosingle = 1; @@ -475,8 +489,8 @@ catchquit(x) * Used by child processes in preen. */ void -voidquit(x) - int x; +voidquit(sig) + int sig; { sleep(1); @@ -520,76 +534,95 @@ dofix(idesc, msg) return (0); default: - errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); - return (0); + errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix); } /* NOTREACHED */ + return (0); } -/* VARARGS1 */ -void -errexit(const char *s1, ...) -{ - va_list ap; - va_start(ap,s1); - vfprintf(stdout, s1, ap); - va_end(ap); - exit(8); -} +#if __STDC__ +#include +#else +#include +#endif /* * An unexpected inconsistency occured. * Die if preening, otherwise just print message and continue. */ -/* VARARGS1 */ void -pfatal(const char *s, ...) +#if __STDC__ +pfatal(const char *fmt, ...) +#else +pfatal(fmt, va_alist) + char *fmt; + va_dcl +#endif { - va_list ap; - va_start(ap,s); - if (preen) { - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); - printf("\n"); - printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", - cdevname); - exit(8); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (!preen) { + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + return; } - vfprintf(stdout, s, ap); - va_end(ap); + (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 */ void -pwarn(const char *s, ...) +#if __STDC__ +pwarn(const char *fmt, ...) +#else +pwarn(fmt, va_alist) + char *fmt; + va_dcl +#endif { va_list ap; - va_start(ap,s); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif if (preen) - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); + (void)fprintf(stderr, "%s: ", cdevname); + (void)vfprintf(stderr, fmt, ap); va_end(ap); } -#ifndef lint /* * Stub for routines from kernel. */ void -#ifdef __STDC__ +#if __STDC__ panic(const char *fmt, ...) #else panic(fmt, va_alist) char *fmt; + va_dcl #endif { - - pfatal("INTERNAL INCONSISTENCY:"); - errexit(fmt); -} + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); #endif + pfatal("INTERNAL INCONSISTENCY:"); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EEXIT); +} diff --git a/sbin/fsck_ifs/Makefile b/sbin/fsck_ifs/Makefile index e31e9928824f..3155b1a466ea 100644 --- a/sbin/fsck_ifs/Makefile +++ b/sbin/fsck_ifs/Makefile @@ -1,9 +1,10 @@ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 +# @(#)Makefile 8.2 (Berkeley) 4/27/95 PROG= fsck MAN8= fsck.8 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 diff --git a/sbin/fsck_ifs/dir.c b/sbin/fsck_ifs/dir.c index 9a2b9239a99f..5662b6e4fee1 100644 --- a/sbin/fsck_ifs/dir.c +++ b/sbin/fsck_ifs/dir.c @@ -32,17 +32,20 @@ */ #ifndef lint -static const char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #include "fsck.h" char *lfname = "lost+found"; @@ -57,15 +60,14 @@ struct odirtemplate odirhead = { 0, DIRBLKSIZ - 12, 2, ".." }; - -static int chgino __P((struct inodesc *idesc)); -static int dircheck __P((struct inodesc *idesc, struct direct *dp)); -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 *idesc)); -static struct bufarea * getdirblk __P((daddr_t blkno, long size)); -static int lftempname __P((char *bufp, ino_t ino)); -static int mkentry __P((struct inodesc *idesc)); +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. @@ -107,7 +109,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); @@ -119,7 +121,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; @@ -144,7 +146,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(); @@ -158,7 +160,7 @@ dirscan(idesc) /* * get next entry in a directory. */ -struct direct * +static struct direct * fsck_readdir(idesc) register struct inodesc *idesc; { @@ -173,6 +175,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); @@ -202,6 +206,8 @@ fsck_readdir(idesc) 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); @@ -216,7 +222,7 @@ fsck_readdir(idesc) * Verify that a directory entry is valid. * This is a superset of the checks made in the kernel. */ -int +static int dircheck(idesc, dp) struct inodesc *idesc; register struct direct *dp; @@ -226,8 +232,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; @@ -240,23 +253,17 @@ 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 @@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg) void adjust(idesc, lcnt) register struct inodesc *idesc; - short lcnt; + int lcnt; { register struct dinode *dp; @@ -323,7 +330,7 @@ adjust(idesc, lcnt) } } -int +static int mkentry(idesc) struct inodesc *idesc; { @@ -343,30 +350,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 */ - if (newinofmt) { - dirp->d_type = typemap[idesc->id_parent]; - dirp->d_namlen = newent.d_namlen; - } else { -# if (BYTE_ORDER == LITTLE_ENDIAN) - dirp->d_type = newent.d_namlen; - dirp->d_namlen = 0; -# else - dirp->d_type = 0; - dirp->d_namlen = newent.d_namlen; -# endif - } dirp->d_reclen = newent.d_reclen; - bcopy(idesc->id_name, dirp->d_name, (size_t)newent.d_namlen + 1); + if (newinofmt) + dirp->d_type = typemap[idesc->id_parent]; + else + dirp->d_type = 0; + dirp->d_namlen = newent.d_namlen; + 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); } -int +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) @@ -387,7 +402,7 @@ linkup(orphan, parentdir) struct inodesc idesc; char tempname[BUFSIZ]; - 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"); @@ -501,7 +516,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; @@ -526,7 +541,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; @@ -550,12 +565,12 @@ makeentry(parent, ino, name) /* * Attempt to expand the size of a directory */ -int +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]; @@ -572,21 +587,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"); @@ -631,11 +646,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(); @@ -680,7 +695,7 @@ freedir(ino, parent) /* * generate a temporary name for the lost+found directory. */ -int +static int lftempname(bufp, ino) char *bufp; ino_t ino; @@ -707,9 +722,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_ifs/fsck.h b/sbin/fsck_ifs/fsck.h index 57cb17a02096..1967691e989c 100644 --- a/sbin/fsck_ifs/fsck.h +++ b/sbin/fsck_ifs/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 +#include +#include + #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; @@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */ int returntosingle; /* return to single user mode */ int rerun; /* rerun fsck. Only used in non-preen mode */ -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 */ -unsigned 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; @@ -210,84 +213,69 @@ struct dinode zino; #define ALTERED 0x08 #define FOUND 0x10 -/* dir.c */ -void adjust __P((struct inodesc *idesc, short lcnt)); -ino_t allocdir __P((ino_t parent, ino_t request, int mode)); -int changeino __P((ino_t dir, char *name, ino_t newnum)); -void direrror __P((ino_t ino, char *errmesg)); -int dirscan __P((struct inodesc *idesc)); -void fileerror __P((ino_t cwd, ino_t ino, char *errmesg)); -int linkup __P((ino_t orphan, ino_t parentdir)); -int makeentry __P((ino_t parent, ino_t ino, char *name)); -void propagate __P((void)); +#define EEXIT 8 /* Standard error exit. */ -/* ffs_subr.c */ -void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt)); +struct fstab; -/* inode.c */ -ino_t allocino __P((ino_t request, int type)); -void blkerror __P((ino_t ino, char *type, daddr_t blk)); -void cacheino __P((struct dinode *dp, ino_t inumber)); -int chkrange __P((daddr_t blk, int cnt)); -int ckinode __P((struct dinode *dp, struct inodesc *idesc)); -void clri __P((struct inodesc *idesc, char *type, int flag)); -int findino __P((struct inodesc *idesc)); -void freeino __P((ino_t ino)); -void freeinodebuf __P((void)); -struct dinode * ginode __P((ino_t inumber)); -struct inoinfo * getinoinfo __P((ino_t inumber)); -struct dinode * getnextinode __P((ino_t inumber)); -void inodirty __P((void)); -void inocleanup __P((void)); -void pinode __P((ino_t ino)); -void resetinodebuf __P((void)); -int findname __P((struct inodesc *idesc)); - -/* pass1.c */ -void pass1 __P((void)); -int pass1check __P((struct inodesc *idesc)); - -/* pass1b.c */ -void pass1b __P((void)); - -/* pass2.c */ -void pass2 __P((void)); - -/* pass3.c */ -void pass3 __P((void)); - -/* pass4.c */ -void pass4 __P((void)); -int pass4check __P((struct inodesc *idesc)); - -/* pass5.c */ -void pass5 __P((void)); - -/* preen.c */ -char *blockcheck __P((char *name)); -int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); - -/* setup.c */ -int setup __P((char *dev)); - -/* utilities.c */ -int allocblk __P((long frags)); -int bread __P((int fd, char *buf, daddr_t blk, long size)); -void bufinit __P((void)); -void bwrite __P((int fd, char *buf, daddr_t blk, long size)); -void catch __P((int)); -void catchquit __P((int)); -void ckfini __P((void)); -int dofix __P((struct inodesc *idesc, char *msg)); -void errexit __P((const char *s1, ...)) __dead2; -void flush __P((int fd, struct bufarea *bp)); -void freeblk __P((daddr_t blkno, long frags)); -int ftypeok __P((struct dinode *dp)); -void getblk __P((struct bufarea *bp, daddr_t blk, long size)); -struct bufarea * getdatablk __P((daddr_t blkno, long size)); -void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); -void panic __P((const char *, ...)) __dead2; -void pfatal __P((const char *s1, ...)); -void pwarn __P((const char *s1, ...)); -int reply __P((char *question)); -void voidquit __P((int)); +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_ifs/fsck_ifs.8 b/sbin/fsck_ifs/fsck_ifs.8 index db91f329c571..ee0f7780ed2a 100644 --- a/sbin/fsck_ifs/fsck_ifs.8 +++ b/sbin/fsck_ifs/fsck_ifs.8 @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 -.|' $Id$ +.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95 +.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $ .\" -.Dd December 11, 1993 +.Dd May 9, 1995 .Dt FSCK 8 .Os BSD 4 .Sh NAME @@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed to be the partition designator. .Pp The clean flag of each filesystem's superblock is examined and only those filesystems that -are not marked clean are checked. If the +are not marked clean are checked. +Filesystems are marked clean when they are unmounted, +when they have been mounted read-only, or when +.Nm fsck +runs on them successfully. +If the .Fl f option is specified, the filesystems will be checked regardless of the state of their clean flag. @@ -189,7 +194,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 @@ -198,6 +203,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_ifs/inode.c b/sbin/fsck_ifs/inode.c index 5adac75f0832..9e22bdcca72d 100644 --- a/sbin/fsck_ifs/inode.c +++ b/sbin/fsck_ifs/inode.c @@ -32,32 +32,35 @@ */ #ifndef lint -static const char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; +static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + +#include #include #include #include #include + #include "fsck.h" static ino_t startinum; -static int iblock __P((struct inodesc *idesc, long ilevel, quad_t isize)); +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; - int ret; - long n, ndb, offset; + ufs_daddr_t *ap; + long ret, n, ndb, offset; struct dinode dino; quad_t remsize, sizepb; mode_t mode; @@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize) 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]; @@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize) */ int chkrange(blk, cnt) - daddr_t blk; + ufs_daddr_t blk; int cnt; { register int c; @@ -268,10 +271,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); @@ -296,11 +299,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)); @@ -338,7 +341,7 @@ 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); } @@ -372,7 +375,7 @@ 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]; @@ -385,15 +388,14 @@ cacheino(dp, inumber) 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; } @@ -412,7 +414,7 @@ getinoinfo(inumber) continue; return (inp); } - errexit("cannot find inode %d\n", inumber); + errx(EEXIT, "cannot find inode %d", inumber); return ((struct inoinfo *)0); } @@ -472,7 +474,7 @@ 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); } @@ -514,7 +516,7 @@ pinode(ino) if (preen) printf("%s: ", cdevname); printf("SIZE=%qu ", dp->di_size); - p = ctime(&dp->di_mtime.tv_sec); + p = ctime(&dp->di_mtime); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); } @@ -522,7 +524,7 @@ 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); @@ -542,7 +544,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 */ } } @@ -585,7 +587,7 @@ allocino(request, type) return (0); } dp->di_mode = type; - (void)time(&dp->di_atime.tv_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); @@ -606,7 +608,7 @@ freeino(ino) struct inodesc idesc; 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_ifs/main.c b/sbin/fsck_ifs/main.c index 363bba76ee78..b6588310ca11 100644 --- a/sbin/fsck_ifs/main.c +++ b/sbin/fsck_ifs/main.c @@ -38,25 +38,35 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; +static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95"; #endif /* not lint */ #include #include #include #include + #include +#include #include + +#include +#include #include #include #include #include #include + #include "fsck.h" -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)); + +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)); +int main __P((int argc, char *argv[])); int main(argc, argv) @@ -99,7 +109,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; @@ -116,7 +126,7 @@ main(argc, argv) break; default: - errexit("%c option?\n", ch); + errx(EEXIT, "%c option?", ch); } } argc -= optind; @@ -136,7 +146,7 @@ main(argc, argv) exit(ret); } -int +static int argtoi(flag, req, str, base) int flag; char *req, *str; @@ -147,14 +157,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. */ -int +static int docheck(fsp) register struct fstab *fsp; { @@ -171,25 +181,28 @@ docheck(fsp) * Check the specified filesystem. */ /* ARGSUSED */ -int +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); } @@ -302,7 +315,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); @@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child) if (rerun) printf("\n***** PLEASE RERUN FSCK *****\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_ifs/pass1.c b/sbin/fsck_ifs/pass1.c index 3fec63adc0d8..0114c5e85ec1 100644 --- a/sbin/fsck_ifs/pass1.c +++ b/sbin/fsck_ifs/pass1.c @@ -32,23 +32,27 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include + #include #include +#include #include + #include "fsck.h" -static daddr_t badblk; -static daddr_t dupblk; +static ufs_daddr_t badblk; +static ufs_daddr_t dupblk; -static void checkinode __P((ino_t inumber, struct inodesc *idesc)); +static void checkinode __P((ino_t inumber, struct inodesc *)); void pass1() @@ -73,7 +77,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; @@ -89,7 +93,7 @@ pass1() freeinodebuf(); } -void +static void checkinode(inumber, idesc) ino_t inumber; register struct inodesc *idesc; @@ -103,10 +107,10 @@ checkinode(inumber, idesc) 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) { @@ -120,7 +124,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; @@ -148,15 +153,14 @@ checkinode(inumber, idesc) if (bread(fsreadfd, symbuf, fsbtodb(&sblock, dp->di_db[0]), (long)secsize) != 0) - errexit("cannot read symlink"); + errx(EEXIT, "cannot read symlink"); if (debug) { symbuf[dp->di_size] = 0; printf("convert symlink %ld(%s) of size %ld\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(); } @@ -165,7 +169,7 @@ checkinode(inumber, idesc) * will detect any garbage after symlink string. */ if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { - 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--) @@ -198,7 +202,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; @@ -256,7 +260,7 @@ pass1check(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; @@ -268,7 +272,7 @@ pass1check(idesc) if (preen) printf(" (SKIPPING)\n"); else if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); return (STOP); } } @@ -286,14 +290,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_ifs/pass1b.c b/sbin/fsck_ifs/pass1b.c index 1450bd80e0a3..e5036c7e8806 100644 --- a/sbin/fsck_ifs/pass1b.c +++ b/sbin/fsck_ifs/pass1b.c @@ -32,18 +32,21 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include + #include + #include "fsck.h" -int pass1bcheck(); static struct dups *duphead; +static int pass1bcheck __P((struct inodesc *)); void pass1b() @@ -53,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; @@ -73,13 +76,13 @@ pass1b() } } -int +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_ifs/pass2.c b/sbin/fsck_ifs/pass2.c index 382207e9602c..6c9eb8b120da 100644 --- a/sbin/fsck_ifs/pass2.c +++ b/sbin/fsck_ifs/pass2.c @@ -32,22 +32,26 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94"; +static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include #include #include +#include #include + #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() @@ -64,9 +68,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: @@ -74,11 +78,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: @@ -87,11 +91,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; @@ -102,9 +106,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. */ @@ -112,7 +120,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; @@ -144,11 +152,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); @@ -191,7 +198,7 @@ pass2() propagate(); } -int +static int pass2check(idesc) struct inodesc *idesc; { @@ -239,6 +246,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", @@ -247,17 +263,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; @@ -273,6 +289,15 @@ pass2check(idesc) 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); @@ -283,7 +308,7 @@ pass2check(idesc) 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) { @@ -312,7 +337,7 @@ pass2check(idesc) 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; } @@ -346,6 +371,14 @@ pass2check(idesc) 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]) { @@ -412,7 +445,7 @@ pass2check(idesc) 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); } } @@ -425,10 +458,11 @@ pass2check(idesc) /* * Routine to sort disk blocks. */ -int -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_ifs/pass3.c b/sbin/fsck_ifs/pass3.c index 963c41a28c5c..89aff79958fa 100644 --- a/sbin/fsck_ifs/pass3.c +++ b/sbin/fsck_ifs/pass3.c @@ -32,13 +32,15 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95"; #endif /* not lint */ #include #include + #include #include + #include "fsck.h" void diff --git a/sbin/fsck_ifs/pass4.c b/sbin/fsck_ifs/pass4.c index df8f72247186..e20f6fa30372 100644 --- a/sbin/fsck_ifs/pass4.c +++ b/sbin/fsck_ifs/pass4.c @@ -32,18 +32,19 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include -#include -#include -#include "fsck.h" -int pass4check(); +#include +#include + +#include "fsck.h" void pass4() @@ -54,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++) { @@ -98,7 +99,7 @@ pass4() break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[inumber], inumber); } } @@ -110,7 +111,7 @@ pass4check(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_ifs/pass5.c b/sbin/fsck_ifs/pass5.c index a6ed6a1b39d5..1ea122bf3e46 100644 --- a/sbin/fsck_ifs/pass5.c +++ b/sbin/fsck_ifs/pass5.c @@ -32,26 +32,29 @@ */ #ifndef lint -static const char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; +static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95"; #endif /* not lint */ #include #include + #include #include #include +#include #include + #include "fsck.h" void pass5() { - int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; - register struct fs *fs = &sblock; - register struct cg *cg = &cgrp; - daddr_t dbase, dmax; - register daddr_t d; - register long i, j; + int c, blk, frags, basesize, sumsize, mapsize, savednrpos; + 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]; @@ -59,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"); @@ -103,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; @@ -114,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 + @@ -136,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); @@ -188,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; @@ -215,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); } } @@ -249,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; @@ -282,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; sbdirty(); } diff --git a/sbin/fsck_ifs/preen.c b/sbin/fsck_ifs/preen.c index b5608617c18d..09b47c37e9df 100644 --- a/sbin/fsck_ifs/preen.c +++ b/sbin/fsck_ifs/preen.c @@ -32,7 +32,7 @@ */ #ifndef lint -static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; #include #include #include -#include + #include "fsck.h" struct part { @@ -62,19 +62,22 @@ struct disk { int pid; /* If != 0, pid of proc working on */ } *disks; -static void addpart __P((char *name, char *fsname, long auxdata)); -static int startdisk __P((struct disk *dk, int (*checkit)())); -static struct disk *finddisk __P((char *name)); -static char *unrawname __P((char *name)); -static char *rawname __P((char *name)); - 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; @@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit) while ((fsp = getfsent()) != 0) { if ((auxdata = (*docheck)(fsp)) == 0) continue; - if (!preen || (passno == 1 && fsp->fs_passno == 1)) { - name = blockcheck(fsp->fs_spec); - if (name) { - sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0); - if (sumstatus) + 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); @@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit) return (0); } -struct disk * +static struct disk * finddisk(name) char *name; { @@ -206,13 +208,11 @@ finddisk(name) register char *p; size_t len = 0; - 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 && @@ -237,7 +237,7 @@ finddisk(name) return (dk); } -void +static void addpart(name, fsname, auxdata) char *name, *fsname; long auxdata; @@ -269,10 +269,10 @@ addpart(name, fsname, auxdata) pt->auxdata = auxdata; } -int +static int startdisk(dk, checkit) register struct disk *dk; - int (*checkit)(); + int (*checkit)(char *, char *, long, int); { register struct part *pt = dk->part; @@ -288,11 +288,11 @@ startdisk(dk, checkit) } char * -blockcheck(name) - char *name; +blockcheck(origname) + char *origname; { struct stat stslash, stblock, stchar; - char *raw; + char *newname, *raw; struct fstab *fsinfo; int retried = 0, l; @@ -300,60 +300,63 @@ blockcheck(name) 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(origname); retried++; goto retry; } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { - l = strlen(name) - 1; - if (l > 0 && name[l] == '/') + l = strlen(origname) - 1; + if (l > 0 && origname[l] == '/') /* remove trailing slash */ - name[l] = '\0'; - if(!(fsinfo=getfsfile(name))) { + origname[l] = '\0'; + if(!(fsinfo=getfsfile(origname))) { printf("Can't resolve %s to character special device", - name); + origname); return (0); } - name = fsinfo->fs_spec; + newname = fsinfo->fs_spec; retried++; goto retry; } - printf("Warning: Can't find blockdevice corresponding to name %s\n", - name); - return (name); + /* + * 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); @@ -365,14 +368,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_ifs/setup.c b/sbin/fsck_ifs/setup.c index 5fb5697e3035..2d25ff6bf9bc 100644 --- a/sbin/fsck_ifs/setup.c +++ b/sbin/fsck_ifs/setup.c @@ -32,41 +32,49 @@ */ #ifndef lint -static const char sccsid[] = "@(#)setup.c 8.2 (Berkeley) 2/21/94"; +static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95"; #endif /* not lint */ #define DKTYPENAMES #include #include -#include -#include #include #include #include #include + +#include +#include + +#include +#include #include #include #include #include -#include + #include "fsck.h" struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -static int readsb __P((int listerr)); -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 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; @@ -74,6 +82,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); @@ -104,7 +113,7 @@ 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"); + errx(EEXIT, "cannot allocate space for superblock"); lp = getdisklabel((char *)NULL, fsreadfd); if (lp) dev_bsize = secsize = lp->d_secsize; @@ -114,6 +123,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) @@ -137,6 +147,10 @@ setup(dev) pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); bflag = 0; } + if (skipclean && sblock.fs_clean) { + pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n"); + return (-1); + } maxfsblock = sblock.fs_size; maxino = sblock.fs_ncg * sblock.fs_ipg; /* @@ -223,17 +237,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); } /* @@ -249,7 +262,7 @@ setup(dev) size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); if (reply("CONTINUE") == 0) - errexit(""); + exit(EEXIT); asked++; } } @@ -297,7 +310,7 @@ setup(dev) return (1); badsb: - ckfini(); + ckfini(0); return (0); } @@ -308,7 +321,7 @@ 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); @@ -348,8 +361,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; @@ -362,12 +375,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. */ @@ -375,11 +387,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); @@ -407,7 +434,7 @@ badsb(listerr, s) * can be used. Do NOT attempt to use other macros without verifying that * their needed information is available! */ -int +static int calcsb(dev, devfd, fs) char *dev; int devfd; @@ -418,7 +445,7 @@ calcsb(dev, devfd, fs) register char *cp; int i; - cp = index(dev, '\0') - 1; + 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); @@ -434,7 +461,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; @@ -461,7 +488,7 @@ calcsb(dev, devfd, fs) return (1); } -struct disklabel * +static struct disklabel * getdisklabel(s, fd) char *s; int fd; @@ -472,7 +499,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_ifs/utilities.c b/sbin/fsck_ifs/utilities.c index d0c91faa6090..badb70348851 100644 --- a/sbin/fsck_ifs/utilities.c +++ b/sbin/fsck_ifs/utilities.c @@ -32,11 +32,12 @@ */ #ifndef lint -static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95"; #endif /* not lint */ #include #include + #include #include #include @@ -45,11 +46,14 @@ static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #include #include #include +#include +#include + #include "fsck.h" long diskreads, totalreads; /* Disk cache statistics */ -static void rwerror __P((char *mesg, daddr_t blk)); +static void rwerror __P((char *mesg, ufs_daddr_t blk)); int ftypeok(dp) @@ -119,7 +123,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; @@ -132,7 +136,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; @@ -149,7 +153,7 @@ bufinit() */ struct bufarea * getdatablk(blkno, size) - daddr_t blkno; + ufs_daddr_t blkno; long size; { register struct bufarea *bp; @@ -161,7 +165,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: @@ -179,10 +183,10 @@ getdatablk(blkno, size) 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) { @@ -220,24 +224,25 @@ flush(fd, bp) } } -void +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); } void -ckfini() +ckfini(markclean) + int markclean; { register struct bufarea *bp, *nbp; - int cnt = 0; + int ofsmodified, cnt = 0; if (fswritefd < 0) { (void)close(fsreadfd); @@ -260,8 +265,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)); @@ -273,7 +287,7 @@ int bread(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { char *cp; @@ -290,7 +304,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) { @@ -312,7 +326,7 @@ void bwrite(fd, buf, blk, size) int fd; char *buf; - daddr_t blk; + ufs_daddr_t blk; long size; { int i; @@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size) /* * allocate a data block with the specified number of fragments */ -int +ufs_daddr_t allocblk(frags) long frags; { @@ -378,7 +392,7 @@ allocblk(frags) */ void freeblk(blkno, frags) - daddr_t blkno; + ufs_daddr_t blkno; long frags; { struct inodesc idesc; @@ -411,7 +425,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]; @@ -435,7 +449,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; @@ -444,15 +458,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(x) - int x; +catch(sig) + int sig; { if (!doinglevel2) - ckfini(); + ckfini(0); exit(12); } @@ -462,8 +476,8 @@ catch(x) * so that reboot sequence may be interrupted. */ void -catchquit(x) - int x; +catchquit(sig) + int sig; { printf("returning to single-user after filesystem check\n"); returntosingle = 1; @@ -475,8 +489,8 @@ catchquit(x) * Used by child processes in preen. */ void -voidquit(x) - int x; +voidquit(sig) + int sig; { sleep(1); @@ -520,76 +534,95 @@ dofix(idesc, msg) return (0); default: - errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); - return (0); + errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix); } /* NOTREACHED */ + return (0); } -/* VARARGS1 */ -void -errexit(const char *s1, ...) -{ - va_list ap; - va_start(ap,s1); - vfprintf(stdout, s1, ap); - va_end(ap); - exit(8); -} +#if __STDC__ +#include +#else +#include +#endif /* * An unexpected inconsistency occured. * Die if preening, otherwise just print message and continue. */ -/* VARARGS1 */ void -pfatal(const char *s, ...) +#if __STDC__ +pfatal(const char *fmt, ...) +#else +pfatal(fmt, va_alist) + char *fmt; + va_dcl +#endif { - va_list ap; - va_start(ap,s); - if (preen) { - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); - printf("\n"); - printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", - cdevname); - exit(8); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + if (!preen) { + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + return; } - vfprintf(stdout, s, ap); - va_end(ap); + (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 */ void -pwarn(const char *s, ...) +#if __STDC__ +pwarn(const char *fmt, ...) +#else +pwarn(fmt, va_alist) + char *fmt; + va_dcl +#endif { va_list ap; - va_start(ap,s); +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif if (preen) - printf("%s: ", cdevname); - vfprintf(stdout, s, ap); + (void)fprintf(stderr, "%s: ", cdevname); + (void)vfprintf(stderr, fmt, ap); va_end(ap); } -#ifndef lint /* * Stub for routines from kernel. */ void -#ifdef __STDC__ +#if __STDC__ panic(const char *fmt, ...) #else panic(fmt, va_alist) char *fmt; + va_dcl #endif { - - pfatal("INTERNAL INCONSISTENCY:"); - errexit(fmt); -} + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); #endif + pfatal("INTERNAL INCONSISTENCY:"); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EEXIT); +} diff --git a/sbin/quotacheck/preen.c b/sbin/quotacheck/preen.c index b5608617c18d..09b47c37e9df 100644 --- a/sbin/quotacheck/preen.c +++ b/sbin/quotacheck/preen.c @@ -32,7 +32,7 @@ */ #ifndef lint -static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; +static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95"; #endif /* not lint */ #include @@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; #include #include #include -#include + #include "fsck.h" struct part { @@ -62,19 +62,22 @@ struct disk { int pid; /* If != 0, pid of proc working on */ } *disks; -static void addpart __P((char *name, char *fsname, long auxdata)); -static int startdisk __P((struct disk *dk, int (*checkit)())); -static struct disk *finddisk __P((char *name)); -static char *unrawname __P((char *name)); -static char *rawname __P((char *name)); - 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; @@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit) while ((fsp = getfsent()) != 0) { if ((auxdata = (*docheck)(fsp)) == 0) continue; - if (!preen || (passno == 1 && fsp->fs_passno == 1)) { - name = blockcheck(fsp->fs_spec); - if (name) { - sumstatus = (*chkit)(name, - fsp->fs_file, auxdata, 0); - if (sumstatus) + 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); @@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit) return (0); } -struct disk * +static struct disk * finddisk(name) char *name; { @@ -206,13 +208,11 @@ finddisk(name) register char *p; size_t len = 0; - 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 && @@ -237,7 +237,7 @@ finddisk(name) return (dk); } -void +static void addpart(name, fsname, auxdata) char *name, *fsname; long auxdata; @@ -269,10 +269,10 @@ addpart(name, fsname, auxdata) pt->auxdata = auxdata; } -int +static int startdisk(dk, checkit) register struct disk *dk; - int (*checkit)(); + int (*checkit)(char *, char *, long, int); { register struct part *pt = dk->part; @@ -288,11 +288,11 @@ startdisk(dk, checkit) } char * -blockcheck(name) - char *name; +blockcheck(origname) + char *origname; { struct stat stslash, stblock, stchar; - char *raw; + char *newname, *raw; struct fstab *fsinfo; int retried = 0, l; @@ -300,60 +300,63 @@ blockcheck(name) 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(origname); retried++; goto retry; } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { - l = strlen(name) - 1; - if (l > 0 && name[l] == '/') + l = strlen(origname) - 1; + if (l > 0 && origname[l] == '/') /* remove trailing slash */ - name[l] = '\0'; - if(!(fsinfo=getfsfile(name))) { + origname[l] = '\0'; + if(!(fsinfo=getfsfile(origname))) { printf("Can't resolve %s to character special device", - name); + origname); return (0); } - name = fsinfo->fs_spec; + newname = fsinfo->fs_spec; retried++; goto retry; } - printf("Warning: Can't find blockdevice corresponding to name %s\n", - name); - return (name); + /* + * 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); @@ -365,14 +368,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);