diff options
author | peter <peter@FreeBSD.org> | 1997-03-11 12:20:21 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1997-03-11 12:20:21 +0000 |
commit | ac28da2dc002612b2fd129500af8084d63aa8504 (patch) | |
tree | 8cadfc9709953ec63a6c3fe257fe499055b9f832 /sbin/fsck_ffs | |
parent | 683ee3c015f8c8071f4de0e2cd952c8643315c98 (diff) | |
download | FreeBSD-src-ac28da2dc002612b2fd129500af8084d63aa8504.zip FreeBSD-src-ac28da2dc002612b2fd129500af8084d63aa8504.tar.gz |
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.
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r-- | sbin/fsck_ffs/Makefile | 3 | ||||
-rw-r--r-- | sbin/fsck_ffs/dir.c | 143 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsck.h | 194 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsck_ffs.8 | 19 | ||||
-rw-r--r-- | sbin/fsck_ffs/inode.c | 54 | ||||
-rw-r--r-- | sbin/fsck_ffs/main.c | 80 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass1.c | 44 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass1b.c | 13 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass2.c | 82 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass3.c | 4 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass4.c | 15 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 73 | ||||
-rw-r--r-- | sbin/fsck_ffs/preen.c | 99 | ||||
-rw-r--r-- | sbin/fsck_ffs/setup.c | 93 | ||||
-rw-r--r-- | sbin/fsck_ffs/utilities.c | 161 |
15 files changed, 613 insertions, 464 deletions
diff --git a/sbin/fsck_ffs/Makefile b/sbin/fsck_ffs/Makefile index e31e992..3155b1a 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 <bsd.prog.mk> diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index 9a2b923..5662b6e 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> #include <stdio.h> #include <stdlib.h> +#include <err.h> #include <string.h> + #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 @@ dpok: size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); idesc->id_loc += size; idesc->id_filesize -= size; + if (idesc->id_fix == IGNORE) + return (0); fix = dofix(idesc, "DIRECTORY CORRUPTED"); bp = getdirblk(idesc->id_blkno, blksiz); dp = (struct direct *)(bp->b_un.b_buf + dploc); @@ -216,7 +222,7 @@ dpok: * 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 57cb17a..1967691 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 <unistd.h> +#include <stdlib.h> +#include <stdio.h> + #define MAXDUP 10 /* limit on dup blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ @@ -53,20 +57,20 @@ * buffer cache structure. */ struct bufarea { - struct bufarea *b_next; /* free list queue */ - struct bufarea *b_prev; /* free list queue */ - daddr_t b_bno; - int b_size; - int b_errs; - int b_flags; + struct bufarea *b_next; /* free list queue */ + struct bufarea *b_prev; /* free list queue */ + ufs_daddr_t b_bno; + int b_size; + int b_errs; + int b_flags; union { - char *b_buf; /* buffer space */ - daddr_t *b_indir; /* indirect block */ - struct fs *b_fs; /* super block */ - struct cg *b_cg; /* cylinder group */ - struct dinode *b_dinode; /* inode block */ + char *b_buf; /* buffer space */ + ufs_daddr_t *b_indir; /* indirect block */ + struct fs *b_fs; /* super block */ + struct cg *b_cg; /* cylinder group */ + struct dinode *b_dinode; /* inode block */ } b_un; - char b_dirty; + char b_dirty; }; #define B_INUSE 1 @@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */ struct bufarea cgblk; /* cylinder group blocks */ struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pbp; /* current inode block */ -struct bufarea *getdatablk(); #define dirty(bp) (bp)->b_dirty = 1 #define initbarea(bp) \ (bp)->b_dirty = 0; \ - (bp)->b_bno = (daddr_t)-1; \ + (bp)->b_bno = (ufs_daddr_t)-1; \ (bp)->b_flags = 0; #define sbdirty() sblk.b_dirty = 1 @@ -97,7 +100,7 @@ struct inodesc { int (*id_func)(); /* function to be applied to blocks of inode */ ino_t id_number; /* inode number described */ ino_t id_parent; /* for DATA nodes, their parent */ - daddr_t id_blkno; /* current block number being examined */ + ufs_daddr_t id_blkno; /* current block number being examined */ int id_numfrags; /* number of frags contained in block */ quad_t id_filesize; /* for DATA nodes, the size of the directory */ int id_loc; /* for DATA nodes, current location in dir */ @@ -133,7 +136,7 @@ struct inodesc { */ struct dups { struct dups *next; - daddr_t dup; + ufs_daddr_t dup; }; struct dups *duplist; /* head of dup list */ struct dups *muldup; /* end of unique duplicate dup block numbers */ @@ -157,7 +160,7 @@ struct inoinfo { ino_t i_dotdot; /* inode number of `..' */ size_t i_isize; /* size of inode */ u_int i_numblks; /* size of block array in bytes */ - daddr_t i_blks[1]; /* actually longer */ + ufs_daddr_t i_blks[1]; /* actually longer */ } **inphead, **inpsort; long numdirs, listmax, inplast; @@ -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)); - -/* ffs_subr.c */ -void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt)); - -/* 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)); +#define EEXIT 8 /* Standard error exit. */ + +struct fstab; + +void adjust __P((struct inodesc *, int lcnt)); +ufs_daddr_t allocblk __P((long frags)); +ino_t allocdir __P((ino_t parent, ino_t request, int mode)); +ino_t allocino __P((ino_t request, int type)); +void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk)); +char *blockcheck __P((char *name)); +int bread __P((int fd, char *buf, ufs_daddr_t blk, long size)); +void bufinit __P((void)); +void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size)); +void cacheino __P((struct dinode *dp, ino_t inumber)); +void catch __P((int)); +void catchquit __P((int)); +int changeino __P((ino_t dir, char *name, ino_t newnum)); +int checkfstab __P((int preen, int maxrun, + int (*docheck)(struct fstab *), + int (*chkit)(char *, char *, long, int))); +int chkrange __P((ufs_daddr_t blk, int cnt)); +void ckfini __P((int markclean)); +int ckinode __P((struct dinode *dp, struct inodesc *)); +void clri __P((struct inodesc *, char *type, int flag)); +void direrror __P((ino_t ino, char *errmesg)); +int dirscan __P((struct inodesc *)); +int dofix __P((struct inodesc *, char *msg)); +void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t)); +void ffs_fragacct __P((struct fs *, int, int32_t [], int)); +int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t)); +void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t)); +void fileerror __P((ino_t cwd, ino_t ino, char *errmesg)); +int findino __P((struct inodesc *)); +int findname __P((struct inodesc *)); +void flush __P((int fd, struct bufarea *bp)); +void freeblk __P((ufs_daddr_t blkno, long frags)); +void freeino __P((ino_t ino)); +void freeinodebuf __P((void)); +int ftypeok __P((struct dinode *dp)); +void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size)); +struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size)); +struct inoinfo *getinoinfo __P((ino_t inumber)); +struct dinode *getnextinode __P((ino_t inumber)); +void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); +struct dinode *ginode __P((ino_t inumber)); +void inocleanup __P((void)); +void inodirty __P((void)); +int linkup __P((ino_t orphan, ino_t parentdir)); +int makeentry __P((ino_t parent, ino_t ino, char *name)); +void panic __P((const char *fmt, ...)); +void pass1 __P((void)); +void pass1b __P((void)); +int pass1check __P((struct inodesc *)); +void pass2 __P((void)); +void pass3 __P((void)); +void pass4 __P((void)); +int pass4check __P((struct inodesc *)); +void pass5 __P((void)); +void pfatal __P((const char *fmt, ...)); +void pinode __P((ino_t ino)); +void propagate __P((void)); +void pwarn __P((const char *fmt, ...)); +int reply __P((char *question)); +void resetinodebuf __P((void)); +int setup __P((char *dev)); +void voidquit __P((int)); diff --git a/sbin/fsck_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8 index db91f32..ee0f778 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 5adac75..9e22bdc 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> + +#include <err.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> + #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 363bba7..b658831 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 <sys/param.h> #include <sys/time.h> #include <sys/proc.h> #include <sys/mount.h> + #include <ufs/ufs/dinode.h> +#include <ufs/ufs/ufsmount.h> #include <ufs/ffs/fs.h> + +#include <ctype.h> +#include <err.h> #include <fstab.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <stdio.h> + #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 3fec63a..0114c5e 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> + #include <stdio.h> #include <stdlib.h> +#include <err.h> #include <string.h> + #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 1450bd8..e5036c7 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> + #include <string.h> + #include "fsck.h" -int pass1bcheck(); static struct dups *duphead; +static int pass1bcheck __P((struct inodesc *)); void pass1b() @@ -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 382207e..6c9eb8b 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> #include <stdio.h> #include <stdlib.h> +#include <err.h> #include <string.h> + #include "fsck.h" #define MINDIRSIZE (sizeof (struct dirtemplate)) -int pass2check(), blksort(); +static int blksort __P((const void *, const void *)); +static int pass2check __P((struct inodesc *)); void pass2() @@ -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 @@ chk1: proto.d_type = 0; proto.d_namlen = 2; (void)strcpy(proto.d_name, ".."); +# if BYTE_ORDER == LITTLE_ENDIAN + if (!newinofmt) { + u_char tmp; + + tmp = proto.d_type; + proto.d_type = proto.d_namlen; + proto.d_namlen = tmp; + } +# endif entrysize = DIRSIZ(0, &proto); if (idesc->id_entryno == 0) { n = DIRSIZ(0, dirp); @@ -283,7 +308,7 @@ chk1: idesc->id_entryno++; lncntp[dirp->d_ino]--; dirp = (struct direct *)((char *)(dirp) + n); - bzero((char *)dirp, (size_t)proto.d_reclen); + memset(dirp, 0, (size_t)proto.d_reclen); dirp->d_reclen = proto.d_reclen; } if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { @@ -312,7 +337,7 @@ chk1: inp->i_dotdot = inp->i_parent; fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); proto.d_reclen = dirp->d_reclen; - bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); + memmove(dirp, &proto, (size_t)entrysize); if (reply("FIX") == 1) ret |= ALTERED; } @@ -346,6 +371,14 @@ chk2: if (dirp->d_ino > maxino) { fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); n = reply("REMOVE"); + } else if (newinofmt && + ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) || + (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) { + fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY"); + dirp->d_ino = WINO; + dirp->d_type = DT_WHT; + if (reply("FIX") == 1) + ret |= ALTERED; } else { again: switch (statemap[dirp->d_ino]) { @@ -412,7 +445,7 @@ again: break; default: - errexit("BAD STATE %d FOR INODE I=%d", + errx(EEXIT, "BAD STATE %d FOR INODE I=%d", statemap[dirp->d_ino], dirp->d_ino); } } @@ -425,10 +458,11 @@ again: /* * 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 963c41a..89aff79 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> + #include "fsck.h" void diff --git a/sbin/fsck_ffs/pass4.c b/sbin/fsck_ffs/pass4.c index df8f722..e20f6fa 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> -#include <stdlib.h> + +#include <err.h> #include <string.h> -#include "fsck.h" -int pass4check(); +#include "fsck.h" void pass4() @@ -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 a6ed6a1..1ea122b 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> #include <stdio.h> +#include <err.h> #include <string.h> + #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 b560861..09b47c3 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 <sys/param.h> @@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93"; #include <unistd.h> #include <stdlib.h> #include <ctype.h> -#include <fstab.h> + #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 5fb5697..2d25ff6 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 <sys/param.h> #include <sys/time.h> -#include <ufs/ufs/dinode.h> -#include <ufs/ffs/fs.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/disklabel.h> #include <sys/file.h> + +#include <ufs/ufs/dinode.h> +#include <ufs/ffs/fs.h> + +#include <ctype.h> +#include <err.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> + #include "fsck.h" struct bufarea asblk; #define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) -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 d0c91fa..badb703 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 <sys/param.h> #include <sys/time.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/dir.h> #include <ufs/ffs/fs.h> @@ -45,11 +46,14 @@ static const char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #include <unistd.h> #include <stdarg.h> #include <string.h> +#include <ctype.h> +#include <err.h> + #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 @@ foundit: void getblk(bp, blk, size) register struct bufarea *bp; - daddr_t blk; + ufs_daddr_t blk; long size; { - daddr_t dblk; + ufs_daddr_t dblk; dblk = fsbtodb(&sblock, blk); if (bp->b_bno != dblk) { @@ -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 <stdarg.h> +#else +#include <varargs.h> +#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 { - + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif pfatal("INTERNAL INCONSISTENCY:"); - errexit(fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + exit(EEXIT); } -#endif |