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.
This commit is contained in:
Peter Wemm 1997-03-11 12:20:21 +00:00
parent 82b49328cd
commit 780a5c1ec1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=23675
46 changed files with 1890 additions and 1440 deletions

View File

@ -1,9 +1,10 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93 # @(#)Makefile 8.2 (Berkeley) 4/27/95
PROG= fsck PROG= fsck
MAN8= fsck.8 MAN8= fsck.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ 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 pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
CFLAGS+=-W
.PATH: ${.CURDIR}/../../sys/ufs/ffs .PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -32,17 +32,20 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
char *lfname = "lost+found"; char *lfname = "lost+found";
@ -57,15 +60,14 @@ struct odirtemplate odirhead = {
0, DIRBLKSIZ - 12, 2, ".." 0, DIRBLKSIZ - 12, 2, ".."
}; };
static int chgino __P((struct inodesc *));
static int chgino __P((struct inodesc *idesc)); static int dircheck __P((struct inodesc *, struct direct *));
static int dircheck __P((struct inodesc *idesc, struct direct *dp)); static int expanddir __P((struct dinode *dp, char *name));
static int expanddir __P((struct dinode *dp, char *name)); static void freedir __P((ino_t ino, ino_t parent));
static void freedir __P((ino_t ino, ino_t parent)); static struct direct *fsck_readdir __P((struct inodesc *));
static struct direct * fsck_readdir __P((struct inodesc *idesc)); static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
static struct bufarea * getdirblk __P((daddr_t blkno, long size)); static int lftempname __P((char *bufp, ino_t ino));
static int lftempname __P((char *bufp, ino_t ino)); static int mkentry __P((struct inodesc *));
static int mkentry __P((struct inodesc *idesc));
/* /*
* Propagate connected state through the tree. * Propagate connected state through the tree.
@ -107,7 +109,7 @@ dirscan(idesc)
char dbuf[DIRBLKSIZ]; char dbuf[DIRBLKSIZ];
if (idesc->id_type != DATA) 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 && if (idesc->id_entryno == 0 &&
(idesc->id_filesize & (DIRBLKSIZ - 1)) != 0) (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ); idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
@ -119,7 +121,7 @@ dirscan(idesc)
idesc->id_loc = 0; idesc->id_loc = 0;
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
dsize = dp->d_reclen; dsize = dp->d_reclen;
bcopy((char *)dp, dbuf, (size_t)dsize); memmove(dbuf, dp, (size_t)dsize);
# if (BYTE_ORDER == LITTLE_ENDIAN) # if (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
struct direct *tdp = (struct direct *)dbuf; struct direct *tdp = (struct direct *)dbuf;
@ -144,7 +146,7 @@ dirscan(idesc)
} }
# endif # endif
bp = getdirblk(idesc->id_blkno, blksiz); 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); (size_t)dsize);
dirty(bp); dirty(bp);
sbdirty(); sbdirty();
@ -158,7 +160,7 @@ dirscan(idesc)
/* /*
* get next entry in a directory. * get next entry in a directory.
*/ */
struct direct * static struct direct *
fsck_readdir(idesc) fsck_readdir(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
@ -173,6 +175,8 @@ fsck_readdir(idesc)
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (dircheck(idesc, dp)) if (dircheck(idesc, dp))
goto dpok; goto dpok;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
@ -202,6 +206,8 @@ fsck_readdir(idesc)
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
idesc->id_loc += size; idesc->id_loc += size;
idesc->id_filesize -= size; idesc->id_filesize -= size;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + dploc); dp = (struct direct *)(bp->b_un.b_buf + dploc);
@ -216,7 +222,7 @@ fsck_readdir(idesc)
* Verify that a directory entry is valid. * Verify that a directory entry is valid.
* This is a superset of the checks made in the kernel. * This is a superset of the checks made in the kernel.
*/ */
int static int
dircheck(idesc, dp) dircheck(idesc, dp)
struct inodesc *idesc; struct inodesc *idesc;
register struct direct *dp; register struct direct *dp;
@ -226,8 +232,15 @@ dircheck(idesc, dp)
u_char namlen, type; u_char namlen, type;
int spaceleft; int spaceleft;
size = DIRSIZ(!newinofmt, dp);
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 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 (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
type = dp->d_namlen; type = dp->d_namlen;
@ -240,23 +253,17 @@ dircheck(idesc, dp)
namlen = dp->d_namlen; namlen = dp->d_namlen;
type = dp->d_type; type = dp->d_type;
# endif # endif
if (dp->d_ino < maxino && if (dp->d_reclen < size ||
dp->d_reclen != 0 && idesc->id_filesize < size ||
dp->d_reclen <= spaceleft && namlen > MAXNAMLEN ||
(dp->d_reclen & 0x3) == 0 && type > 15)
dp->d_reclen >= size && return (0);
idesc->id_filesize >= size && for (cp = dp->d_name, size = 0; size < namlen; size++)
namlen <= MAXNAMLEN && if (*cp == '\0' || (*cp++ == '/'))
type <= 15) { return (0);
if (dp->d_ino == 0) if (*cp != '\0')
return (1); return (0);
for (cp = dp->d_name, size = 0; size < namlen; size++) return (1);
if (*cp == 0 || (*cp++ == '/'))
return (0);
if (*cp == 0)
return (1);
}
return (0);
} }
void void
@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg)
void void
adjust(idesc, lcnt) adjust(idesc, lcnt)
register struct inodesc *idesc; register struct inodesc *idesc;
short lcnt; int lcnt;
{ {
register struct dinode *dp; register struct dinode *dp;
@ -323,7 +330,7 @@ adjust(idesc, lcnt)
} }
} }
int static int
mkentry(idesc) mkentry(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -343,30 +350,38 @@ mkentry(idesc)
dirp->d_reclen = oldlen; dirp->d_reclen = oldlen;
dirp = (struct direct *)(((char *)dirp) + oldlen); dirp = (struct direct *)(((char *)dirp) + oldlen);
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ 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; 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); return (ALTERED|STOP);
} }
int static int
chgino(idesc) chgino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
register struct direct *dirp = idesc->id_dirp; 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); return (KEEPON);
dirp->d_ino = idesc->id_parent; dirp->d_ino = idesc->id_parent;
if (newinofmt) if (newinofmt)
@ -387,7 +402,7 @@ linkup(orphan, parentdir)
struct inodesc idesc; struct inodesc idesc;
char tempname[BUFSIZ]; char tempname[BUFSIZ];
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
dp = ginode(orphan); dp = ginode(orphan);
lostdir = (dp->di_mode & IFMT) == IFDIR; lostdir = (dp->di_mode & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
@ -501,7 +516,7 @@ changeino(dir, name, newnum)
{ {
struct inodesc idesc; struct inodesc idesc;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = chgino; idesc.id_func = chgino;
idesc.id_number = dir; idesc.id_number = dir;
@ -526,7 +541,7 @@ makeentry(parent, ino, name)
if (parent < ROOTINO || parent >= maxino || if (parent < ROOTINO || parent >= maxino ||
ino < ROOTINO || ino >= maxino) ino < ROOTINO || ino >= maxino)
return (0); return (0);
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = mkentry; idesc.id_func = mkentry;
idesc.id_number = parent; idesc.id_number = parent;
@ -550,12 +565,12 @@ makeentry(parent, ino, name)
/* /*
* Attempt to expand the size of a directory * Attempt to expand the size of a directory
*/ */
int static int
expanddir(dp, name) expanddir(dp, name)
register struct dinode *dp; register struct dinode *dp;
char *name; char *name;
{ {
daddr_t lastbn, newblk; ufs_daddr_t lastbn, newblk;
register struct bufarea *bp; register struct bufarea *bp;
char *cp, firstblk[DIRBLKSIZ]; char *cp, firstblk[DIRBLKSIZ];
@ -572,21 +587,21 @@ expanddir(dp, name)
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ); memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
bp = getdirblk(newblk, sblock.fs_bsize); bp = getdirblk(newblk, sblock.fs_bsize);
if (bp->b_errs) if (bp->b_errs)
goto bad; 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp < &bp->b_un.b_buf[sblock.fs_bsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
bp = getdirblk(dp->di_db[lastbn + 1], bp = getdirblk(dp->di_db[lastbn + 1],
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; 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); pwarn("NO SPACE LEFT IN %s", name);
if (preen) if (preen)
printf(" (EXPANDED)\n"); printf(" (EXPANDED)\n");
@ -631,11 +646,11 @@ allocdir(parent, request, mode)
freeino(ino); freeino(ino);
return (0); 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_fsize]; cp < &bp->b_un.b_buf[sblock.fs_fsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
dp->di_nlink = 2; dp->di_nlink = 2;
inodirty(); inodirty();
@ -680,7 +695,7 @@ freedir(ino, parent)
/* /*
* generate a temporary name for the lost+found directory. * generate a temporary name for the lost+found directory.
*/ */
int static int
lftempname(bufp, ino) lftempname(bufp, ino)
char *bufp; char *bufp;
ino_t ino; ino_t ino;
@ -707,9 +722,9 @@ lftempname(bufp, ino)
* Get a directory block. * Get a directory block.
* Insure that it is held until another is requested. * Insure that it is held until another is requested.
*/ */
struct bufarea * static struct bufarea *
getdirblk(blkno, size) getdirblk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 .\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id$ .|' $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 .Dt FSCK 8
.Os BSD 4 .Os BSD 4
.Sh NAME .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. to be the partition designator.
.Pp .Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that 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 .Fl f
option is specified, the filesystems option is specified, the filesystems
will be checked regardless of the state of their clean flag. 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. Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised. Note that the level of a filesystem can only be raised.
.Bl -tag -width indent .Bl -tag -width indent
There are currently three levels defined: There are currently four levels defined:
.It 0 .It 0
The filesystem is in the old (static table) format. The filesystem is in the old (static table) format.
.It 1 .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, The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode, short symbolic links are stored in the inode,
and directories have an added field showing the file type. 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 .El
.Pp .Pp
In interactive mode, In interactive mode,

View File

@ -30,9 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 MAXDUP 10 /* limit on dup blks (per inode) */
#define MAXBAD 10 /* limit on bad blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
@ -53,20 +57,20 @@
* buffer cache structure. * buffer cache structure.
*/ */
struct bufarea { struct bufarea {
struct bufarea *b_next; /* free list queue */ struct bufarea *b_next; /* free list queue */
struct bufarea *b_prev; /* free list queue */ struct bufarea *b_prev; /* free list queue */
daddr_t b_bno; ufs_daddr_t b_bno;
int b_size; int b_size;
int b_errs; int b_errs;
int b_flags; int b_flags;
union { union {
char *b_buf; /* buffer space */ char *b_buf; /* buffer space */
daddr_t *b_indir; /* indirect block */ ufs_daddr_t *b_indir; /* indirect block */
struct fs *b_fs; /* super block */ struct fs *b_fs; /* super block */
struct cg *b_cg; /* cylinder group */ struct cg *b_cg; /* cylinder group */
struct dinode *b_dinode; /* inode block */ struct dinode *b_dinode; /* inode block */
} b_un; } b_un;
char b_dirty; char b_dirty;
}; };
#define B_INUSE 1 #define B_INUSE 1
@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */
struct bufarea cgblk; /* cylinder group blocks */ struct bufarea cgblk; /* cylinder group blocks */
struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */ struct bufarea *pbp; /* current inode block */
struct bufarea *getdatablk();
#define dirty(bp) (bp)->b_dirty = 1 #define dirty(bp) (bp)->b_dirty = 1
#define initbarea(bp) \ #define initbarea(bp) \
(bp)->b_dirty = 0; \ (bp)->b_dirty = 0; \
(bp)->b_bno = (daddr_t)-1; \ (bp)->b_bno = (ufs_daddr_t)-1; \
(bp)->b_flags = 0; (bp)->b_flags = 0;
#define sbdirty() sblk.b_dirty = 1 #define sbdirty() sblk.b_dirty = 1
@ -97,7 +100,7 @@ struct inodesc {
int (*id_func)(); /* function to be applied to blocks of inode */ int (*id_func)(); /* function to be applied to blocks of inode */
ino_t id_number; /* inode number described */ ino_t id_number; /* inode number described */
ino_t id_parent; /* for DATA nodes, their parent */ 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 */ int id_numfrags; /* number of frags contained in block */
quad_t id_filesize; /* for DATA nodes, the size of the directory */ quad_t id_filesize; /* for DATA nodes, the size of the directory */
int id_loc; /* for DATA nodes, current location in dir */ int id_loc; /* for DATA nodes, current location in dir */
@ -133,7 +136,7 @@ struct inodesc {
*/ */
struct dups { struct dups {
struct dups *next; struct dups *next;
daddr_t dup; ufs_daddr_t dup;
}; };
struct dups *duplist; /* head of dup list */ struct dups *duplist; /* head of dup list */
struct dups *muldup; /* end of unique duplicate dup block numbers */ struct dups *muldup; /* end of unique duplicate dup block numbers */
@ -157,7 +160,7 @@ struct inoinfo {
ino_t i_dotdot; /* inode number of `..' */ ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */ size_t i_isize; /* size of inode */
u_int i_numblks; /* size of block array in bytes */ 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; } **inphead, **inpsort;
long numdirs, listmax, inplast; long numdirs, listmax, inplast;
@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */
int returntosingle; /* return to single user mode */ int returntosingle; /* return to single user mode */
int rerun; /* rerun fsck. Only used in non-preen 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 */ char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in file system */ ino_t maxino; /* number of inodes in file system */
ino_t lastino; /* last inode in use */ ino_t lastino; /* last inode in use */
char *statemap; /* ptr to inode state table */ 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 */ short *lncntp; /* ptr to link count table */
ino_t lfdir; /* lost & found directory inode number */ ino_t lfdir; /* lost & found directory inode number */
char *lfname; /* lost & found directory name */ char *lfname; /* lost & found directory name */
int lfmode; /* lost & found directory creation mode */ int lfmode; /* lost & found directory creation mode */
daddr_t n_blks; /* number of blocks in use */ ufs_daddr_t n_blks; /* number of blocks in use */
daddr_t n_files; /* number of files in use */ ufs_daddr_t n_files; /* number of files in use */
#define clearinode(dp) (*(dp) = zino) #define clearinode(dp) (*(dp) = zino)
struct dinode zino; struct dinode zino;
@ -210,84 +213,69 @@ struct dinode zino;
#define ALTERED 0x08 #define ALTERED 0x08
#define FOUND 0x10 #define FOUND 0x10
/* dir.c */ #define EEXIT 8 /* Standard error exit. */
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 */ struct fstab;
void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt));
/* inode.c */ void adjust __P((struct inodesc *, int lcnt));
ino_t allocino __P((ino_t request, int type)); ufs_daddr_t allocblk __P((long frags));
void blkerror __P((ino_t ino, char *type, daddr_t blk)); ino_t allocdir __P((ino_t parent, ino_t request, int mode));
void cacheino __P((struct dinode *dp, ino_t inumber)); ino_t allocino __P((ino_t request, int type));
int chkrange __P((daddr_t blk, int cnt)); void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
int ckinode __P((struct dinode *dp, struct inodesc *idesc)); char *blockcheck __P((char *name));
void clri __P((struct inodesc *idesc, char *type, int flag)); int bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
int findino __P((struct inodesc *idesc)); void bufinit __P((void));
void freeino __P((ino_t ino)); void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
void freeinodebuf __P((void)); void cacheino __P((struct dinode *dp, ino_t inumber));
struct dinode * ginode __P((ino_t inumber)); void catch __P((int));
struct inoinfo * getinoinfo __P((ino_t inumber)); void catchquit __P((int));
struct dinode * getnextinode __P((ino_t inumber)); int changeino __P((ino_t dir, char *name, ino_t newnum));
void inodirty __P((void)); int checkfstab __P((int preen, int maxrun,
void inocleanup __P((void)); int (*docheck)(struct fstab *),
void pinode __P((ino_t ino)); int (*chkit)(char *, char *, long, int)));
void resetinodebuf __P((void)); int chkrange __P((ufs_daddr_t blk, int cnt));
int findname __P((struct inodesc *idesc)); void ckfini __P((int markclean));
int ckinode __P((struct dinode *dp, struct inodesc *));
/* pass1.c */ void clri __P((struct inodesc *, char *type, int flag));
void pass1 __P((void)); void direrror __P((ino_t ino, char *errmesg));
int pass1check __P((struct inodesc *idesc)); int dirscan __P((struct inodesc *));
int dofix __P((struct inodesc *, char *msg));
/* pass1b.c */ void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass1b __P((void)); void ffs_fragacct __P((struct fs *, int, int32_t [], int));
int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
/* pass2.c */ void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass2 __P((void)); void fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
int findino __P((struct inodesc *));
/* pass3.c */ int findname __P((struct inodesc *));
void pass3 __P((void)); void flush __P((int fd, struct bufarea *bp));
void freeblk __P((ufs_daddr_t blkno, long frags));
/* pass4.c */ void freeino __P((ino_t ino));
void pass4 __P((void)); void freeinodebuf __P((void));
int pass4check __P((struct inodesc *idesc)); int ftypeok __P((struct dinode *dp));
void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
/* pass5.c */ struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
void pass5 __P((void)); struct inoinfo *getinoinfo __P((ino_t inumber));
struct dinode *getnextinode __P((ino_t inumber));
/* preen.c */ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
char *blockcheck __P((char *name)); struct dinode *ginode __P((ino_t inumber));
int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); void inocleanup __P((void));
void inodirty __P((void));
/* setup.c */ int linkup __P((ino_t orphan, ino_t parentdir));
int setup __P((char *dev)); int makeentry __P((ino_t parent, ino_t ino, char *name));
void panic __P((const char *fmt, ...));
/* utilities.c */ void pass1 __P((void));
int allocblk __P((long frags)); void pass1b __P((void));
int bread __P((int fd, char *buf, daddr_t blk, long size)); int pass1check __P((struct inodesc *));
void bufinit __P((void)); void pass2 __P((void));
void bwrite __P((int fd, char *buf, daddr_t blk, long size)); void pass3 __P((void));
void catch __P((int)); void pass4 __P((void));
void catchquit __P((int)); int pass4check __P((struct inodesc *));
void ckfini __P((void)); void pass5 __P((void));
int dofix __P((struct inodesc *idesc, char *msg)); void pfatal __P((const char *fmt, ...));
void errexit __P((const char *s1, ...)) __dead2; void pinode __P((ino_t ino));
void flush __P((int fd, struct bufarea *bp)); void propagate __P((void));
void freeblk __P((daddr_t blkno, long frags)); void pwarn __P((const char *fmt, ...));
int ftypeok __P((struct dinode *dp)); int reply __P((char *question));
void getblk __P((struct bufarea *bp, daddr_t blk, long size)); void resetinodebuf __P((void));
struct bufarea * getdatablk __P((daddr_t blkno, long size)); int setup __P((char *dev));
void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); void voidquit __P((int));
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));

View File

@ -32,32 +32,35 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <err.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static ino_t startinum; 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 int
ckinode(dp, idesc) ckinode(dp, idesc)
struct dinode *dp; struct dinode *dp;
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
int ret; long ret, n, ndb, offset;
long n, ndb, offset;
struct dinode dino; struct dinode dino;
quad_t remsize, sizepb; quad_t remsize, sizepb;
mode_t mode; mode_t mode;
@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize)
long ilevel; long ilevel;
quad_t isize; quad_t isize;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
register daddr_t *aplim; ufs_daddr_t *aplim;
register struct bufarea *bp; struct bufarea *bp;
int i, n, (*func)(), nif; int i, n, (*func)(), nif;
quad_t sizepb; quad_t sizepb;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize)
*/ */
int int
chkrange(blk, cnt) chkrange(blk, cnt)
daddr_t blk; ufs_daddr_t blk;
int cnt; int cnt;
{ {
register int c; register int c;
@ -268,10 +271,10 @@ struct dinode *
ginode(inumber) ginode(inumber)
ino_t inumber; ino_t inumber;
{ {
daddr_t iblk; ufs_daddr_t iblk;
if (inumber < ROOTINO || inumber > maxino) 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 || if (startinum == 0 ||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) { inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
iblk = ino_to_fsba(&sblock, inumber); iblk = ino_to_fsba(&sblock, inumber);
@ -296,11 +299,11 @@ getnextinode(inumber)
ino_t inumber; ino_t inumber;
{ {
long size; long size;
daddr_t dblk; ufs_daddr_t dblk;
static struct dinode *dp; static struct dinode *dp;
if (inumber != nextino++ || inumber > maxino) 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) { if (inumber >= lastinum) {
readcnt++; readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
@ -338,7 +341,7 @@ resetinodebuf()
} }
if (inodebuf == NULL && if (inodebuf == NULL &&
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == 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) while (nextino < ROOTINO)
(void)getnextinode(nextino); (void)getnextinode(nextino);
} }
@ -372,7 +375,7 @@ cacheino(dp, inumber)
if (blks > NDADDR) if (blks > NDADDR)
blks = NDADDR + NIADDR; blks = NDADDR + NIADDR;
inp = (struct inoinfo *) inp = (struct inoinfo *)
malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t)); malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
if (inp == NULL) if (inp == NULL)
return; return;
inpp = &inphead[inumber % numdirs]; inpp = &inphead[inumber % numdirs];
@ -385,15 +388,14 @@ cacheino(dp, inumber)
inp->i_dotdot = (ino_t)0; inp->i_dotdot = (ino_t)0;
inp->i_number = inumber; inp->i_number = inumber;
inp->i_isize = dp->di_size; inp->i_isize = dp->di_size;
inp->i_numblks = blks * sizeof(daddr_t); inp->i_numblks = blks * sizeof(ufs_daddr_t);
bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0], memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
if (inplast == listmax) { if (inplast == listmax) {
listmax += 100; listmax += 100;
inpsort = (struct inoinfo **)realloc((char *)inpsort, inpsort = (struct inoinfo **)realloc((char *)inpsort,
(unsigned)listmax * sizeof(struct inoinfo *)); (unsigned)listmax * sizeof(struct inoinfo *));
if (inpsort == NULL) if (inpsort == NULL)
errexit("cannot increase directory list"); errx(EEXIT, "cannot increase directory list");
} }
inpsort[inplast++] = inp; inpsort[inplast++] = inp;
} }
@ -412,7 +414,7 @@ getinoinfo(inumber)
continue; continue;
return (inp); return (inp);
} }
errexit("cannot find inode %d\n", inumber); errx(EEXIT, "cannot find inode %d", inumber);
return ((struct inoinfo *)0); return ((struct inoinfo *)0);
} }
@ -472,7 +474,7 @@ findname(idesc)
if (dirp->d_ino != idesc->id_parent) if (dirp->d_ino != idesc->id_parent)
return (KEEPON); 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); return (STOP|FOUND);
} }
@ -514,7 +516,7 @@ pinode(ino)
if (preen) if (preen)
printf("%s: ", cdevname); printf("%s: ", cdevname);
printf("SIZE=%qu ", dp->di_size); 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]); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
} }
@ -522,7 +524,7 @@ void
blkerror(ino, type, blk) blkerror(ino, type, blk)
ino_t ino; ino_t ino;
char *type; char *type;
daddr_t blk; ufs_daddr_t blk;
{ {
pfatal("%ld %s I=%lu", blk, type, ino); pfatal("%ld %s I=%lu", blk, type, ino);
@ -542,7 +544,7 @@ blkerror(ino, type, blk)
return; return;
default: default:
errexit("BAD STATE %d TO BLKERR", statemap[ino]); errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@ -585,7 +587,7 @@ allocino(request, type)
return (0); return (0);
} }
dp->di_mode = type; 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_mtime = dp->di_ctime = dp->di_atime;
dp->di_size = sblock.fs_fsize; dp->di_size = sblock.fs_fsize;
dp->di_blocks = btodb(sblock.fs_fsize); dp->di_blocks = btodb(sblock.fs_fsize);
@ -606,7 +608,7 @@ freeino(ino)
struct inodesc idesc; struct inodesc idesc;
struct dinode *dp; struct dinode *dp;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
idesc.id_number = ino; idesc.id_number = ino;

View File

@ -38,25 +38,35 @@ static const char copyright[] =
#endif /* not lint */ #endif /* not lint */
#ifndef 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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <ctype.h>
#include <err.h>
#include <fstab.h> #include <fstab.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "fsck.h" #include "fsck.h"
static int argtoi __P((int flag, char *req, char *str, int base));
static int docheck __P((struct fstab *fsp)); int returntosingle;
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
int child)); 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 int
main(argc, argv) main(argc, argv)
@ -99,7 +109,7 @@ main(argc, argv)
case 'm': case 'm':
lfmode = argtoi('m', "mode", optarg, 8); lfmode = argtoi('m', "mode", optarg, 8);
if (lfmode &~ 07777) 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); printf("** lost+found creation mode %o\n", lfmode);
break; break;
@ -116,7 +126,7 @@ main(argc, argv)
break; break;
default: default:
errexit("%c option?\n", ch); errx(EEXIT, "%c option?", ch);
} }
} }
argc -= optind; argc -= optind;
@ -136,7 +146,7 @@ main(argc, argv)
exit(ret); exit(ret);
} }
int static int
argtoi(flag, req, str, base) argtoi(flag, req, str, base)
int flag; int flag;
char *req, *str; char *req, *str;
@ -147,14 +157,14 @@ argtoi(flag, req, str, base)
ret = (int)strtol(str, &cp, base); ret = (int)strtol(str, &cp, base);
if (cp == str || *cp) if (cp == str || *cp)
errexit("-%c flag requires a %s\n", flag, req); errx(EEXIT, "-%c flag requires a %s", flag, req);
return (ret); return (ret);
} }
/* /*
* Determine whether a filesystem should be checked. * Determine whether a filesystem should be checked.
*/ */
int static int
docheck(fsp) docheck(fsp)
register struct fstab *fsp; register struct fstab *fsp;
{ {
@ -171,25 +181,28 @@ docheck(fsp)
* Check the specified filesystem. * Check the specified filesystem.
*/ */
/* ARGSUSED */ /* ARGSUSED */
int static int
checkfilesys(filesys, mntpt, auxdata, child) checkfilesys(filesys, mntpt, auxdata, child)
char *filesys, *mntpt; char *filesys, *mntpt;
long auxdata; long auxdata;
int child; int child;
{ {
daddr_t n_ffree, n_bfree; ufs_daddr_t n_ffree, n_bfree;
struct dups *dp; struct dups *dp;
struct zlncnt *zlnp; struct zlncnt *zlnp;
int cylno; int cylno, flags;
if (preen && child) if (preen && child)
(void)signal(SIGQUIT, voidquit); (void)signal(SIGQUIT, voidquit);
cdevname = filesys; cdevname = filesys;
if (debug && preen) if (debug && preen)
pwarn("starting\n"); pwarn("starting\n");
if (setup(filesys) == 0) { switch (setup(filesys)) {
case 0:
if (preen) if (preen)
pfatal("CAN'T CHECK FILE SYSTEM."); pfatal("CAN'T CHECK FILE SYSTEM.");
/* fall through */
case -1:
return (0); return (0);
} }
@ -302,7 +315,19 @@ checkfilesys(filesys, mntpt, auxdata, child)
bwrite(fswritefd, (char *)&sblock, bwrite(fswritefd, (char *)&sblock,
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); 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(blockmap);
free(statemap); free(statemap);
free((char *)lncntp); free((char *)lncntp);
@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (rerun) if (rerun)
printf("\n***** PLEASE RERUN FSCK *****\n"); printf("\n***** PLEASE RERUN FSCK *****\n");
if (hotroot) { if (hotroot) {
struct statfs stfs_buf; struct ufs_args args;
int ret;
/* /*
* We modified the root. Do a mount update on * We modified the root. Do a mount update on
* it, unless it is read-write, so we can continue. * it, unless it is read-write, so we can continue.
*/ */
if (statfs("/", &stfs_buf) == 0) { if (flags & MNT_RDONLY) {
long flags = stfs_buf.f_flags; args.fspec = 0;
struct ufs_args args; args.export.ex_flags = 0;
int ret; args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
if (flags & MNT_RDONLY) { ret = mount("ufs", "/", flags, &args);
args.fspec = 0; if (ret == 0)
args.export.ex_flags = 0; return (0);
args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
ret = mount(MOUNT_UFS, "/", flags, &args);
if (ret == 0)
return(0);
}
} }
if (!preen) if (!preen)
printf("\n***** REBOOT NOW *****\n"); printf("\n***** REBOOT NOW *****\n");

View File

@ -32,23 +32,27 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static daddr_t badblk; static ufs_daddr_t badblk;
static daddr_t dupblk; 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 void
pass1() pass1()
@ -73,7 +77,7 @@ pass1()
/* /*
* Find all allocated blocks. * Find all allocated blocks.
*/ */
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1check; idesc.id_func = pass1check;
inumber = 0; inumber = 0;
@ -89,7 +93,7 @@ pass1()
freeinodebuf(); freeinodebuf();
} }
void static void
checkinode(inumber, idesc) checkinode(inumber, idesc)
ino_t inumber; ino_t inumber;
register struct inodesc *idesc; register struct inodesc *idesc;
@ -103,10 +107,10 @@ checkinode(inumber, idesc)
dp = getnextinode(inumber); dp = getnextinode(inumber);
mode = dp->di_mode & IFMT; mode = dp->di_mode & IFMT;
if (mode == 0) { if (mode == 0) {
if (bcmp((char *)dp->di_db, (char *)zino.di_db, if (memcmp(dp->di_db, zino.di_db,
NDADDR * sizeof(daddr_t)) || NDADDR * sizeof(ufs_daddr_t)) ||
bcmp((char *)dp->di_ib, (char *)zino.di_ib, memcmp(dp->di_ib, zino.di_ib,
NIADDR * sizeof(daddr_t)) || NIADDR * sizeof(ufs_daddr_t)) ||
dp->di_mode || dp->di_size) { dp->di_mode || dp->di_size) {
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
if (reply("CLEAR") == 1) { if (reply("CLEAR") == 1) {
@ -120,7 +124,8 @@ checkinode(inumber, idesc)
} }
lastino = inumber; lastino = inumber;
if (/* dp->di_size < 0 || */ 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) if (debug)
printf("bad size %qu:", dp->di_size); printf("bad size %qu:", dp->di_size);
goto unknown; goto unknown;
@ -148,15 +153,14 @@ checkinode(inumber, idesc)
if (bread(fsreadfd, symbuf, if (bread(fsreadfd, symbuf,
fsbtodb(&sblock, dp->di_db[0]), fsbtodb(&sblock, dp->di_db[0]),
(long)secsize) != 0) (long)secsize) != 0)
errexit("cannot read symlink"); errx(EEXIT, "cannot read symlink");
if (debug) { if (debug) {
symbuf[dp->di_size] = 0; symbuf[dp->di_size] = 0;
printf("convert symlink %ld(%s) of size %ld\n", printf("convert symlink %ld(%s) of size %ld\n",
inumber, symbuf, (long)dp->di_size); inumber, symbuf, (long)dp->di_size);
} }
dp = ginode(inumber); dp = ginode(inumber);
bcopy(symbuf, (caddr_t)dp->di_shortlink, memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
(long)dp->di_size);
dp->di_blocks = 0; dp->di_blocks = 0;
inodirty(); inodirty();
} }
@ -165,7 +169,7 @@ checkinode(inumber, idesc)
* will detect any garbage after symlink string. * will detect any garbage after symlink string.
*/ */
if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { 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) { if (ndb > NDADDR) {
j = ndb - NDADDR; j = ndb - NDADDR;
for (ndb = 1; j > 1; j--) for (ndb = 1; j > 1; j--)
@ -198,7 +202,7 @@ checkinode(inumber, idesc)
if (zlnp == NULL) { if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW"); pfatal("LINK COUNT TABLE OVERFLOW");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
} else { } else {
zlnp->zlncnt = inumber; zlnp->zlncnt = inumber;
zlnp->next = zlnhead; zlnp->next = zlnhead;
@ -256,7 +260,7 @@ pass1check(idesc)
{ {
int res = KEEPON; int res = KEEPON;
int anyout, nfrags; int anyout, nfrags;
daddr_t blkno = idesc->id_blkno; ufs_daddr_t blkno = idesc->id_blkno;
register struct dups *dlp; register struct dups *dlp;
struct dups *new; struct dups *new;
@ -268,7 +272,7 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
} }
@ -286,14 +290,14 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new = (struct dups *)malloc(sizeof(struct dups)); new = (struct dups *)malloc(sizeof(struct dups));
if (new == NULL) { if (new == NULL) {
pfatal("DUP TABLE OVERFLOW."); pfatal("DUP TABLE OVERFLOW.");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new->dup = blkno; new->dup = blkno;

View File

@ -32,18 +32,21 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
int pass1bcheck();
static struct dups *duphead; static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void void
pass1b() pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc; struct inodesc idesc;
ino_t inumber; ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1bcheck; idesc.id_func = pass1bcheck;
duphead = duplist; duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
} }
} }
int static int
pass1bcheck(idesc) pass1bcheck(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) if (chkrange(blkno, 1))

View File

@ -32,22 +32,26 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
#define MINDIRSIZE (sizeof (struct dirtemplate)) #define MINDIRSIZE (sizeof (struct dirtemplate))
int pass2check(), blksort(); static int blksort __P((const void *, const void *));
static int pass2check __P((struct inodesc *));
void void
pass2() pass2()
@ -64,9 +68,9 @@ pass2()
case USTATE: case USTATE:
pfatal("ROOT INODE UNALLOCATED"); pfatal("ROOT INODE UNALLOCATED");
if (reply("ALLOCATE") == 0) if (reply("ALLOCATE") == 0)
errexit(""); exit(EEXIT);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
case DCLEAR: case DCLEAR:
@ -74,11 +78,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
break; break;
case FSTATE: case FSTATE:
@ -87,11 +91,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("FIX") == 0) if (reply("FIX") == 0)
errexit(""); exit(EEXIT);
dp = ginode(ROOTINO); dp = ginode(ROOTINO);
dp->di_mode &= ~IFMT; dp->di_mode &= ~IFMT;
dp->di_mode |= IFDIR; dp->di_mode |= IFDIR;
@ -102,9 +106,13 @@ pass2()
break; break;
default: default:
errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
} }
statemap[ROOTINO] = DFOUND; statemap[ROOTINO] = DFOUND;
if (newinofmt) {
statemap[WINO] = FSTATE;
typemap[WINO] = DT_WHT;
}
/* /*
* Sort the directory list into disk block order. * Sort the directory list into disk block order.
*/ */
@ -112,7 +120,7 @@ pass2()
/* /*
* Check the integrity of each directory. * Check the integrity of each directory.
*/ */
bzero((char *)&curino, sizeof(struct inodesc)); memset(&curino, 0, sizeof(struct inodesc));
curino.id_type = DATA; curino.id_type = DATA;
curino.id_func = pass2check; curino.id_func = pass2check;
dp = &dino; dp = &dino;
@ -144,11 +152,10 @@ pass2()
dp = &dino; dp = &dino;
} }
} }
bzero((char *)&dino, sizeof(struct dinode)); memset(&dino, 0, sizeof(struct dinode));
dino.di_mode = IFDIR; dino.di_mode = IFDIR;
dp->di_size = inp->i_isize; dp->di_size = inp->i_isize;
bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0], memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
curino.id_number = inp->i_number; curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent; curino.id_parent = inp->i_parent;
(void)ckinode(dp, &curino); (void)ckinode(dp, &curino);
@ -191,7 +198,7 @@ pass2()
propagate(); propagate();
} }
int static int
pass2check(idesc) pass2check(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -239,6 +246,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 1; proto.d_namlen = 1;
(void)strcpy(proto.d_name, "."); (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); entrysize = DIRSIZ(0, &proto);
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
@ -247,17 +263,17 @@ pass2check(idesc)
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp->d_reclen < 2 * entrysize) { } else if (dirp->d_reclen < 2 * entrysize) {
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} else { } else {
n = dirp->d_reclen - entrysize; n = dirp->d_reclen - entrysize;
proto.d_reclen = entrysize; proto.d_reclen = entrysize;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + entrysize); dirp = (struct direct *)((char *)(dirp) + entrysize);
bzero((char *)dirp, (size_t)n); memset(dirp, 0, (size_t)n);
dirp->d_reclen = n; dirp->d_reclen = n;
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
@ -273,6 +289,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 2; proto.d_namlen = 2;
(void)strcpy(proto.d_name, ".."); (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); entrysize = DIRSIZ(0, &proto);
if (idesc->id_entryno == 0) { if (idesc->id_entryno == 0) {
n = DIRSIZ(0, dirp); n = DIRSIZ(0, dirp);
@ -283,7 +308,7 @@ pass2check(idesc)
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + n); 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; dirp->d_reclen = proto.d_reclen;
} }
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
@ -312,7 +337,7 @@ pass2check(idesc)
inp->i_dotdot = inp->i_parent; inp->i_dotdot = inp->i_parent;
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
@ -346,6 +371,14 @@ pass2check(idesc)
if (dirp->d_ino > maxino) { if (dirp->d_ino > maxino) {
fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
n = reply("REMOVE"); 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 { } else {
again: again:
switch (statemap[dirp->d_ino]) { switch (statemap[dirp->d_ino]) {
@ -412,7 +445,7 @@ pass2check(idesc)
break; break;
default: 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); statemap[dirp->d_ino], dirp->d_ino);
} }
} }
@ -425,10 +458,11 @@ pass2check(idesc)
/* /*
* Routine to sort disk blocks. * Routine to sort disk blocks.
*/ */
int static int
blksort(inpp1, inpp2) blksort(arg1, arg2)
struct inoinfo **inpp1, **inpp2; 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]);
} }

View File

@ -32,13 +32,15 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include "fsck.h" #include "fsck.h"
void void

View File

@ -32,18 +32,19 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdlib.h>
#include <string.h>
#include "fsck.h"
int pass4check(); #include <err.h>
#include <string.h>
#include "fsck.h"
void void
pass4() pass4()
@ -54,7 +55,7 @@ pass4()
struct inodesc idesc; struct inodesc idesc;
int n; int n;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
for (inumber = ROOTINO; inumber <= lastino; inumber++) { for (inumber = ROOTINO; inumber <= lastino; inumber++) {
@ -98,7 +99,7 @@ pass4()
break; break;
default: default:
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[inumber], inumber); statemap[inumber], inumber);
} }
} }
@ -110,7 +111,7 @@ pass4check(idesc)
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) { if (chkrange(blkno, 1)) {

View File

@ -32,26 +32,29 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
void void
pass5() pass5()
{ {
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
register struct fs *fs = &sblock; struct fs *fs = &sblock;
register struct cg *cg = &cgrp; struct cg *cg = &cgrp;
daddr_t dbase, dmax; ufs_daddr_t dbase, dmax;
register daddr_t d; ufs_daddr_t d;
register long i, j; long i, j;
struct csum *cs; struct csum *cs;
struct csum cstotal; struct csum cstotal;
struct inodesc idesc[3]; struct inodesc idesc[3];
@ -59,9 +62,10 @@ pass5()
register struct cg *newcg = (struct cg *)buf; register struct cg *newcg = (struct cg *)buf;
struct ocg *ocg = (struct ocg *)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; newcg->cg_niblk = fs->fs_ipg;
if (cvtlevel > 3) { if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen) if (preen)
pwarn("DELETING CLUSTERING MAPS\n"); pwarn("DELETING CLUSTERING MAPS\n");
@ -103,8 +107,9 @@ pass5()
switch ((int)fs->fs_postblformat) { switch ((int)fs->fs_postblformat) {
case FS_42POSTBLFMT: case FS_42POSTBLFMT:
basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); basesize = (char *)(&ocg->cg_btot[0]) -
sumsize = &ocg->cg_iused[0] - (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)] - mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
(u_char *)&ocg->cg_iused[0]; (u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -114,7 +119,7 @@ pass5()
case FS_DYNAMICPOSTBLFMT: case FS_DYNAMICPOSTBLFMT:
newcg->cg_btotoff = 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_boff =
newcg->cg_btotoff + fs->fs_cpg * sizeof(long); newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
newcg->cg_iusedoff = newcg->cg_boff + newcg->cg_iusedoff = newcg->cg_boff +
@ -136,22 +141,24 @@ pass5()
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
} }
newcg->cg_magic = CG_MAGIC; 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; sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
break; break;
default: default:
errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", sumsize = 0; /* keep lint happy */
errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
fs->fs_postblformat); fs->fs_postblformat);
} }
bzero((char *)&idesc[0], sizeof idesc); memset(&idesc[0], 0, sizeof idesc);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
idesc[i].id_type = ADDR; idesc[i].id_type = ADDR;
if (doinglevel2) if (doinglevel2)
idesc[i].id_fix = FIX; 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); j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
for (i = fs->fs_size; i < j; i++) for (i = fs->fs_size; i < j; i++)
setbmap(i); setbmap(i);
@ -188,8 +195,8 @@ pass5()
newcg->cg_irotor = cg->cg_irotor; newcg->cg_irotor = cg->cg_irotor;
else else
newcg->cg_irotor = 0; newcg->cg_irotor = 0;
bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
bzero((char *)&cg_blktot(newcg)[0], memset(&cg_blktot(newcg)[0], 0,
(size_t)(sumsize + mapsize)); (size_t)(sumsize + mapsize));
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -215,7 +222,7 @@ pass5()
default: default:
if (j < ROOTINO) if (j < ROOTINO)
break; break;
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[j], j); statemap[j], j);
} }
} }
@ -249,7 +256,7 @@ pass5()
} }
} }
if (fs->fs_contigsumsize > 0) { if (fs->fs_contigsumsize > 0) {
long *sump = cg_clustersum(newcg); int32_t *sump = cg_clustersum(newcg);
u_char *mapp = cg_clustersfree(newcg); u_char *mapp = cg_clustersfree(newcg);
int map = *mapp++; int map = *mapp++;
int bit = 1; int bit = 1;
@ -282,38 +289,38 @@ pass5()
cstotal.cs_nifree += newcg->cg_cs.cs_nifree; cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
cstotal.cs_ndir += newcg->cg_cs.cs_ndir; cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
cs = &fs->fs_cs(fs, c); 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")) { 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(); sbdirty();
} }
if (doinglevel1) { if (doinglevel1) {
bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); memmove(cg, newcg, (size_t)fs->fs_cgsize);
cgdirty(); cgdirty();
continue; continue;
} }
if (bcmp(cg_inosused(newcg), if (memcmp(cg_inosused(newcg),
cg_inosused(cg), mapsize) != 0 && cg_inosused(cg), mapsize) != 0 &&
dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 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); (size_t)mapsize);
cgdirty(); cgdirty();
} }
if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || if ((memcmp(newcg, cg, basesize) != 0 ||
bcmp((char *)&cg_blktot(newcg)[0], memcmp(&cg_blktot(newcg)[0],
(char *)&cg_blktot(cg)[0], sumsize) != 0) && &cg_blktot(cg)[0], sumsize) != 0) &&
dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
bcopy((char *)newcg, (char *)cg, (size_t)basesize); memmove(cg, newcg, (size_t)basesize);
bcopy((char *)&cg_blktot(newcg)[0], memmove(&cg_blktot(cg)[0],
(char *)&cg_blktot(cg)[0], (size_t)sumsize); &cg_blktot(newcg)[0], (size_t)sumsize);
cgdirty(); cgdirty();
} }
} }
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
fs->fs_nrpos = savednrpos; 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")) { && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
fs->fs_ronly = 0; fs->fs_ronly = 0;
sbdirty(); sbdirty();
} }

View File

@ -32,7 +32,7 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93";
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <fstab.h>
#include "fsck.h" #include "fsck.h"
struct part { struct part {
@ -62,19 +62,22 @@ struct disk {
int pid; /* If != 0, pid of proc working on */ int pid; /* If != 0, pid of proc working on */
} *disks; } *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; int nrun, ndisks;
char hotroot; 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 int
checkfstab(preen, maxrun, docheck, chkit) checkfstab(preen, maxrun, docheck, chkit)
int preen, maxrun; int preen;
int (*docheck)(), (*chkit)(); int maxrun;
int (*docheck)(struct fstab *);
int (*chkit)(char *, char *, long, int);
{ {
register struct fstab *fsp; register struct fstab *fsp;
register struct disk *dk, *nextdisk; register struct disk *dk, *nextdisk;
@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit)
while ((fsp = getfsent()) != 0) { while ((fsp = getfsent()) != 0) {
if ((auxdata = (*docheck)(fsp)) == 0) if ((auxdata = (*docheck)(fsp)) == 0)
continue; continue;
if (!preen || (passno == 1 && fsp->fs_passno == 1)) { if (preen == 0 ||
name = blockcheck(fsp->fs_spec); (passno == 1 && fsp->fs_passno == 1)) {
if (name) { if ((name = blockcheck(fsp->fs_spec)) != 0) {
sumstatus = (*chkit)(name, if ((sumstatus = (*chkit)(name,
fsp->fs_file, auxdata, 0); fsp->fs_file, auxdata, 0)) != 0)
if (sumstatus)
return (sumstatus); return (sumstatus);
} else if (preen) } else if (preen)
return (8); return (8);
@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit)
return (0); return (0);
} }
struct disk * static struct disk *
finddisk(name) finddisk(name)
char *name; char *name;
{ {
@ -206,13 +208,11 @@ finddisk(name)
register char *p; register char *p;
size_t len = 0; 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)) { if (isdigit(*p)) {
len = p - name + 1; len = p - name + 1;
break; break;
} }
if (p < name)
len = strlen(name);
for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
if (strncmp(dk->name, name, len) == 0 && if (strncmp(dk->name, name, len) == 0 &&
@ -237,7 +237,7 @@ finddisk(name)
return (dk); return (dk);
} }
void static void
addpart(name, fsname, auxdata) addpart(name, fsname, auxdata)
char *name, *fsname; char *name, *fsname;
long auxdata; long auxdata;
@ -269,10 +269,10 @@ addpart(name, fsname, auxdata)
pt->auxdata = auxdata; pt->auxdata = auxdata;
} }
int static int
startdisk(dk, checkit) startdisk(dk, checkit)
register struct disk *dk; register struct disk *dk;
int (*checkit)(); int (*checkit)(char *, char *, long, int);
{ {
register struct part *pt = dk->part; register struct part *pt = dk->part;
@ -288,11 +288,11 @@ startdisk(dk, checkit)
} }
char * char *
blockcheck(name) blockcheck(origname)
char *name; char *origname;
{ {
struct stat stslash, stblock, stchar; struct stat stslash, stblock, stchar;
char *raw; char *newname, *raw;
struct fstab *fsinfo; struct fstab *fsinfo;
int retried = 0, l; int retried = 0, l;
@ -300,60 +300,63 @@ blockcheck(name)
if (stat("/", &stslash) < 0) { if (stat("/", &stslash) < 0) {
perror("/"); perror("/");
printf("Can't stat root\n"); printf("Can't stat root\n");
return (0); return (origname);
} }
newname = origname;
retry: retry:
if (stat(name, &stblock) < 0) { if (stat(newname, &stblock) < 0) {
perror(name); perror(newname);
printf("Can't stat %s\n", name); printf("Can't stat %s\n", newname);
return (0); return (origname);
} }
if ((stblock.st_mode & S_IFMT) == S_IFBLK) { if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
if (stslash.st_dev == stblock.st_rdev) if (stslash.st_dev == stblock.st_rdev)
hotroot++; hotroot++;
raw = rawname(name); raw = rawname(newname);
if (stat(raw, &stchar) < 0) { if (stat(raw, &stchar) < 0) {
perror(raw); perror(raw);
printf("Can't stat %s\n", raw); printf("Can't stat %s\n", raw);
return (name); return (origname);
} }
if ((stchar.st_mode & S_IFMT) == S_IFCHR) { if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
return (raw); return (raw);
} else { } else {
printf("%s is not a character device\n", raw); printf("%s is not a character device\n", raw);
return (name); return (origname);
} }
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
name = unrawname(name); newname = unrawname(origname);
retried++; retried++;
goto retry; goto retry;
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
l = strlen(name) - 1; l = strlen(origname) - 1;
if (l > 0 && name[l] == '/') if (l > 0 && origname[l] == '/')
/* remove trailing slash */ /* remove trailing slash */
name[l] = '\0'; origname[l] = '\0';
if(!(fsinfo=getfsfile(name))) { if(!(fsinfo=getfsfile(origname))) {
printf("Can't resolve %s to character special device", printf("Can't resolve %s to character special device",
name); origname);
return (0); return (0);
} }
name = fsinfo->fs_spec; newname = fsinfo->fs_spec;
retried++; retried++;
goto retry; goto retry;
} }
printf("Warning: Can't find blockdevice corresponding to name %s\n", /*
name); * Not a block or character device, just return name and
return (name); * let the user decide whether to use it.
*/
return (origname);
} }
char * static char *
unrawname(name) unrawname(name)
char *name; char *name;
{ {
char *dp; char *dp;
struct stat stb; struct stat stb;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (name); return (name);
if (stat(name, &stb) < 0) if (stat(name, &stb) < 0)
return (name); return (name);
@ -365,14 +368,14 @@ unrawname(name)
return (name); return (name);
} }
char * static char *
rawname(name) rawname(name)
char *name; char *name;
{ {
static char rawbuf[32]; static char rawbuf[32];
char *dp; char *dp;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (0); return (0);
*dp = 0; *dp = 0;
(void)strcpy(rawbuf, name); (void)strcpy(rawbuf, name);

View File

@ -32,41 +32,49 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#define DKTYPENAMES #define DKTYPENAMES
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/file.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 <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "fsck.h" #include "fsck.h"
struct bufarea asblk; struct bufarea asblk;
#define altsblock (*asblk.b_un.b_fs) #define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0) #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static int readsb __P((int listerr)); static void badsb __P((int listerr, char *s));
static void badsb __P((int listerr, char *s)); static int calcsb __P((char *dev, int devfd, struct fs *fs));
static int calcsb __P((char *dev, int devfd, struct fs *fs)); static struct disklabel *getdisklabel __P((char *s, int fd));
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 int
setup(dev) setup(dev)
char *dev; char *dev;
{ {
long cg, size, asked, i, j; long cg, size, asked, i, j;
long bmapsize; long skipclean, bmapsize;
struct disklabel *lp; struct disklabel *lp;
off_t sizepb; off_t sizepb;
struct stat statb; struct stat statb;
@ -74,6 +82,7 @@ setup(dev)
havesb = 0; havesb = 0;
fswritefd = -1; fswritefd = -1;
skipclean = preen;
if (stat(dev, &statb) < 0) { if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno)); printf("Can't stat %s: %s\n", dev, strerror(errno));
return (0); return (0);
@ -104,7 +113,7 @@ setup(dev)
sblk.b_un.b_buf = malloc(SBSIZE); sblk.b_un.b_buf = malloc(SBSIZE);
asblk.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) 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); lp = getdisklabel((char *)NULL, fsreadfd);
if (lp) if (lp)
dev_bsize = secsize = lp->d_secsize; dev_bsize = secsize = lp->d_secsize;
@ -114,6 +123,7 @@ setup(dev)
* Read in the superblock, looking for alternates if necessary * Read in the superblock, looking for alternates if necessary
*/ */
if (readsb(1) == 0) { if (readsb(1) == 0) {
skipclean = 0;
if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
return(0); return(0);
if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
@ -137,6 +147,10 @@ setup(dev)
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
bflag = 0; bflag = 0;
} }
if (skipclean && sblock.fs_clean) {
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
return (-1);
}
maxfsblock = sblock.fs_size; maxfsblock = sblock.fs_size;
maxino = sblock.fs_ncg * sblock.fs_ipg; maxino = sblock.fs_ncg * sblock.fs_ipg;
/* /*
@ -223,17 +237,16 @@ setup(dev)
sblock.fs_nrpos = 8; sblock.fs_nrpos = 8;
sblock.fs_postbloff = sblock.fs_postbloff =
(char *)(&sblock.fs_opostbl[0][0]) - (char *)(&sblock.fs_opostbl[0][0]) -
(char *)(&sblock.fs_link); (char *)(&sblock.fs_firstfield);
sblock.fs_rotbloff = &sblock.fs_space[0] - sblock.fs_rotbloff = &sblock.fs_space[0] -
(u_char *)(&sblock.fs_link); (u_char *)(&sblock.fs_firstfield);
sblock.fs_cgsize = sblock.fs_cgsize =
fragroundup(&sblock, CGSIZE(&sblock)); fragroundup(&sblock, CGSIZE(&sblock));
sbdirty(); sbdirty();
dirty(&asblk); dirty(&asblk);
} }
if (asblk.b_dirty) { if (asblk.b_dirty && !bflag) {
bcopy((char *)&sblock, (char *)&altsblock, memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
(size_t)sblock.fs_sbsize);
flush(fswritefd, &asblk); flush(fswritefd, &asblk);
} }
/* /*
@ -249,7 +262,7 @@ setup(dev)
size) != 0 && !asked) { size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION"); pfatal("BAD SUMMARY INFORMATION");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
asked++; asked++;
} }
} }
@ -297,7 +310,7 @@ setup(dev)
return (1); return (1);
badsb: badsb:
ckfini(); ckfini(0);
return (0); return (0);
} }
@ -308,7 +321,7 @@ static int
readsb(listerr) readsb(listerr)
int 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) if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
return (0); return (0);
@ -348,8 +361,8 @@ readsb(listerr)
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
if (asblk.b_errs) if (asblk.b_errs)
return (0); return (0);
altsblock.fs_link = sblock.fs_link; altsblock.fs_firstfield = sblock.fs_firstfield;
altsblock.fs_rlink = sblock.fs_rlink; altsblock.fs_unused_1 = sblock.fs_unused_1;
altsblock.fs_time = sblock.fs_time; altsblock.fs_time = sblock.fs_time;
altsblock.fs_cstotal = sblock.fs_cstotal; altsblock.fs_cstotal = sblock.fs_cstotal;
altsblock.fs_cgrotor = sblock.fs_cgrotor; altsblock.fs_cgrotor = sblock.fs_cgrotor;
@ -362,12 +375,11 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim; altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay; altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg; altsblock.fs_maxbpg = sblock.fs_maxbpg;
bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
sizeof sblock.fs_csp); altsblock.fs_maxcluster = sblock.fs_maxcluster;
bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
sizeof sblock.fs_fsmnt); memmove(altsblock.fs_sparecon,
bcopy((char *)sblock.fs_sparecon, (char *)altsblock.fs_sparecon, sblock.fs_sparecon, sizeof sblock.fs_sparecon);
sizeof sblock.fs_sparecon);
/* /*
* The following should not have to be copied. * The following should not have to be copied.
*/ */
@ -375,11 +387,26 @@ readsb(listerr)
altsblock.fs_interleave = sblock.fs_interleave; altsblock.fs_interleave = sblock.fs_interleave;
altsblock.fs_npsect = sblock.fs_npsect; altsblock.fs_npsect = sblock.fs_npsect;
altsblock.fs_nrpos = sblock.fs_nrpos; altsblock.fs_nrpos = sblock.fs_nrpos;
altsblock.fs_state = sblock.fs_state;
altsblock.fs_qbmask = sblock.fs_qbmask; altsblock.fs_qbmask = sblock.fs_qbmask;
altsblock.fs_qfmask = sblock.fs_qfmask; altsblock.fs_qfmask = sblock.fs_qfmask;
altsblock.fs_state = sblock.fs_state; altsblock.fs_state = sblock.fs_state;
altsblock.fs_maxfilesize = sblock.fs_maxfilesize; 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, badsb(listerr,
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0); return (0);
@ -407,7 +434,7 @@ badsb(listerr, s)
* can be used. Do NOT attempt to use other macros without verifying that * can be used. Do NOT attempt to use other macros without verifying that
* their needed information is available! * their needed information is available!
*/ */
int static int
calcsb(dev, devfd, fs) calcsb(dev, devfd, fs)
char *dev; char *dev;
int devfd; int devfd;
@ -418,7 +445,7 @@ calcsb(dev, devfd, fs)
register char *cp; register char *cp;
int i; int i;
cp = index(dev, '\0') - 1; cp = strchr(dev, '\0') - 1;
if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) { if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0); return (0);
@ -434,7 +461,7 @@ calcsb(dev, devfd, fs)
fstypenames[pp->p_fstype] : "unknown"); fstypenames[pp->p_fstype] : "unknown");
return (0); return (0);
} }
bzero((char *)fs, sizeof(struct fs)); memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize; fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag; fs->fs_frag = pp->p_frag;
fs->fs_cpg = pp->p_cpg; fs->fs_cpg = pp->p_cpg;
@ -461,7 +488,7 @@ calcsb(dev, devfd, fs)
return (1); return (1);
} }
struct disklabel * static struct disklabel *
getdisklabel(s, fd) getdisklabel(s, fd)
char *s; char *s;
int fd; int fd;
@ -472,7 +499,7 @@ getdisklabel(s, fd)
if (s == NULL) if (s == NULL)
return ((struct disklabel *)NULL); return ((struct disklabel *)NULL);
pwarn("ioctl (GCINFO): %s\n", strerror(errno)); 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); return (&lab);
} }

View File

@ -32,11 +32,12 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.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 <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <err.h>
#include "fsck.h" #include "fsck.h"
long diskreads, totalreads; /* Disk cache statistics */ 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 int
ftypeok(dp) ftypeok(dp)
@ -119,7 +123,7 @@ bufinit()
pbp = pdirbp = (struct bufarea *)0; pbp = pdirbp = (struct bufarea *)0;
bufp = malloc((unsigned int)sblock.fs_bsize); bufp = malloc((unsigned int)sblock.fs_bsize);
if (bufp == 0) if (bufp == 0)
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
cgblk.b_un.b_buf = bufp; cgblk.b_un.b_buf = bufp;
initbarea(&cgblk); initbarea(&cgblk);
bufhead.b_next = bufhead.b_prev = &bufhead; bufhead.b_next = bufhead.b_prev = &bufhead;
@ -132,7 +136,7 @@ bufinit()
if (bp == NULL || bufp == NULL) { if (bp == NULL || bufp == NULL) {
if (i >= MINBUFS) if (i >= MINBUFS)
break; break;
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
} }
bp->b_un.b_buf = bufp; bp->b_un.b_buf = bufp;
bp->b_prev = &bufhead; bp->b_prev = &bufhead;
@ -149,7 +153,7 @@ bufinit()
*/ */
struct bufarea * struct bufarea *
getdatablk(blkno, size) getdatablk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {
register struct bufarea *bp; register struct bufarea *bp;
@ -161,7 +165,7 @@ getdatablk(blkno, size)
if ((bp->b_flags & B_INUSE) == 0) if ((bp->b_flags & B_INUSE) == 0)
break; break;
if (bp == &bufhead) if (bp == &bufhead)
errexit("deadlocked buffer pool\n"); errx(EEXIT, "deadlocked buffer pool");
getblk(bp, blkno, size); getblk(bp, blkno, size);
/* fall through */ /* fall through */
foundit: foundit:
@ -179,10 +183,10 @@ getdatablk(blkno, size)
void void
getblk(bp, blk, size) getblk(bp, blk, size)
register struct bufarea *bp; register struct bufarea *bp;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
daddr_t dblk; ufs_daddr_t dblk;
dblk = fsbtodb(&sblock, blk); dblk = fsbtodb(&sblock, blk);
if (bp->b_bno != dblk) { if (bp->b_bno != dblk) {
@ -220,24 +224,25 @@ flush(fd, bp)
} }
} }
void static void
rwerror(mesg, blk) rwerror(mesg, blk)
char *mesg; char *mesg;
daddr_t blk; ufs_daddr_t blk;
{ {
if (preen == 0) if (preen == 0)
printf("\n"); printf("\n");
pfatal("CANNOT %s: BLK %ld", mesg, blk); pfatal("CANNOT %s: BLK %ld", mesg, blk);
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit("Program terminated\n"); exit(EEXIT);
} }
void void
ckfini() ckfini(markclean)
int markclean;
{ {
register struct bufarea *bp, *nbp; register struct bufarea *bp, *nbp;
int cnt = 0; int ofsmodified, cnt = 0;
if (fswritefd < 0) { if (fswritefd < 0) {
(void)close(fsreadfd); (void)close(fsreadfd);
@ -260,8 +265,17 @@ ckfini()
free((char *)bp); free((char *)bp);
} }
if (bufhead.b_size != cnt) 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; 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) if (debug)
printf("cache missed %ld of %ld (%d%%)\n", diskreads, printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads)); totalreads, (int)(diskreads * 100 / totalreads));
@ -273,7 +287,7 @@ int
bread(fd, buf, blk, size) bread(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
char *cp; char *cp;
@ -290,7 +304,7 @@ bread(fd, buf, blk, size)
if (lseek(fd, offset, 0) < 0) if (lseek(fd, offset, 0) < 0)
rwerror("SEEK", blk); rwerror("SEEK", blk);
errs = 0; errs = 0;
bzero(buf, (size_t)size); memset(buf, 0, (size_t)size);
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
if (read(fd, cp, (int)secsize) != secsize) { if (read(fd, cp, (int)secsize) != secsize) {
@ -312,7 +326,7 @@ void
bwrite(fd, buf, blk, size) bwrite(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
int i; int i;
@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size)
/* /*
* allocate a data block with the specified number of fragments * allocate a data block with the specified number of fragments
*/ */
int ufs_daddr_t
allocblk(frags) allocblk(frags)
long frags; long frags;
{ {
@ -378,7 +392,7 @@ allocblk(frags)
*/ */
void void
freeblk(blkno, frags) freeblk(blkno, frags)
daddr_t blkno; ufs_daddr_t blkno;
long frags; long frags;
{ {
struct inodesc idesc; struct inodesc idesc;
@ -411,7 +425,7 @@ getpathname(namebuf, curdir, ino)
return; return;
} }
busy = 1; busy = 1;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_fix = IGNORE; idesc.id_fix = IGNORE;
cp = &namebuf[MAXPATHLEN - 1]; cp = &namebuf[MAXPATHLEN - 1];
@ -435,7 +449,7 @@ getpathname(namebuf, curdir, ino)
break; break;
len = strlen(namebuf); len = strlen(namebuf);
cp -= len; cp -= len;
bcopy(namebuf, cp, (size_t)len); memmove(cp, namebuf, (size_t)len);
*--cp = '/'; *--cp = '/';
if (cp < &namebuf[MAXNAMLEN]) if (cp < &namebuf[MAXNAMLEN])
break; break;
@ -444,15 +458,15 @@ getpathname(namebuf, curdir, ino)
busy = 0; busy = 0;
if (ino != ROOTINO) if (ino != ROOTINO)
*--cp = '?'; *--cp = '?';
bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp)); memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp));
} }
void void
catch(x) catch(sig)
int x; int sig;
{ {
if (!doinglevel2) if (!doinglevel2)
ckfini(); ckfini(0);
exit(12); exit(12);
} }
@ -462,8 +476,8 @@ catch(x)
* so that reboot sequence may be interrupted. * so that reboot sequence may be interrupted.
*/ */
void void
catchquit(x) catchquit(sig)
int x; int sig;
{ {
printf("returning to single-user after filesystem check\n"); printf("returning to single-user after filesystem check\n");
returntosingle = 1; returntosingle = 1;
@ -475,8 +489,8 @@ catchquit(x)
* Used by child processes in preen. * Used by child processes in preen.
*/ */
void void
voidquit(x) voidquit(sig)
int x; int sig;
{ {
sleep(1); sleep(1);
@ -520,76 +534,95 @@ dofix(idesc, msg)
return (0); return (0);
default: default:
errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix);
return (0);
} }
/* NOTREACHED */ /* NOTREACHED */
return (0);
} }
/* VARARGS1 */ #if __STDC__
void #include <stdarg.h>
errexit(const char *s1, ...) #else
{ #include <varargs.h>
va_list ap; #endif
va_start(ap,s1);
vfprintf(stdout, s1, ap);
va_end(ap);
exit(8);
}
/* /*
* An unexpected inconsistency occured. * An unexpected inconsistency occured.
* Die if preening, otherwise just print message and continue. * Die if preening, otherwise just print message and continue.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
if (preen) { va_start(ap, fmt);
printf("%s: ", cdevname); #else
vfprintf(stdout, s, ap); va_start(ap);
printf("\n"); #endif
printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", if (!preen) {
cdevname); (void)vfprintf(stderr, fmt, ap);
exit(8); va_end(ap);
return;
} }
vfprintf(stdout, s, ap); (void)fprintf(stderr, "%s: ", cdevname);
va_end(ap); (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, * Pwarn just prints a message when not preening,
* or a warning (preceded by filename) when preening. * or a warning (preceded by filename) when preening.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
if (preen) if (preen)
printf("%s: ", cdevname); (void)fprintf(stderr, "%s: ", cdevname);
vfprintf(stdout, s, ap); (void)vfprintf(stderr, fmt, ap);
va_end(ap); va_end(ap);
} }
#ifndef lint
/* /*
* Stub for routines from kernel. * Stub for routines from kernel.
*/ */
void void
#ifdef __STDC__ #if __STDC__
panic(const char *fmt, ...) panic(const char *fmt, ...)
#else #else
panic(fmt, va_alist) panic(fmt, va_alist)
char *fmt; char *fmt;
va_dcl
#endif #endif
{ {
va_list ap;
pfatal("INTERNAL INCONSISTENCY:"); #if __STDC__
errexit(fmt); va_start(ap, fmt);
} #else
va_start(ap);
#endif #endif
pfatal("INTERNAL INCONSISTENCY:");
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
exit(EEXIT);
}

View File

@ -1,9 +1,10 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93 # @(#)Makefile 8.2 (Berkeley) 4/27/95
PROG= fsck PROG= fsck
MAN8= fsck.8 MAN8= fsck.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ 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 pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
CFLAGS+=-W
.PATH: ${.CURDIR}/../../sys/ufs/ffs .PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -32,17 +32,20 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
char *lfname = "lost+found"; char *lfname = "lost+found";
@ -57,15 +60,14 @@ struct odirtemplate odirhead = {
0, DIRBLKSIZ - 12, 2, ".." 0, DIRBLKSIZ - 12, 2, ".."
}; };
static int chgino __P((struct inodesc *));
static int chgino __P((struct inodesc *idesc)); static int dircheck __P((struct inodesc *, struct direct *));
static int dircheck __P((struct inodesc *idesc, struct direct *dp)); static int expanddir __P((struct dinode *dp, char *name));
static int expanddir __P((struct dinode *dp, char *name)); static void freedir __P((ino_t ino, ino_t parent));
static void freedir __P((ino_t ino, ino_t parent)); static struct direct *fsck_readdir __P((struct inodesc *));
static struct direct * fsck_readdir __P((struct inodesc *idesc)); static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
static struct bufarea * getdirblk __P((daddr_t blkno, long size)); static int lftempname __P((char *bufp, ino_t ino));
static int lftempname __P((char *bufp, ino_t ino)); static int mkentry __P((struct inodesc *));
static int mkentry __P((struct inodesc *idesc));
/* /*
* Propagate connected state through the tree. * Propagate connected state through the tree.
@ -107,7 +109,7 @@ dirscan(idesc)
char dbuf[DIRBLKSIZ]; char dbuf[DIRBLKSIZ];
if (idesc->id_type != DATA) 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 && if (idesc->id_entryno == 0 &&
(idesc->id_filesize & (DIRBLKSIZ - 1)) != 0) (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ); idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
@ -119,7 +121,7 @@ dirscan(idesc)
idesc->id_loc = 0; idesc->id_loc = 0;
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
dsize = dp->d_reclen; dsize = dp->d_reclen;
bcopy((char *)dp, dbuf, (size_t)dsize); memmove(dbuf, dp, (size_t)dsize);
# if (BYTE_ORDER == LITTLE_ENDIAN) # if (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
struct direct *tdp = (struct direct *)dbuf; struct direct *tdp = (struct direct *)dbuf;
@ -144,7 +146,7 @@ dirscan(idesc)
} }
# endif # endif
bp = getdirblk(idesc->id_blkno, blksiz); 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); (size_t)dsize);
dirty(bp); dirty(bp);
sbdirty(); sbdirty();
@ -158,7 +160,7 @@ dirscan(idesc)
/* /*
* get next entry in a directory. * get next entry in a directory.
*/ */
struct direct * static struct direct *
fsck_readdir(idesc) fsck_readdir(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
@ -173,6 +175,8 @@ fsck_readdir(idesc)
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (dircheck(idesc, dp)) if (dircheck(idesc, dp))
goto dpok; goto dpok;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
@ -202,6 +206,8 @@ fsck_readdir(idesc)
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
idesc->id_loc += size; idesc->id_loc += size;
idesc->id_filesize -= size; idesc->id_filesize -= size;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + dploc); dp = (struct direct *)(bp->b_un.b_buf + dploc);
@ -216,7 +222,7 @@ fsck_readdir(idesc)
* Verify that a directory entry is valid. * Verify that a directory entry is valid.
* This is a superset of the checks made in the kernel. * This is a superset of the checks made in the kernel.
*/ */
int static int
dircheck(idesc, dp) dircheck(idesc, dp)
struct inodesc *idesc; struct inodesc *idesc;
register struct direct *dp; register struct direct *dp;
@ -226,8 +232,15 @@ dircheck(idesc, dp)
u_char namlen, type; u_char namlen, type;
int spaceleft; int spaceleft;
size = DIRSIZ(!newinofmt, dp);
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 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 (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
type = dp->d_namlen; type = dp->d_namlen;
@ -240,23 +253,17 @@ dircheck(idesc, dp)
namlen = dp->d_namlen; namlen = dp->d_namlen;
type = dp->d_type; type = dp->d_type;
# endif # endif
if (dp->d_ino < maxino && if (dp->d_reclen < size ||
dp->d_reclen != 0 && idesc->id_filesize < size ||
dp->d_reclen <= spaceleft && namlen > MAXNAMLEN ||
(dp->d_reclen & 0x3) == 0 && type > 15)
dp->d_reclen >= size && return (0);
idesc->id_filesize >= size && for (cp = dp->d_name, size = 0; size < namlen; size++)
namlen <= MAXNAMLEN && if (*cp == '\0' || (*cp++ == '/'))
type <= 15) { return (0);
if (dp->d_ino == 0) if (*cp != '\0')
return (1); return (0);
for (cp = dp->d_name, size = 0; size < namlen; size++) return (1);
if (*cp == 0 || (*cp++ == '/'))
return (0);
if (*cp == 0)
return (1);
}
return (0);
} }
void void
@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg)
void void
adjust(idesc, lcnt) adjust(idesc, lcnt)
register struct inodesc *idesc; register struct inodesc *idesc;
short lcnt; int lcnt;
{ {
register struct dinode *dp; register struct dinode *dp;
@ -323,7 +330,7 @@ adjust(idesc, lcnt)
} }
} }
int static int
mkentry(idesc) mkentry(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -343,30 +350,38 @@ mkentry(idesc)
dirp->d_reclen = oldlen; dirp->d_reclen = oldlen;
dirp = (struct direct *)(((char *)dirp) + oldlen); dirp = (struct direct *)(((char *)dirp) + oldlen);
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ 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; 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); return (ALTERED|STOP);
} }
int static int
chgino(idesc) chgino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
register struct direct *dirp = idesc->id_dirp; 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); return (KEEPON);
dirp->d_ino = idesc->id_parent; dirp->d_ino = idesc->id_parent;
if (newinofmt) if (newinofmt)
@ -387,7 +402,7 @@ linkup(orphan, parentdir)
struct inodesc idesc; struct inodesc idesc;
char tempname[BUFSIZ]; char tempname[BUFSIZ];
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
dp = ginode(orphan); dp = ginode(orphan);
lostdir = (dp->di_mode & IFMT) == IFDIR; lostdir = (dp->di_mode & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
@ -501,7 +516,7 @@ changeino(dir, name, newnum)
{ {
struct inodesc idesc; struct inodesc idesc;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = chgino; idesc.id_func = chgino;
idesc.id_number = dir; idesc.id_number = dir;
@ -526,7 +541,7 @@ makeentry(parent, ino, name)
if (parent < ROOTINO || parent >= maxino || if (parent < ROOTINO || parent >= maxino ||
ino < ROOTINO || ino >= maxino) ino < ROOTINO || ino >= maxino)
return (0); return (0);
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = mkentry; idesc.id_func = mkentry;
idesc.id_number = parent; idesc.id_number = parent;
@ -550,12 +565,12 @@ makeentry(parent, ino, name)
/* /*
* Attempt to expand the size of a directory * Attempt to expand the size of a directory
*/ */
int static int
expanddir(dp, name) expanddir(dp, name)
register struct dinode *dp; register struct dinode *dp;
char *name; char *name;
{ {
daddr_t lastbn, newblk; ufs_daddr_t lastbn, newblk;
register struct bufarea *bp; register struct bufarea *bp;
char *cp, firstblk[DIRBLKSIZ]; char *cp, firstblk[DIRBLKSIZ];
@ -572,21 +587,21 @@ expanddir(dp, name)
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ); memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
bp = getdirblk(newblk, sblock.fs_bsize); bp = getdirblk(newblk, sblock.fs_bsize);
if (bp->b_errs) if (bp->b_errs)
goto bad; 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp < &bp->b_un.b_buf[sblock.fs_bsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
bp = getdirblk(dp->di_db[lastbn + 1], bp = getdirblk(dp->di_db[lastbn + 1],
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; 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); pwarn("NO SPACE LEFT IN %s", name);
if (preen) if (preen)
printf(" (EXPANDED)\n"); printf(" (EXPANDED)\n");
@ -631,11 +646,11 @@ allocdir(parent, request, mode)
freeino(ino); freeino(ino);
return (0); 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_fsize]; cp < &bp->b_un.b_buf[sblock.fs_fsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
dp->di_nlink = 2; dp->di_nlink = 2;
inodirty(); inodirty();
@ -680,7 +695,7 @@ freedir(ino, parent)
/* /*
* generate a temporary name for the lost+found directory. * generate a temporary name for the lost+found directory.
*/ */
int static int
lftempname(bufp, ino) lftempname(bufp, ino)
char *bufp; char *bufp;
ino_t ino; ino_t ino;
@ -707,9 +722,9 @@ lftempname(bufp, ino)
* Get a directory block. * Get a directory block.
* Insure that it is held until another is requested. * Insure that it is held until another is requested.
*/ */
struct bufarea * static struct bufarea *
getdirblk(blkno, size) getdirblk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {

View File

@ -30,9 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 MAXDUP 10 /* limit on dup blks (per inode) */
#define MAXBAD 10 /* limit on bad blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
@ -53,20 +57,20 @@
* buffer cache structure. * buffer cache structure.
*/ */
struct bufarea { struct bufarea {
struct bufarea *b_next; /* free list queue */ struct bufarea *b_next; /* free list queue */
struct bufarea *b_prev; /* free list queue */ struct bufarea *b_prev; /* free list queue */
daddr_t b_bno; ufs_daddr_t b_bno;
int b_size; int b_size;
int b_errs; int b_errs;
int b_flags; int b_flags;
union { union {
char *b_buf; /* buffer space */ char *b_buf; /* buffer space */
daddr_t *b_indir; /* indirect block */ ufs_daddr_t *b_indir; /* indirect block */
struct fs *b_fs; /* super block */ struct fs *b_fs; /* super block */
struct cg *b_cg; /* cylinder group */ struct cg *b_cg; /* cylinder group */
struct dinode *b_dinode; /* inode block */ struct dinode *b_dinode; /* inode block */
} b_un; } b_un;
char b_dirty; char b_dirty;
}; };
#define B_INUSE 1 #define B_INUSE 1
@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */
struct bufarea cgblk; /* cylinder group blocks */ struct bufarea cgblk; /* cylinder group blocks */
struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */ struct bufarea *pbp; /* current inode block */
struct bufarea *getdatablk();
#define dirty(bp) (bp)->b_dirty = 1 #define dirty(bp) (bp)->b_dirty = 1
#define initbarea(bp) \ #define initbarea(bp) \
(bp)->b_dirty = 0; \ (bp)->b_dirty = 0; \
(bp)->b_bno = (daddr_t)-1; \ (bp)->b_bno = (ufs_daddr_t)-1; \
(bp)->b_flags = 0; (bp)->b_flags = 0;
#define sbdirty() sblk.b_dirty = 1 #define sbdirty() sblk.b_dirty = 1
@ -97,7 +100,7 @@ struct inodesc {
int (*id_func)(); /* function to be applied to blocks of inode */ int (*id_func)(); /* function to be applied to blocks of inode */
ino_t id_number; /* inode number described */ ino_t id_number; /* inode number described */
ino_t id_parent; /* for DATA nodes, their parent */ 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 */ int id_numfrags; /* number of frags contained in block */
quad_t id_filesize; /* for DATA nodes, the size of the directory */ quad_t id_filesize; /* for DATA nodes, the size of the directory */
int id_loc; /* for DATA nodes, current location in dir */ int id_loc; /* for DATA nodes, current location in dir */
@ -133,7 +136,7 @@ struct inodesc {
*/ */
struct dups { struct dups {
struct dups *next; struct dups *next;
daddr_t dup; ufs_daddr_t dup;
}; };
struct dups *duplist; /* head of dup list */ struct dups *duplist; /* head of dup list */
struct dups *muldup; /* end of unique duplicate dup block numbers */ struct dups *muldup; /* end of unique duplicate dup block numbers */
@ -157,7 +160,7 @@ struct inoinfo {
ino_t i_dotdot; /* inode number of `..' */ ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */ size_t i_isize; /* size of inode */
u_int i_numblks; /* size of block array in bytes */ 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; } **inphead, **inpsort;
long numdirs, listmax, inplast; long numdirs, listmax, inplast;
@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */
int returntosingle; /* return to single user mode */ int returntosingle; /* return to single user mode */
int rerun; /* rerun fsck. Only used in non-preen 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 */ char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in file system */ ino_t maxino; /* number of inodes in file system */
ino_t lastino; /* last inode in use */ ino_t lastino; /* last inode in use */
char *statemap; /* ptr to inode state table */ 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 */ short *lncntp; /* ptr to link count table */
ino_t lfdir; /* lost & found directory inode number */ ino_t lfdir; /* lost & found directory inode number */
char *lfname; /* lost & found directory name */ char *lfname; /* lost & found directory name */
int lfmode; /* lost & found directory creation mode */ int lfmode; /* lost & found directory creation mode */
daddr_t n_blks; /* number of blocks in use */ ufs_daddr_t n_blks; /* number of blocks in use */
daddr_t n_files; /* number of files in use */ ufs_daddr_t n_files; /* number of files in use */
#define clearinode(dp) (*(dp) = zino) #define clearinode(dp) (*(dp) = zino)
struct dinode zino; struct dinode zino;
@ -210,84 +213,69 @@ struct dinode zino;
#define ALTERED 0x08 #define ALTERED 0x08
#define FOUND 0x10 #define FOUND 0x10
/* dir.c */ #define EEXIT 8 /* Standard error exit. */
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 */ struct fstab;
void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt));
/* inode.c */ void adjust __P((struct inodesc *, int lcnt));
ino_t allocino __P((ino_t request, int type)); ufs_daddr_t allocblk __P((long frags));
void blkerror __P((ino_t ino, char *type, daddr_t blk)); ino_t allocdir __P((ino_t parent, ino_t request, int mode));
void cacheino __P((struct dinode *dp, ino_t inumber)); ino_t allocino __P((ino_t request, int type));
int chkrange __P((daddr_t blk, int cnt)); void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
int ckinode __P((struct dinode *dp, struct inodesc *idesc)); char *blockcheck __P((char *name));
void clri __P((struct inodesc *idesc, char *type, int flag)); int bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
int findino __P((struct inodesc *idesc)); void bufinit __P((void));
void freeino __P((ino_t ino)); void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
void freeinodebuf __P((void)); void cacheino __P((struct dinode *dp, ino_t inumber));
struct dinode * ginode __P((ino_t inumber)); void catch __P((int));
struct inoinfo * getinoinfo __P((ino_t inumber)); void catchquit __P((int));
struct dinode * getnextinode __P((ino_t inumber)); int changeino __P((ino_t dir, char *name, ino_t newnum));
void inodirty __P((void)); int checkfstab __P((int preen, int maxrun,
void inocleanup __P((void)); int (*docheck)(struct fstab *),
void pinode __P((ino_t ino)); int (*chkit)(char *, char *, long, int)));
void resetinodebuf __P((void)); int chkrange __P((ufs_daddr_t blk, int cnt));
int findname __P((struct inodesc *idesc)); void ckfini __P((int markclean));
int ckinode __P((struct dinode *dp, struct inodesc *));
/* pass1.c */ void clri __P((struct inodesc *, char *type, int flag));
void pass1 __P((void)); void direrror __P((ino_t ino, char *errmesg));
int pass1check __P((struct inodesc *idesc)); int dirscan __P((struct inodesc *));
int dofix __P((struct inodesc *, char *msg));
/* pass1b.c */ void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass1b __P((void)); void ffs_fragacct __P((struct fs *, int, int32_t [], int));
int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
/* pass2.c */ void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass2 __P((void)); void fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
int findino __P((struct inodesc *));
/* pass3.c */ int findname __P((struct inodesc *));
void pass3 __P((void)); void flush __P((int fd, struct bufarea *bp));
void freeblk __P((ufs_daddr_t blkno, long frags));
/* pass4.c */ void freeino __P((ino_t ino));
void pass4 __P((void)); void freeinodebuf __P((void));
int pass4check __P((struct inodesc *idesc)); int ftypeok __P((struct dinode *dp));
void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
/* pass5.c */ struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
void pass5 __P((void)); struct inoinfo *getinoinfo __P((ino_t inumber));
struct dinode *getnextinode __P((ino_t inumber));
/* preen.c */ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
char *blockcheck __P((char *name)); struct dinode *ginode __P((ino_t inumber));
int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); void inocleanup __P((void));
void inodirty __P((void));
/* setup.c */ int linkup __P((ino_t orphan, ino_t parentdir));
int setup __P((char *dev)); int makeentry __P((ino_t parent, ino_t ino, char *name));
void panic __P((const char *fmt, ...));
/* utilities.c */ void pass1 __P((void));
int allocblk __P((long frags)); void pass1b __P((void));
int bread __P((int fd, char *buf, daddr_t blk, long size)); int pass1check __P((struct inodesc *));
void bufinit __P((void)); void pass2 __P((void));
void bwrite __P((int fd, char *buf, daddr_t blk, long size)); void pass3 __P((void));
void catch __P((int)); void pass4 __P((void));
void catchquit __P((int)); int pass4check __P((struct inodesc *));
void ckfini __P((void)); void pass5 __P((void));
int dofix __P((struct inodesc *idesc, char *msg)); void pfatal __P((const char *fmt, ...));
void errexit __P((const char *s1, ...)) __dead2; void pinode __P((ino_t ino));
void flush __P((int fd, struct bufarea *bp)); void propagate __P((void));
void freeblk __P((daddr_t blkno, long frags)); void pwarn __P((const char *fmt, ...));
int ftypeok __P((struct dinode *dp)); int reply __P((char *question));
void getblk __P((struct bufarea *bp, daddr_t blk, long size)); void resetinodebuf __P((void));
struct bufarea * getdatablk __P((daddr_t blkno, long size)); int setup __P((char *dev));
void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); void voidquit __P((int));
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));

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 .\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id$ .|' $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 .Dt FSCK 8
.Os BSD 4 .Os BSD 4
.Sh NAME .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. to be the partition designator.
.Pp .Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that 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 .Fl f
option is specified, the filesystems option is specified, the filesystems
will be checked regardless of the state of their clean flag. 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. Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised. Note that the level of a filesystem can only be raised.
.Bl -tag -width indent .Bl -tag -width indent
There are currently three levels defined: There are currently four levels defined:
.It 0 .It 0
The filesystem is in the old (static table) format. The filesystem is in the old (static table) format.
.It 1 .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, The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode, short symbolic links are stored in the inode,
and directories have an added field showing the file type. 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 .El
.Pp .Pp
In interactive mode, In interactive mode,

View File

@ -32,32 +32,35 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <err.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static ino_t startinum; 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 int
ckinode(dp, idesc) ckinode(dp, idesc)
struct dinode *dp; struct dinode *dp;
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
int ret; long ret, n, ndb, offset;
long n, ndb, offset;
struct dinode dino; struct dinode dino;
quad_t remsize, sizepb; quad_t remsize, sizepb;
mode_t mode; mode_t mode;
@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize)
long ilevel; long ilevel;
quad_t isize; quad_t isize;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
register daddr_t *aplim; ufs_daddr_t *aplim;
register struct bufarea *bp; struct bufarea *bp;
int i, n, (*func)(), nif; int i, n, (*func)(), nif;
quad_t sizepb; quad_t sizepb;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize)
*/ */
int int
chkrange(blk, cnt) chkrange(blk, cnt)
daddr_t blk; ufs_daddr_t blk;
int cnt; int cnt;
{ {
register int c; register int c;
@ -268,10 +271,10 @@ struct dinode *
ginode(inumber) ginode(inumber)
ino_t inumber; ino_t inumber;
{ {
daddr_t iblk; ufs_daddr_t iblk;
if (inumber < ROOTINO || inumber > maxino) 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 || if (startinum == 0 ||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) { inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
iblk = ino_to_fsba(&sblock, inumber); iblk = ino_to_fsba(&sblock, inumber);
@ -296,11 +299,11 @@ getnextinode(inumber)
ino_t inumber; ino_t inumber;
{ {
long size; long size;
daddr_t dblk; ufs_daddr_t dblk;
static struct dinode *dp; static struct dinode *dp;
if (inumber != nextino++ || inumber > maxino) 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) { if (inumber >= lastinum) {
readcnt++; readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
@ -338,7 +341,7 @@ resetinodebuf()
} }
if (inodebuf == NULL && if (inodebuf == NULL &&
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == 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) while (nextino < ROOTINO)
(void)getnextinode(nextino); (void)getnextinode(nextino);
} }
@ -372,7 +375,7 @@ cacheino(dp, inumber)
if (blks > NDADDR) if (blks > NDADDR)
blks = NDADDR + NIADDR; blks = NDADDR + NIADDR;
inp = (struct inoinfo *) inp = (struct inoinfo *)
malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t)); malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
if (inp == NULL) if (inp == NULL)
return; return;
inpp = &inphead[inumber % numdirs]; inpp = &inphead[inumber % numdirs];
@ -385,15 +388,14 @@ cacheino(dp, inumber)
inp->i_dotdot = (ino_t)0; inp->i_dotdot = (ino_t)0;
inp->i_number = inumber; inp->i_number = inumber;
inp->i_isize = dp->di_size; inp->i_isize = dp->di_size;
inp->i_numblks = blks * sizeof(daddr_t); inp->i_numblks = blks * sizeof(ufs_daddr_t);
bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0], memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
if (inplast == listmax) { if (inplast == listmax) {
listmax += 100; listmax += 100;
inpsort = (struct inoinfo **)realloc((char *)inpsort, inpsort = (struct inoinfo **)realloc((char *)inpsort,
(unsigned)listmax * sizeof(struct inoinfo *)); (unsigned)listmax * sizeof(struct inoinfo *));
if (inpsort == NULL) if (inpsort == NULL)
errexit("cannot increase directory list"); errx(EEXIT, "cannot increase directory list");
} }
inpsort[inplast++] = inp; inpsort[inplast++] = inp;
} }
@ -412,7 +414,7 @@ getinoinfo(inumber)
continue; continue;
return (inp); return (inp);
} }
errexit("cannot find inode %d\n", inumber); errx(EEXIT, "cannot find inode %d", inumber);
return ((struct inoinfo *)0); return ((struct inoinfo *)0);
} }
@ -472,7 +474,7 @@ findname(idesc)
if (dirp->d_ino != idesc->id_parent) if (dirp->d_ino != idesc->id_parent)
return (KEEPON); 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); return (STOP|FOUND);
} }
@ -514,7 +516,7 @@ pinode(ino)
if (preen) if (preen)
printf("%s: ", cdevname); printf("%s: ", cdevname);
printf("SIZE=%qu ", dp->di_size); 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]); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
} }
@ -522,7 +524,7 @@ void
blkerror(ino, type, blk) blkerror(ino, type, blk)
ino_t ino; ino_t ino;
char *type; char *type;
daddr_t blk; ufs_daddr_t blk;
{ {
pfatal("%ld %s I=%lu", blk, type, ino); pfatal("%ld %s I=%lu", blk, type, ino);
@ -542,7 +544,7 @@ blkerror(ino, type, blk)
return; return;
default: default:
errexit("BAD STATE %d TO BLKERR", statemap[ino]); errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@ -585,7 +587,7 @@ allocino(request, type)
return (0); return (0);
} }
dp->di_mode = type; 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_mtime = dp->di_ctime = dp->di_atime;
dp->di_size = sblock.fs_fsize; dp->di_size = sblock.fs_fsize;
dp->di_blocks = btodb(sblock.fs_fsize); dp->di_blocks = btodb(sblock.fs_fsize);
@ -606,7 +608,7 @@ freeino(ino)
struct inodesc idesc; struct inodesc idesc;
struct dinode *dp; struct dinode *dp;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
idesc.id_number = ino; idesc.id_number = ino;

View File

@ -38,25 +38,35 @@ static const char copyright[] =
#endif /* not lint */ #endif /* not lint */
#ifndef 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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <ctype.h>
#include <err.h>
#include <fstab.h> #include <fstab.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "fsck.h" #include "fsck.h"
static int argtoi __P((int flag, char *req, char *str, int base));
static int docheck __P((struct fstab *fsp)); int returntosingle;
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
int child)); 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 int
main(argc, argv) main(argc, argv)
@ -99,7 +109,7 @@ main(argc, argv)
case 'm': case 'm':
lfmode = argtoi('m', "mode", optarg, 8); lfmode = argtoi('m', "mode", optarg, 8);
if (lfmode &~ 07777) 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); printf("** lost+found creation mode %o\n", lfmode);
break; break;
@ -116,7 +126,7 @@ main(argc, argv)
break; break;
default: default:
errexit("%c option?\n", ch); errx(EEXIT, "%c option?", ch);
} }
} }
argc -= optind; argc -= optind;
@ -136,7 +146,7 @@ main(argc, argv)
exit(ret); exit(ret);
} }
int static int
argtoi(flag, req, str, base) argtoi(flag, req, str, base)
int flag; int flag;
char *req, *str; char *req, *str;
@ -147,14 +157,14 @@ argtoi(flag, req, str, base)
ret = (int)strtol(str, &cp, base); ret = (int)strtol(str, &cp, base);
if (cp == str || *cp) if (cp == str || *cp)
errexit("-%c flag requires a %s\n", flag, req); errx(EEXIT, "-%c flag requires a %s", flag, req);
return (ret); return (ret);
} }
/* /*
* Determine whether a filesystem should be checked. * Determine whether a filesystem should be checked.
*/ */
int static int
docheck(fsp) docheck(fsp)
register struct fstab *fsp; register struct fstab *fsp;
{ {
@ -171,25 +181,28 @@ docheck(fsp)
* Check the specified filesystem. * Check the specified filesystem.
*/ */
/* ARGSUSED */ /* ARGSUSED */
int static int
checkfilesys(filesys, mntpt, auxdata, child) checkfilesys(filesys, mntpt, auxdata, child)
char *filesys, *mntpt; char *filesys, *mntpt;
long auxdata; long auxdata;
int child; int child;
{ {
daddr_t n_ffree, n_bfree; ufs_daddr_t n_ffree, n_bfree;
struct dups *dp; struct dups *dp;
struct zlncnt *zlnp; struct zlncnt *zlnp;
int cylno; int cylno, flags;
if (preen && child) if (preen && child)
(void)signal(SIGQUIT, voidquit); (void)signal(SIGQUIT, voidquit);
cdevname = filesys; cdevname = filesys;
if (debug && preen) if (debug && preen)
pwarn("starting\n"); pwarn("starting\n");
if (setup(filesys) == 0) { switch (setup(filesys)) {
case 0:
if (preen) if (preen)
pfatal("CAN'T CHECK FILE SYSTEM."); pfatal("CAN'T CHECK FILE SYSTEM.");
/* fall through */
case -1:
return (0); return (0);
} }
@ -302,7 +315,19 @@ checkfilesys(filesys, mntpt, auxdata, child)
bwrite(fswritefd, (char *)&sblock, bwrite(fswritefd, (char *)&sblock,
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); 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(blockmap);
free(statemap); free(statemap);
free((char *)lncntp); free((char *)lncntp);
@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (rerun) if (rerun)
printf("\n***** PLEASE RERUN FSCK *****\n"); printf("\n***** PLEASE RERUN FSCK *****\n");
if (hotroot) { if (hotroot) {
struct statfs stfs_buf; struct ufs_args args;
int ret;
/* /*
* We modified the root. Do a mount update on * We modified the root. Do a mount update on
* it, unless it is read-write, so we can continue. * it, unless it is read-write, so we can continue.
*/ */
if (statfs("/", &stfs_buf) == 0) { if (flags & MNT_RDONLY) {
long flags = stfs_buf.f_flags; args.fspec = 0;
struct ufs_args args; args.export.ex_flags = 0;
int ret; args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
if (flags & MNT_RDONLY) { ret = mount("ufs", "/", flags, &args);
args.fspec = 0; if (ret == 0)
args.export.ex_flags = 0; return (0);
args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
ret = mount(MOUNT_UFS, "/", flags, &args);
if (ret == 0)
return(0);
}
} }
if (!preen) if (!preen)
printf("\n***** REBOOT NOW *****\n"); printf("\n***** REBOOT NOW *****\n");

View File

@ -32,23 +32,27 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static daddr_t badblk; static ufs_daddr_t badblk;
static daddr_t dupblk; 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 void
pass1() pass1()
@ -73,7 +77,7 @@ pass1()
/* /*
* Find all allocated blocks. * Find all allocated blocks.
*/ */
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1check; idesc.id_func = pass1check;
inumber = 0; inumber = 0;
@ -89,7 +93,7 @@ pass1()
freeinodebuf(); freeinodebuf();
} }
void static void
checkinode(inumber, idesc) checkinode(inumber, idesc)
ino_t inumber; ino_t inumber;
register struct inodesc *idesc; register struct inodesc *idesc;
@ -103,10 +107,10 @@ checkinode(inumber, idesc)
dp = getnextinode(inumber); dp = getnextinode(inumber);
mode = dp->di_mode & IFMT; mode = dp->di_mode & IFMT;
if (mode == 0) { if (mode == 0) {
if (bcmp((char *)dp->di_db, (char *)zino.di_db, if (memcmp(dp->di_db, zino.di_db,
NDADDR * sizeof(daddr_t)) || NDADDR * sizeof(ufs_daddr_t)) ||
bcmp((char *)dp->di_ib, (char *)zino.di_ib, memcmp(dp->di_ib, zino.di_ib,
NIADDR * sizeof(daddr_t)) || NIADDR * sizeof(ufs_daddr_t)) ||
dp->di_mode || dp->di_size) { dp->di_mode || dp->di_size) {
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
if (reply("CLEAR") == 1) { if (reply("CLEAR") == 1) {
@ -120,7 +124,8 @@ checkinode(inumber, idesc)
} }
lastino = inumber; lastino = inumber;
if (/* dp->di_size < 0 || */ 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) if (debug)
printf("bad size %qu:", dp->di_size); printf("bad size %qu:", dp->di_size);
goto unknown; goto unknown;
@ -148,15 +153,14 @@ checkinode(inumber, idesc)
if (bread(fsreadfd, symbuf, if (bread(fsreadfd, symbuf,
fsbtodb(&sblock, dp->di_db[0]), fsbtodb(&sblock, dp->di_db[0]),
(long)secsize) != 0) (long)secsize) != 0)
errexit("cannot read symlink"); errx(EEXIT, "cannot read symlink");
if (debug) { if (debug) {
symbuf[dp->di_size] = 0; symbuf[dp->di_size] = 0;
printf("convert symlink %ld(%s) of size %ld\n", printf("convert symlink %ld(%s) of size %ld\n",
inumber, symbuf, (long)dp->di_size); inumber, symbuf, (long)dp->di_size);
} }
dp = ginode(inumber); dp = ginode(inumber);
bcopy(symbuf, (caddr_t)dp->di_shortlink, memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
(long)dp->di_size);
dp->di_blocks = 0; dp->di_blocks = 0;
inodirty(); inodirty();
} }
@ -165,7 +169,7 @@ checkinode(inumber, idesc)
* will detect any garbage after symlink string. * will detect any garbage after symlink string.
*/ */
if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { 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) { if (ndb > NDADDR) {
j = ndb - NDADDR; j = ndb - NDADDR;
for (ndb = 1; j > 1; j--) for (ndb = 1; j > 1; j--)
@ -198,7 +202,7 @@ checkinode(inumber, idesc)
if (zlnp == NULL) { if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW"); pfatal("LINK COUNT TABLE OVERFLOW");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
} else { } else {
zlnp->zlncnt = inumber; zlnp->zlncnt = inumber;
zlnp->next = zlnhead; zlnp->next = zlnhead;
@ -256,7 +260,7 @@ pass1check(idesc)
{ {
int res = KEEPON; int res = KEEPON;
int anyout, nfrags; int anyout, nfrags;
daddr_t blkno = idesc->id_blkno; ufs_daddr_t blkno = idesc->id_blkno;
register struct dups *dlp; register struct dups *dlp;
struct dups *new; struct dups *new;
@ -268,7 +272,7 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
} }
@ -286,14 +290,14 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new = (struct dups *)malloc(sizeof(struct dups)); new = (struct dups *)malloc(sizeof(struct dups));
if (new == NULL) { if (new == NULL) {
pfatal("DUP TABLE OVERFLOW."); pfatal("DUP TABLE OVERFLOW.");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new->dup = blkno; new->dup = blkno;

View File

@ -32,18 +32,21 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
int pass1bcheck();
static struct dups *duphead; static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void void
pass1b() pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc; struct inodesc idesc;
ino_t inumber; ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1bcheck; idesc.id_func = pass1bcheck;
duphead = duplist; duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
} }
} }
int static int
pass1bcheck(idesc) pass1bcheck(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) if (chkrange(blkno, 1))

View File

@ -32,22 +32,26 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
#define MINDIRSIZE (sizeof (struct dirtemplate)) #define MINDIRSIZE (sizeof (struct dirtemplate))
int pass2check(), blksort(); static int blksort __P((const void *, const void *));
static int pass2check __P((struct inodesc *));
void void
pass2() pass2()
@ -64,9 +68,9 @@ pass2()
case USTATE: case USTATE:
pfatal("ROOT INODE UNALLOCATED"); pfatal("ROOT INODE UNALLOCATED");
if (reply("ALLOCATE") == 0) if (reply("ALLOCATE") == 0)
errexit(""); exit(EEXIT);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
case DCLEAR: case DCLEAR:
@ -74,11 +78,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
break; break;
case FSTATE: case FSTATE:
@ -87,11 +91,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("FIX") == 0) if (reply("FIX") == 0)
errexit(""); exit(EEXIT);
dp = ginode(ROOTINO); dp = ginode(ROOTINO);
dp->di_mode &= ~IFMT; dp->di_mode &= ~IFMT;
dp->di_mode |= IFDIR; dp->di_mode |= IFDIR;
@ -102,9 +106,13 @@ pass2()
break; break;
default: default:
errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
} }
statemap[ROOTINO] = DFOUND; statemap[ROOTINO] = DFOUND;
if (newinofmt) {
statemap[WINO] = FSTATE;
typemap[WINO] = DT_WHT;
}
/* /*
* Sort the directory list into disk block order. * Sort the directory list into disk block order.
*/ */
@ -112,7 +120,7 @@ pass2()
/* /*
* Check the integrity of each directory. * Check the integrity of each directory.
*/ */
bzero((char *)&curino, sizeof(struct inodesc)); memset(&curino, 0, sizeof(struct inodesc));
curino.id_type = DATA; curino.id_type = DATA;
curino.id_func = pass2check; curino.id_func = pass2check;
dp = &dino; dp = &dino;
@ -144,11 +152,10 @@ pass2()
dp = &dino; dp = &dino;
} }
} }
bzero((char *)&dino, sizeof(struct dinode)); memset(&dino, 0, sizeof(struct dinode));
dino.di_mode = IFDIR; dino.di_mode = IFDIR;
dp->di_size = inp->i_isize; dp->di_size = inp->i_isize;
bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0], memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
curino.id_number = inp->i_number; curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent; curino.id_parent = inp->i_parent;
(void)ckinode(dp, &curino); (void)ckinode(dp, &curino);
@ -191,7 +198,7 @@ pass2()
propagate(); propagate();
} }
int static int
pass2check(idesc) pass2check(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -239,6 +246,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 1; proto.d_namlen = 1;
(void)strcpy(proto.d_name, "."); (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); entrysize = DIRSIZ(0, &proto);
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
@ -247,17 +263,17 @@ pass2check(idesc)
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp->d_reclen < 2 * entrysize) { } else if (dirp->d_reclen < 2 * entrysize) {
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} else { } else {
n = dirp->d_reclen - entrysize; n = dirp->d_reclen - entrysize;
proto.d_reclen = entrysize; proto.d_reclen = entrysize;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + entrysize); dirp = (struct direct *)((char *)(dirp) + entrysize);
bzero((char *)dirp, (size_t)n); memset(dirp, 0, (size_t)n);
dirp->d_reclen = n; dirp->d_reclen = n;
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
@ -273,6 +289,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 2; proto.d_namlen = 2;
(void)strcpy(proto.d_name, ".."); (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); entrysize = DIRSIZ(0, &proto);
if (idesc->id_entryno == 0) { if (idesc->id_entryno == 0) {
n = DIRSIZ(0, dirp); n = DIRSIZ(0, dirp);
@ -283,7 +308,7 @@ pass2check(idesc)
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + n); 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; dirp->d_reclen = proto.d_reclen;
} }
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
@ -312,7 +337,7 @@ pass2check(idesc)
inp->i_dotdot = inp->i_parent; inp->i_dotdot = inp->i_parent;
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
@ -346,6 +371,14 @@ pass2check(idesc)
if (dirp->d_ino > maxino) { if (dirp->d_ino > maxino) {
fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
n = reply("REMOVE"); 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 { } else {
again: again:
switch (statemap[dirp->d_ino]) { switch (statemap[dirp->d_ino]) {
@ -412,7 +445,7 @@ pass2check(idesc)
break; break;
default: 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); statemap[dirp->d_ino], dirp->d_ino);
} }
} }
@ -425,10 +458,11 @@ pass2check(idesc)
/* /*
* Routine to sort disk blocks. * Routine to sort disk blocks.
*/ */
int static int
blksort(inpp1, inpp2) blksort(arg1, arg2)
struct inoinfo **inpp1, **inpp2; 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]);
} }

View File

@ -32,13 +32,15 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include "fsck.h" #include "fsck.h"
void void

View File

@ -32,18 +32,19 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdlib.h>
#include <string.h>
#include "fsck.h"
int pass4check(); #include <err.h>
#include <string.h>
#include "fsck.h"
void void
pass4() pass4()
@ -54,7 +55,7 @@ pass4()
struct inodesc idesc; struct inodesc idesc;
int n; int n;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
for (inumber = ROOTINO; inumber <= lastino; inumber++) { for (inumber = ROOTINO; inumber <= lastino; inumber++) {
@ -98,7 +99,7 @@ pass4()
break; break;
default: default:
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[inumber], inumber); statemap[inumber], inumber);
} }
} }
@ -110,7 +111,7 @@ pass4check(idesc)
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) { if (chkrange(blkno, 1)) {

View File

@ -32,26 +32,29 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
void void
pass5() pass5()
{ {
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
register struct fs *fs = &sblock; struct fs *fs = &sblock;
register struct cg *cg = &cgrp; struct cg *cg = &cgrp;
daddr_t dbase, dmax; ufs_daddr_t dbase, dmax;
register daddr_t d; ufs_daddr_t d;
register long i, j; long i, j;
struct csum *cs; struct csum *cs;
struct csum cstotal; struct csum cstotal;
struct inodesc idesc[3]; struct inodesc idesc[3];
@ -59,9 +62,10 @@ pass5()
register struct cg *newcg = (struct cg *)buf; register struct cg *newcg = (struct cg *)buf;
struct ocg *ocg = (struct ocg *)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; newcg->cg_niblk = fs->fs_ipg;
if (cvtlevel > 3) { if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen) if (preen)
pwarn("DELETING CLUSTERING MAPS\n"); pwarn("DELETING CLUSTERING MAPS\n");
@ -103,8 +107,9 @@ pass5()
switch ((int)fs->fs_postblformat) { switch ((int)fs->fs_postblformat) {
case FS_42POSTBLFMT: case FS_42POSTBLFMT:
basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); basesize = (char *)(&ocg->cg_btot[0]) -
sumsize = &ocg->cg_iused[0] - (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)] - mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
(u_char *)&ocg->cg_iused[0]; (u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -114,7 +119,7 @@ pass5()
case FS_DYNAMICPOSTBLFMT: case FS_DYNAMICPOSTBLFMT:
newcg->cg_btotoff = 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_boff =
newcg->cg_btotoff + fs->fs_cpg * sizeof(long); newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
newcg->cg_iusedoff = newcg->cg_boff + newcg->cg_iusedoff = newcg->cg_boff +
@ -136,22 +141,24 @@ pass5()
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
} }
newcg->cg_magic = CG_MAGIC; 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; sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
break; break;
default: default:
errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", sumsize = 0; /* keep lint happy */
errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
fs->fs_postblformat); fs->fs_postblformat);
} }
bzero((char *)&idesc[0], sizeof idesc); memset(&idesc[0], 0, sizeof idesc);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
idesc[i].id_type = ADDR; idesc[i].id_type = ADDR;
if (doinglevel2) if (doinglevel2)
idesc[i].id_fix = FIX; 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); j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
for (i = fs->fs_size; i < j; i++) for (i = fs->fs_size; i < j; i++)
setbmap(i); setbmap(i);
@ -188,8 +195,8 @@ pass5()
newcg->cg_irotor = cg->cg_irotor; newcg->cg_irotor = cg->cg_irotor;
else else
newcg->cg_irotor = 0; newcg->cg_irotor = 0;
bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
bzero((char *)&cg_blktot(newcg)[0], memset(&cg_blktot(newcg)[0], 0,
(size_t)(sumsize + mapsize)); (size_t)(sumsize + mapsize));
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -215,7 +222,7 @@ pass5()
default: default:
if (j < ROOTINO) if (j < ROOTINO)
break; break;
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[j], j); statemap[j], j);
} }
} }
@ -249,7 +256,7 @@ pass5()
} }
} }
if (fs->fs_contigsumsize > 0) { if (fs->fs_contigsumsize > 0) {
long *sump = cg_clustersum(newcg); int32_t *sump = cg_clustersum(newcg);
u_char *mapp = cg_clustersfree(newcg); u_char *mapp = cg_clustersfree(newcg);
int map = *mapp++; int map = *mapp++;
int bit = 1; int bit = 1;
@ -282,38 +289,38 @@ pass5()
cstotal.cs_nifree += newcg->cg_cs.cs_nifree; cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
cstotal.cs_ndir += newcg->cg_cs.cs_ndir; cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
cs = &fs->fs_cs(fs, c); 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")) { 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(); sbdirty();
} }
if (doinglevel1) { if (doinglevel1) {
bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); memmove(cg, newcg, (size_t)fs->fs_cgsize);
cgdirty(); cgdirty();
continue; continue;
} }
if (bcmp(cg_inosused(newcg), if (memcmp(cg_inosused(newcg),
cg_inosused(cg), mapsize) != 0 && cg_inosused(cg), mapsize) != 0 &&
dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 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); (size_t)mapsize);
cgdirty(); cgdirty();
} }
if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || if ((memcmp(newcg, cg, basesize) != 0 ||
bcmp((char *)&cg_blktot(newcg)[0], memcmp(&cg_blktot(newcg)[0],
(char *)&cg_blktot(cg)[0], sumsize) != 0) && &cg_blktot(cg)[0], sumsize) != 0) &&
dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
bcopy((char *)newcg, (char *)cg, (size_t)basesize); memmove(cg, newcg, (size_t)basesize);
bcopy((char *)&cg_blktot(newcg)[0], memmove(&cg_blktot(cg)[0],
(char *)&cg_blktot(cg)[0], (size_t)sumsize); &cg_blktot(newcg)[0], (size_t)sumsize);
cgdirty(); cgdirty();
} }
} }
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
fs->fs_nrpos = savednrpos; 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")) { && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
fs->fs_ronly = 0; fs->fs_ronly = 0;
sbdirty(); sbdirty();
} }

View File

@ -32,7 +32,7 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93";
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <fstab.h>
#include "fsck.h" #include "fsck.h"
struct part { struct part {
@ -62,19 +62,22 @@ struct disk {
int pid; /* If != 0, pid of proc working on */ int pid; /* If != 0, pid of proc working on */
} *disks; } *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; int nrun, ndisks;
char hotroot; 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 int
checkfstab(preen, maxrun, docheck, chkit) checkfstab(preen, maxrun, docheck, chkit)
int preen, maxrun; int preen;
int (*docheck)(), (*chkit)(); int maxrun;
int (*docheck)(struct fstab *);
int (*chkit)(char *, char *, long, int);
{ {
register struct fstab *fsp; register struct fstab *fsp;
register struct disk *dk, *nextdisk; register struct disk *dk, *nextdisk;
@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit)
while ((fsp = getfsent()) != 0) { while ((fsp = getfsent()) != 0) {
if ((auxdata = (*docheck)(fsp)) == 0) if ((auxdata = (*docheck)(fsp)) == 0)
continue; continue;
if (!preen || (passno == 1 && fsp->fs_passno == 1)) { if (preen == 0 ||
name = blockcheck(fsp->fs_spec); (passno == 1 && fsp->fs_passno == 1)) {
if (name) { if ((name = blockcheck(fsp->fs_spec)) != 0) {
sumstatus = (*chkit)(name, if ((sumstatus = (*chkit)(name,
fsp->fs_file, auxdata, 0); fsp->fs_file, auxdata, 0)) != 0)
if (sumstatus)
return (sumstatus); return (sumstatus);
} else if (preen) } else if (preen)
return (8); return (8);
@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit)
return (0); return (0);
} }
struct disk * static struct disk *
finddisk(name) finddisk(name)
char *name; char *name;
{ {
@ -206,13 +208,11 @@ finddisk(name)
register char *p; register char *p;
size_t len = 0; 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)) { if (isdigit(*p)) {
len = p - name + 1; len = p - name + 1;
break; break;
} }
if (p < name)
len = strlen(name);
for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
if (strncmp(dk->name, name, len) == 0 && if (strncmp(dk->name, name, len) == 0 &&
@ -237,7 +237,7 @@ finddisk(name)
return (dk); return (dk);
} }
void static void
addpart(name, fsname, auxdata) addpart(name, fsname, auxdata)
char *name, *fsname; char *name, *fsname;
long auxdata; long auxdata;
@ -269,10 +269,10 @@ addpart(name, fsname, auxdata)
pt->auxdata = auxdata; pt->auxdata = auxdata;
} }
int static int
startdisk(dk, checkit) startdisk(dk, checkit)
register struct disk *dk; register struct disk *dk;
int (*checkit)(); int (*checkit)(char *, char *, long, int);
{ {
register struct part *pt = dk->part; register struct part *pt = dk->part;
@ -288,11 +288,11 @@ startdisk(dk, checkit)
} }
char * char *
blockcheck(name) blockcheck(origname)
char *name; char *origname;
{ {
struct stat stslash, stblock, stchar; struct stat stslash, stblock, stchar;
char *raw; char *newname, *raw;
struct fstab *fsinfo; struct fstab *fsinfo;
int retried = 0, l; int retried = 0, l;
@ -300,60 +300,63 @@ blockcheck(name)
if (stat("/", &stslash) < 0) { if (stat("/", &stslash) < 0) {
perror("/"); perror("/");
printf("Can't stat root\n"); printf("Can't stat root\n");
return (0); return (origname);
} }
newname = origname;
retry: retry:
if (stat(name, &stblock) < 0) { if (stat(newname, &stblock) < 0) {
perror(name); perror(newname);
printf("Can't stat %s\n", name); printf("Can't stat %s\n", newname);
return (0); return (origname);
} }
if ((stblock.st_mode & S_IFMT) == S_IFBLK) { if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
if (stslash.st_dev == stblock.st_rdev) if (stslash.st_dev == stblock.st_rdev)
hotroot++; hotroot++;
raw = rawname(name); raw = rawname(newname);
if (stat(raw, &stchar) < 0) { if (stat(raw, &stchar) < 0) {
perror(raw); perror(raw);
printf("Can't stat %s\n", raw); printf("Can't stat %s\n", raw);
return (name); return (origname);
} }
if ((stchar.st_mode & S_IFMT) == S_IFCHR) { if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
return (raw); return (raw);
} else { } else {
printf("%s is not a character device\n", raw); printf("%s is not a character device\n", raw);
return (name); return (origname);
} }
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
name = unrawname(name); newname = unrawname(origname);
retried++; retried++;
goto retry; goto retry;
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
l = strlen(name) - 1; l = strlen(origname) - 1;
if (l > 0 && name[l] == '/') if (l > 0 && origname[l] == '/')
/* remove trailing slash */ /* remove trailing slash */
name[l] = '\0'; origname[l] = '\0';
if(!(fsinfo=getfsfile(name))) { if(!(fsinfo=getfsfile(origname))) {
printf("Can't resolve %s to character special device", printf("Can't resolve %s to character special device",
name); origname);
return (0); return (0);
} }
name = fsinfo->fs_spec; newname = fsinfo->fs_spec;
retried++; retried++;
goto retry; goto retry;
} }
printf("Warning: Can't find blockdevice corresponding to name %s\n", /*
name); * Not a block or character device, just return name and
return (name); * let the user decide whether to use it.
*/
return (origname);
} }
char * static char *
unrawname(name) unrawname(name)
char *name; char *name;
{ {
char *dp; char *dp;
struct stat stb; struct stat stb;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (name); return (name);
if (stat(name, &stb) < 0) if (stat(name, &stb) < 0)
return (name); return (name);
@ -365,14 +368,14 @@ unrawname(name)
return (name); return (name);
} }
char * static char *
rawname(name) rawname(name)
char *name; char *name;
{ {
static char rawbuf[32]; static char rawbuf[32];
char *dp; char *dp;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (0); return (0);
*dp = 0; *dp = 0;
(void)strcpy(rawbuf, name); (void)strcpy(rawbuf, name);

View File

@ -32,41 +32,49 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#define DKTYPENAMES #define DKTYPENAMES
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/file.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 <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "fsck.h" #include "fsck.h"
struct bufarea asblk; struct bufarea asblk;
#define altsblock (*asblk.b_un.b_fs) #define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0) #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static int readsb __P((int listerr)); static void badsb __P((int listerr, char *s));
static void badsb __P((int listerr, char *s)); static int calcsb __P((char *dev, int devfd, struct fs *fs));
static int calcsb __P((char *dev, int devfd, struct fs *fs)); static struct disklabel *getdisklabel __P((char *s, int fd));
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 int
setup(dev) setup(dev)
char *dev; char *dev;
{ {
long cg, size, asked, i, j; long cg, size, asked, i, j;
long bmapsize; long skipclean, bmapsize;
struct disklabel *lp; struct disklabel *lp;
off_t sizepb; off_t sizepb;
struct stat statb; struct stat statb;
@ -74,6 +82,7 @@ setup(dev)
havesb = 0; havesb = 0;
fswritefd = -1; fswritefd = -1;
skipclean = preen;
if (stat(dev, &statb) < 0) { if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno)); printf("Can't stat %s: %s\n", dev, strerror(errno));
return (0); return (0);
@ -104,7 +113,7 @@ setup(dev)
sblk.b_un.b_buf = malloc(SBSIZE); sblk.b_un.b_buf = malloc(SBSIZE);
asblk.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) 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); lp = getdisklabel((char *)NULL, fsreadfd);
if (lp) if (lp)
dev_bsize = secsize = lp->d_secsize; dev_bsize = secsize = lp->d_secsize;
@ -114,6 +123,7 @@ setup(dev)
* Read in the superblock, looking for alternates if necessary * Read in the superblock, looking for alternates if necessary
*/ */
if (readsb(1) == 0) { if (readsb(1) == 0) {
skipclean = 0;
if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
return(0); return(0);
if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
@ -137,6 +147,10 @@ setup(dev)
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
bflag = 0; bflag = 0;
} }
if (skipclean && sblock.fs_clean) {
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
return (-1);
}
maxfsblock = sblock.fs_size; maxfsblock = sblock.fs_size;
maxino = sblock.fs_ncg * sblock.fs_ipg; maxino = sblock.fs_ncg * sblock.fs_ipg;
/* /*
@ -223,17 +237,16 @@ setup(dev)
sblock.fs_nrpos = 8; sblock.fs_nrpos = 8;
sblock.fs_postbloff = sblock.fs_postbloff =
(char *)(&sblock.fs_opostbl[0][0]) - (char *)(&sblock.fs_opostbl[0][0]) -
(char *)(&sblock.fs_link); (char *)(&sblock.fs_firstfield);
sblock.fs_rotbloff = &sblock.fs_space[0] - sblock.fs_rotbloff = &sblock.fs_space[0] -
(u_char *)(&sblock.fs_link); (u_char *)(&sblock.fs_firstfield);
sblock.fs_cgsize = sblock.fs_cgsize =
fragroundup(&sblock, CGSIZE(&sblock)); fragroundup(&sblock, CGSIZE(&sblock));
sbdirty(); sbdirty();
dirty(&asblk); dirty(&asblk);
} }
if (asblk.b_dirty) { if (asblk.b_dirty && !bflag) {
bcopy((char *)&sblock, (char *)&altsblock, memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
(size_t)sblock.fs_sbsize);
flush(fswritefd, &asblk); flush(fswritefd, &asblk);
} }
/* /*
@ -249,7 +262,7 @@ setup(dev)
size) != 0 && !asked) { size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION"); pfatal("BAD SUMMARY INFORMATION");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
asked++; asked++;
} }
} }
@ -297,7 +310,7 @@ setup(dev)
return (1); return (1);
badsb: badsb:
ckfini(); ckfini(0);
return (0); return (0);
} }
@ -308,7 +321,7 @@ static int
readsb(listerr) readsb(listerr)
int 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) if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
return (0); return (0);
@ -348,8 +361,8 @@ readsb(listerr)
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
if (asblk.b_errs) if (asblk.b_errs)
return (0); return (0);
altsblock.fs_link = sblock.fs_link; altsblock.fs_firstfield = sblock.fs_firstfield;
altsblock.fs_rlink = sblock.fs_rlink; altsblock.fs_unused_1 = sblock.fs_unused_1;
altsblock.fs_time = sblock.fs_time; altsblock.fs_time = sblock.fs_time;
altsblock.fs_cstotal = sblock.fs_cstotal; altsblock.fs_cstotal = sblock.fs_cstotal;
altsblock.fs_cgrotor = sblock.fs_cgrotor; altsblock.fs_cgrotor = sblock.fs_cgrotor;
@ -362,12 +375,11 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim; altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay; altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg; altsblock.fs_maxbpg = sblock.fs_maxbpg;
bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
sizeof sblock.fs_csp); altsblock.fs_maxcluster = sblock.fs_maxcluster;
bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
sizeof sblock.fs_fsmnt); memmove(altsblock.fs_sparecon,
bcopy((char *)sblock.fs_sparecon, (char *)altsblock.fs_sparecon, sblock.fs_sparecon, sizeof sblock.fs_sparecon);
sizeof sblock.fs_sparecon);
/* /*
* The following should not have to be copied. * The following should not have to be copied.
*/ */
@ -375,11 +387,26 @@ readsb(listerr)
altsblock.fs_interleave = sblock.fs_interleave; altsblock.fs_interleave = sblock.fs_interleave;
altsblock.fs_npsect = sblock.fs_npsect; altsblock.fs_npsect = sblock.fs_npsect;
altsblock.fs_nrpos = sblock.fs_nrpos; altsblock.fs_nrpos = sblock.fs_nrpos;
altsblock.fs_state = sblock.fs_state;
altsblock.fs_qbmask = sblock.fs_qbmask; altsblock.fs_qbmask = sblock.fs_qbmask;
altsblock.fs_qfmask = sblock.fs_qfmask; altsblock.fs_qfmask = sblock.fs_qfmask;
altsblock.fs_state = sblock.fs_state; altsblock.fs_state = sblock.fs_state;
altsblock.fs_maxfilesize = sblock.fs_maxfilesize; 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, badsb(listerr,
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0); return (0);
@ -407,7 +434,7 @@ badsb(listerr, s)
* can be used. Do NOT attempt to use other macros without verifying that * can be used. Do NOT attempt to use other macros without verifying that
* their needed information is available! * their needed information is available!
*/ */
int static int
calcsb(dev, devfd, fs) calcsb(dev, devfd, fs)
char *dev; char *dev;
int devfd; int devfd;
@ -418,7 +445,7 @@ calcsb(dev, devfd, fs)
register char *cp; register char *cp;
int i; int i;
cp = index(dev, '\0') - 1; cp = strchr(dev, '\0') - 1;
if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) { if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0); return (0);
@ -434,7 +461,7 @@ calcsb(dev, devfd, fs)
fstypenames[pp->p_fstype] : "unknown"); fstypenames[pp->p_fstype] : "unknown");
return (0); return (0);
} }
bzero((char *)fs, sizeof(struct fs)); memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize; fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag; fs->fs_frag = pp->p_frag;
fs->fs_cpg = pp->p_cpg; fs->fs_cpg = pp->p_cpg;
@ -461,7 +488,7 @@ calcsb(dev, devfd, fs)
return (1); return (1);
} }
struct disklabel * static struct disklabel *
getdisklabel(s, fd) getdisklabel(s, fd)
char *s; char *s;
int fd; int fd;
@ -472,7 +499,7 @@ getdisklabel(s, fd)
if (s == NULL) if (s == NULL)
return ((struct disklabel *)NULL); return ((struct disklabel *)NULL);
pwarn("ioctl (GCINFO): %s\n", strerror(errno)); 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); return (&lab);
} }

View File

@ -32,11 +32,12 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.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 <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <err.h>
#include "fsck.h" #include "fsck.h"
long diskreads, totalreads; /* Disk cache statistics */ 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 int
ftypeok(dp) ftypeok(dp)
@ -119,7 +123,7 @@ bufinit()
pbp = pdirbp = (struct bufarea *)0; pbp = pdirbp = (struct bufarea *)0;
bufp = malloc((unsigned int)sblock.fs_bsize); bufp = malloc((unsigned int)sblock.fs_bsize);
if (bufp == 0) if (bufp == 0)
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
cgblk.b_un.b_buf = bufp; cgblk.b_un.b_buf = bufp;
initbarea(&cgblk); initbarea(&cgblk);
bufhead.b_next = bufhead.b_prev = &bufhead; bufhead.b_next = bufhead.b_prev = &bufhead;
@ -132,7 +136,7 @@ bufinit()
if (bp == NULL || bufp == NULL) { if (bp == NULL || bufp == NULL) {
if (i >= MINBUFS) if (i >= MINBUFS)
break; break;
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
} }
bp->b_un.b_buf = bufp; bp->b_un.b_buf = bufp;
bp->b_prev = &bufhead; bp->b_prev = &bufhead;
@ -149,7 +153,7 @@ bufinit()
*/ */
struct bufarea * struct bufarea *
getdatablk(blkno, size) getdatablk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {
register struct bufarea *bp; register struct bufarea *bp;
@ -161,7 +165,7 @@ getdatablk(blkno, size)
if ((bp->b_flags & B_INUSE) == 0) if ((bp->b_flags & B_INUSE) == 0)
break; break;
if (bp == &bufhead) if (bp == &bufhead)
errexit("deadlocked buffer pool\n"); errx(EEXIT, "deadlocked buffer pool");
getblk(bp, blkno, size); getblk(bp, blkno, size);
/* fall through */ /* fall through */
foundit: foundit:
@ -179,10 +183,10 @@ getdatablk(blkno, size)
void void
getblk(bp, blk, size) getblk(bp, blk, size)
register struct bufarea *bp; register struct bufarea *bp;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
daddr_t dblk; ufs_daddr_t dblk;
dblk = fsbtodb(&sblock, blk); dblk = fsbtodb(&sblock, blk);
if (bp->b_bno != dblk) { if (bp->b_bno != dblk) {
@ -220,24 +224,25 @@ flush(fd, bp)
} }
} }
void static void
rwerror(mesg, blk) rwerror(mesg, blk)
char *mesg; char *mesg;
daddr_t blk; ufs_daddr_t blk;
{ {
if (preen == 0) if (preen == 0)
printf("\n"); printf("\n");
pfatal("CANNOT %s: BLK %ld", mesg, blk); pfatal("CANNOT %s: BLK %ld", mesg, blk);
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit("Program terminated\n"); exit(EEXIT);
} }
void void
ckfini() ckfini(markclean)
int markclean;
{ {
register struct bufarea *bp, *nbp; register struct bufarea *bp, *nbp;
int cnt = 0; int ofsmodified, cnt = 0;
if (fswritefd < 0) { if (fswritefd < 0) {
(void)close(fsreadfd); (void)close(fsreadfd);
@ -260,8 +265,17 @@ ckfini()
free((char *)bp); free((char *)bp);
} }
if (bufhead.b_size != cnt) 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; 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) if (debug)
printf("cache missed %ld of %ld (%d%%)\n", diskreads, printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads)); totalreads, (int)(diskreads * 100 / totalreads));
@ -273,7 +287,7 @@ int
bread(fd, buf, blk, size) bread(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
char *cp; char *cp;
@ -290,7 +304,7 @@ bread(fd, buf, blk, size)
if (lseek(fd, offset, 0) < 0) if (lseek(fd, offset, 0) < 0)
rwerror("SEEK", blk); rwerror("SEEK", blk);
errs = 0; errs = 0;
bzero(buf, (size_t)size); memset(buf, 0, (size_t)size);
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
if (read(fd, cp, (int)secsize) != secsize) { if (read(fd, cp, (int)secsize) != secsize) {
@ -312,7 +326,7 @@ void
bwrite(fd, buf, blk, size) bwrite(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
int i; int i;
@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size)
/* /*
* allocate a data block with the specified number of fragments * allocate a data block with the specified number of fragments
*/ */
int ufs_daddr_t
allocblk(frags) allocblk(frags)
long frags; long frags;
{ {
@ -378,7 +392,7 @@ allocblk(frags)
*/ */
void void
freeblk(blkno, frags) freeblk(blkno, frags)
daddr_t blkno; ufs_daddr_t blkno;
long frags; long frags;
{ {
struct inodesc idesc; struct inodesc idesc;
@ -411,7 +425,7 @@ getpathname(namebuf, curdir, ino)
return; return;
} }
busy = 1; busy = 1;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_fix = IGNORE; idesc.id_fix = IGNORE;
cp = &namebuf[MAXPATHLEN - 1]; cp = &namebuf[MAXPATHLEN - 1];
@ -435,7 +449,7 @@ getpathname(namebuf, curdir, ino)
break; break;
len = strlen(namebuf); len = strlen(namebuf);
cp -= len; cp -= len;
bcopy(namebuf, cp, (size_t)len); memmove(cp, namebuf, (size_t)len);
*--cp = '/'; *--cp = '/';
if (cp < &namebuf[MAXNAMLEN]) if (cp < &namebuf[MAXNAMLEN])
break; break;
@ -444,15 +458,15 @@ getpathname(namebuf, curdir, ino)
busy = 0; busy = 0;
if (ino != ROOTINO) if (ino != ROOTINO)
*--cp = '?'; *--cp = '?';
bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp)); memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp));
} }
void void
catch(x) catch(sig)
int x; int sig;
{ {
if (!doinglevel2) if (!doinglevel2)
ckfini(); ckfini(0);
exit(12); exit(12);
} }
@ -462,8 +476,8 @@ catch(x)
* so that reboot sequence may be interrupted. * so that reboot sequence may be interrupted.
*/ */
void void
catchquit(x) catchquit(sig)
int x; int sig;
{ {
printf("returning to single-user after filesystem check\n"); printf("returning to single-user after filesystem check\n");
returntosingle = 1; returntosingle = 1;
@ -475,8 +489,8 @@ catchquit(x)
* Used by child processes in preen. * Used by child processes in preen.
*/ */
void void
voidquit(x) voidquit(sig)
int x; int sig;
{ {
sleep(1); sleep(1);
@ -520,76 +534,95 @@ dofix(idesc, msg)
return (0); return (0);
default: default:
errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix);
return (0);
} }
/* NOTREACHED */ /* NOTREACHED */
return (0);
} }
/* VARARGS1 */ #if __STDC__
void #include <stdarg.h>
errexit(const char *s1, ...) #else
{ #include <varargs.h>
va_list ap; #endif
va_start(ap,s1);
vfprintf(stdout, s1, ap);
va_end(ap);
exit(8);
}
/* /*
* An unexpected inconsistency occured. * An unexpected inconsistency occured.
* Die if preening, otherwise just print message and continue. * Die if preening, otherwise just print message and continue.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
if (preen) { va_start(ap, fmt);
printf("%s: ", cdevname); #else
vfprintf(stdout, s, ap); va_start(ap);
printf("\n"); #endif
printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", if (!preen) {
cdevname); (void)vfprintf(stderr, fmt, ap);
exit(8); va_end(ap);
return;
} }
vfprintf(stdout, s, ap); (void)fprintf(stderr, "%s: ", cdevname);
va_end(ap); (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, * Pwarn just prints a message when not preening,
* or a warning (preceded by filename) when preening. * or a warning (preceded by filename) when preening.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
if (preen) if (preen)
printf("%s: ", cdevname); (void)fprintf(stderr, "%s: ", cdevname);
vfprintf(stdout, s, ap); (void)vfprintf(stderr, fmt, ap);
va_end(ap); va_end(ap);
} }
#ifndef lint
/* /*
* Stub for routines from kernel. * Stub for routines from kernel.
*/ */
void void
#ifdef __STDC__ #if __STDC__
panic(const char *fmt, ...) panic(const char *fmt, ...)
#else #else
panic(fmt, va_alist) panic(fmt, va_alist)
char *fmt; char *fmt;
va_dcl
#endif #endif
{ {
va_list ap;
pfatal("INTERNAL INCONSISTENCY:"); #if __STDC__
errexit(fmt); va_start(ap, fmt);
} #else
va_start(ap);
#endif #endif
pfatal("INTERNAL INCONSISTENCY:");
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
exit(EEXIT);
}

View File

@ -1,9 +1,10 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93 # @(#)Makefile 8.2 (Berkeley) 4/27/95
PROG= fsck PROG= fsck
MAN8= fsck.8 MAN8= fsck.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ 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 pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
CFLAGS+=-W
.PATH: ${.CURDIR}/../../sys/ufs/ffs .PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -32,17 +32,20 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
char *lfname = "lost+found"; char *lfname = "lost+found";
@ -57,15 +60,14 @@ struct odirtemplate odirhead = {
0, DIRBLKSIZ - 12, 2, ".." 0, DIRBLKSIZ - 12, 2, ".."
}; };
static int chgino __P((struct inodesc *));
static int chgino __P((struct inodesc *idesc)); static int dircheck __P((struct inodesc *, struct direct *));
static int dircheck __P((struct inodesc *idesc, struct direct *dp)); static int expanddir __P((struct dinode *dp, char *name));
static int expanddir __P((struct dinode *dp, char *name)); static void freedir __P((ino_t ino, ino_t parent));
static void freedir __P((ino_t ino, ino_t parent)); static struct direct *fsck_readdir __P((struct inodesc *));
static struct direct * fsck_readdir __P((struct inodesc *idesc)); static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
static struct bufarea * getdirblk __P((daddr_t blkno, long size)); static int lftempname __P((char *bufp, ino_t ino));
static int lftempname __P((char *bufp, ino_t ino)); static int mkentry __P((struct inodesc *));
static int mkentry __P((struct inodesc *idesc));
/* /*
* Propagate connected state through the tree. * Propagate connected state through the tree.
@ -107,7 +109,7 @@ dirscan(idesc)
char dbuf[DIRBLKSIZ]; char dbuf[DIRBLKSIZ];
if (idesc->id_type != DATA) 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 && if (idesc->id_entryno == 0 &&
(idesc->id_filesize & (DIRBLKSIZ - 1)) != 0) (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ); idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
@ -119,7 +121,7 @@ dirscan(idesc)
idesc->id_loc = 0; idesc->id_loc = 0;
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
dsize = dp->d_reclen; dsize = dp->d_reclen;
bcopy((char *)dp, dbuf, (size_t)dsize); memmove(dbuf, dp, (size_t)dsize);
# if (BYTE_ORDER == LITTLE_ENDIAN) # if (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
struct direct *tdp = (struct direct *)dbuf; struct direct *tdp = (struct direct *)dbuf;
@ -144,7 +146,7 @@ dirscan(idesc)
} }
# endif # endif
bp = getdirblk(idesc->id_blkno, blksiz); 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); (size_t)dsize);
dirty(bp); dirty(bp);
sbdirty(); sbdirty();
@ -158,7 +160,7 @@ dirscan(idesc)
/* /*
* get next entry in a directory. * get next entry in a directory.
*/ */
struct direct * static struct direct *
fsck_readdir(idesc) fsck_readdir(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
@ -173,6 +175,8 @@ fsck_readdir(idesc)
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (dircheck(idesc, dp)) if (dircheck(idesc, dp))
goto dpok; goto dpok;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
@ -202,6 +206,8 @@ fsck_readdir(idesc)
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
idesc->id_loc += size; idesc->id_loc += size;
idesc->id_filesize -= size; idesc->id_filesize -= size;
if (idesc->id_fix == IGNORE)
return (0);
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + dploc); dp = (struct direct *)(bp->b_un.b_buf + dploc);
@ -216,7 +222,7 @@ fsck_readdir(idesc)
* Verify that a directory entry is valid. * Verify that a directory entry is valid.
* This is a superset of the checks made in the kernel. * This is a superset of the checks made in the kernel.
*/ */
int static int
dircheck(idesc, dp) dircheck(idesc, dp)
struct inodesc *idesc; struct inodesc *idesc;
register struct direct *dp; register struct direct *dp;
@ -226,8 +232,15 @@ dircheck(idesc, dp)
u_char namlen, type; u_char namlen, type;
int spaceleft; int spaceleft;
size = DIRSIZ(!newinofmt, dp);
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 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 (BYTE_ORDER == LITTLE_ENDIAN)
if (!newinofmt) { if (!newinofmt) {
type = dp->d_namlen; type = dp->d_namlen;
@ -240,23 +253,17 @@ dircheck(idesc, dp)
namlen = dp->d_namlen; namlen = dp->d_namlen;
type = dp->d_type; type = dp->d_type;
# endif # endif
if (dp->d_ino < maxino && if (dp->d_reclen < size ||
dp->d_reclen != 0 && idesc->id_filesize < size ||
dp->d_reclen <= spaceleft && namlen > MAXNAMLEN ||
(dp->d_reclen & 0x3) == 0 && type > 15)
dp->d_reclen >= size && return (0);
idesc->id_filesize >= size && for (cp = dp->d_name, size = 0; size < namlen; size++)
namlen <= MAXNAMLEN && if (*cp == '\0' || (*cp++ == '/'))
type <= 15) { return (0);
if (dp->d_ino == 0) if (*cp != '\0')
return (1); return (0);
for (cp = dp->d_name, size = 0; size < namlen; size++) return (1);
if (*cp == 0 || (*cp++ == '/'))
return (0);
if (*cp == 0)
return (1);
}
return (0);
} }
void void
@ -295,7 +302,7 @@ fileerror(cwd, ino, errmesg)
void void
adjust(idesc, lcnt) adjust(idesc, lcnt)
register struct inodesc *idesc; register struct inodesc *idesc;
short lcnt; int lcnt;
{ {
register struct dinode *dp; register struct dinode *dp;
@ -323,7 +330,7 @@ adjust(idesc, lcnt)
} }
} }
int static int
mkentry(idesc) mkentry(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -343,30 +350,38 @@ mkentry(idesc)
dirp->d_reclen = oldlen; dirp->d_reclen = oldlen;
dirp = (struct direct *)(((char *)dirp) + oldlen); dirp = (struct direct *)(((char *)dirp) + oldlen);
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ 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; 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); return (ALTERED|STOP);
} }
int static int
chgino(idesc) chgino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
register struct direct *dirp = idesc->id_dirp; 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); return (KEEPON);
dirp->d_ino = idesc->id_parent; dirp->d_ino = idesc->id_parent;
if (newinofmt) if (newinofmt)
@ -387,7 +402,7 @@ linkup(orphan, parentdir)
struct inodesc idesc; struct inodesc idesc;
char tempname[BUFSIZ]; char tempname[BUFSIZ];
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
dp = ginode(orphan); dp = ginode(orphan);
lostdir = (dp->di_mode & IFMT) == IFDIR; lostdir = (dp->di_mode & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
@ -501,7 +516,7 @@ changeino(dir, name, newnum)
{ {
struct inodesc idesc; struct inodesc idesc;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = chgino; idesc.id_func = chgino;
idesc.id_number = dir; idesc.id_number = dir;
@ -526,7 +541,7 @@ makeentry(parent, ino, name)
if (parent < ROOTINO || parent >= maxino || if (parent < ROOTINO || parent >= maxino ||
ino < ROOTINO || ino >= maxino) ino < ROOTINO || ino >= maxino)
return (0); return (0);
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_func = mkentry; idesc.id_func = mkentry;
idesc.id_number = parent; idesc.id_number = parent;
@ -550,12 +565,12 @@ makeentry(parent, ino, name)
/* /*
* Attempt to expand the size of a directory * Attempt to expand the size of a directory
*/ */
int static int
expanddir(dp, name) expanddir(dp, name)
register struct dinode *dp; register struct dinode *dp;
char *name; char *name;
{ {
daddr_t lastbn, newblk; ufs_daddr_t lastbn, newblk;
register struct bufarea *bp; register struct bufarea *bp;
char *cp, firstblk[DIRBLKSIZ]; char *cp, firstblk[DIRBLKSIZ];
@ -572,21 +587,21 @@ expanddir(dp, name)
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ); memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
bp = getdirblk(newblk, sblock.fs_bsize); bp = getdirblk(newblk, sblock.fs_bsize);
if (bp->b_errs) if (bp->b_errs)
goto bad; 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_bsize]; cp < &bp->b_un.b_buf[sblock.fs_bsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
bp = getdirblk(dp->di_db[lastbn + 1], bp = getdirblk(dp->di_db[lastbn + 1],
(long)dblksize(&sblock, dp, lastbn + 1)); (long)dblksize(&sblock, dp, lastbn + 1));
if (bp->b_errs) if (bp->b_errs)
goto bad; 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); pwarn("NO SPACE LEFT IN %s", name);
if (preen) if (preen)
printf(" (EXPANDED)\n"); printf(" (EXPANDED)\n");
@ -631,11 +646,11 @@ allocdir(parent, request, mode)
freeino(ino); freeino(ino);
return (0); 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]; for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
cp < &bp->b_un.b_buf[sblock.fs_fsize]; cp < &bp->b_un.b_buf[sblock.fs_fsize];
cp += DIRBLKSIZ) cp += DIRBLKSIZ)
bcopy((char *)&emptydir, cp, sizeof emptydir); memmove(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
dp->di_nlink = 2; dp->di_nlink = 2;
inodirty(); inodirty();
@ -680,7 +695,7 @@ freedir(ino, parent)
/* /*
* generate a temporary name for the lost+found directory. * generate a temporary name for the lost+found directory.
*/ */
int static int
lftempname(bufp, ino) lftempname(bufp, ino)
char *bufp; char *bufp;
ino_t ino; ino_t ino;
@ -707,9 +722,9 @@ lftempname(bufp, ino)
* Get a directory block. * Get a directory block.
* Insure that it is held until another is requested. * Insure that it is held until another is requested.
*/ */
struct bufarea * static struct bufarea *
getdirblk(blkno, size) getdirblk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {

View File

@ -30,9 +30,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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 MAXDUP 10 /* limit on dup blks (per inode) */
#define MAXBAD 10 /* limit on bad blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
@ -53,20 +57,20 @@
* buffer cache structure. * buffer cache structure.
*/ */
struct bufarea { struct bufarea {
struct bufarea *b_next; /* free list queue */ struct bufarea *b_next; /* free list queue */
struct bufarea *b_prev; /* free list queue */ struct bufarea *b_prev; /* free list queue */
daddr_t b_bno; ufs_daddr_t b_bno;
int b_size; int b_size;
int b_errs; int b_errs;
int b_flags; int b_flags;
union { union {
char *b_buf; /* buffer space */ char *b_buf; /* buffer space */
daddr_t *b_indir; /* indirect block */ ufs_daddr_t *b_indir; /* indirect block */
struct fs *b_fs; /* super block */ struct fs *b_fs; /* super block */
struct cg *b_cg; /* cylinder group */ struct cg *b_cg; /* cylinder group */
struct dinode *b_dinode; /* inode block */ struct dinode *b_dinode; /* inode block */
} b_un; } b_un;
char b_dirty; char b_dirty;
}; };
#define B_INUSE 1 #define B_INUSE 1
@ -77,12 +81,11 @@ struct bufarea sblk; /* file system superblock */
struct bufarea cgblk; /* cylinder group blocks */ struct bufarea cgblk; /* cylinder group blocks */
struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */ struct bufarea *pbp; /* current inode block */
struct bufarea *getdatablk();
#define dirty(bp) (bp)->b_dirty = 1 #define dirty(bp) (bp)->b_dirty = 1
#define initbarea(bp) \ #define initbarea(bp) \
(bp)->b_dirty = 0; \ (bp)->b_dirty = 0; \
(bp)->b_bno = (daddr_t)-1; \ (bp)->b_bno = (ufs_daddr_t)-1; \
(bp)->b_flags = 0; (bp)->b_flags = 0;
#define sbdirty() sblk.b_dirty = 1 #define sbdirty() sblk.b_dirty = 1
@ -97,7 +100,7 @@ struct inodesc {
int (*id_func)(); /* function to be applied to blocks of inode */ int (*id_func)(); /* function to be applied to blocks of inode */
ino_t id_number; /* inode number described */ ino_t id_number; /* inode number described */
ino_t id_parent; /* for DATA nodes, their parent */ 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 */ int id_numfrags; /* number of frags contained in block */
quad_t id_filesize; /* for DATA nodes, the size of the directory */ quad_t id_filesize; /* for DATA nodes, the size of the directory */
int id_loc; /* for DATA nodes, current location in dir */ int id_loc; /* for DATA nodes, current location in dir */
@ -133,7 +136,7 @@ struct inodesc {
*/ */
struct dups { struct dups {
struct dups *next; struct dups *next;
daddr_t dup; ufs_daddr_t dup;
}; };
struct dups *duplist; /* head of dup list */ struct dups *duplist; /* head of dup list */
struct dups *muldup; /* end of unique duplicate dup block numbers */ struct dups *muldup; /* end of unique duplicate dup block numbers */
@ -157,7 +160,7 @@ struct inoinfo {
ino_t i_dotdot; /* inode number of `..' */ ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */ size_t i_isize; /* size of inode */
u_int i_numblks; /* size of block array in bytes */ 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; } **inphead, **inpsort;
long numdirs, listmax, inplast; long numdirs, listmax, inplast;
@ -182,20 +185,20 @@ int fswritefd; /* file descriptor for writing file system */
int returntosingle; /* return to single user mode */ int returntosingle; /* return to single user mode */
int rerun; /* rerun fsck. Only used in non-preen 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 */ char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in file system */ ino_t maxino; /* number of inodes in file system */
ino_t lastino; /* last inode in use */ ino_t lastino; /* last inode in use */
char *statemap; /* ptr to inode state table */ 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 */ short *lncntp; /* ptr to link count table */
ino_t lfdir; /* lost & found directory inode number */ ino_t lfdir; /* lost & found directory inode number */
char *lfname; /* lost & found directory name */ char *lfname; /* lost & found directory name */
int lfmode; /* lost & found directory creation mode */ int lfmode; /* lost & found directory creation mode */
daddr_t n_blks; /* number of blocks in use */ ufs_daddr_t n_blks; /* number of blocks in use */
daddr_t n_files; /* number of files in use */ ufs_daddr_t n_files; /* number of files in use */
#define clearinode(dp) (*(dp) = zino) #define clearinode(dp) (*(dp) = zino)
struct dinode zino; struct dinode zino;
@ -210,84 +213,69 @@ struct dinode zino;
#define ALTERED 0x08 #define ALTERED 0x08
#define FOUND 0x10 #define FOUND 0x10
/* dir.c */ #define EEXIT 8 /* Standard error exit. */
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 */ struct fstab;
void ffs_fragacct __P((struct fs *fs, int fragmap, long *fraglist, int cnt));
/* inode.c */ void adjust __P((struct inodesc *, int lcnt));
ino_t allocino __P((ino_t request, int type)); ufs_daddr_t allocblk __P((long frags));
void blkerror __P((ino_t ino, char *type, daddr_t blk)); ino_t allocdir __P((ino_t parent, ino_t request, int mode));
void cacheino __P((struct dinode *dp, ino_t inumber)); ino_t allocino __P((ino_t request, int type));
int chkrange __P((daddr_t blk, int cnt)); void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
int ckinode __P((struct dinode *dp, struct inodesc *idesc)); char *blockcheck __P((char *name));
void clri __P((struct inodesc *idesc, char *type, int flag)); int bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
int findino __P((struct inodesc *idesc)); void bufinit __P((void));
void freeino __P((ino_t ino)); void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
void freeinodebuf __P((void)); void cacheino __P((struct dinode *dp, ino_t inumber));
struct dinode * ginode __P((ino_t inumber)); void catch __P((int));
struct inoinfo * getinoinfo __P((ino_t inumber)); void catchquit __P((int));
struct dinode * getnextinode __P((ino_t inumber)); int changeino __P((ino_t dir, char *name, ino_t newnum));
void inodirty __P((void)); int checkfstab __P((int preen, int maxrun,
void inocleanup __P((void)); int (*docheck)(struct fstab *),
void pinode __P((ino_t ino)); int (*chkit)(char *, char *, long, int)));
void resetinodebuf __P((void)); int chkrange __P((ufs_daddr_t blk, int cnt));
int findname __P((struct inodesc *idesc)); void ckfini __P((int markclean));
int ckinode __P((struct dinode *dp, struct inodesc *));
/* pass1.c */ void clri __P((struct inodesc *, char *type, int flag));
void pass1 __P((void)); void direrror __P((ino_t ino, char *errmesg));
int pass1check __P((struct inodesc *idesc)); int dirscan __P((struct inodesc *));
int dofix __P((struct inodesc *, char *msg));
/* pass1b.c */ void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass1b __P((void)); void ffs_fragacct __P((struct fs *, int, int32_t [], int));
int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
/* pass2.c */ void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
void pass2 __P((void)); void fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
int findino __P((struct inodesc *));
/* pass3.c */ int findname __P((struct inodesc *));
void pass3 __P((void)); void flush __P((int fd, struct bufarea *bp));
void freeblk __P((ufs_daddr_t blkno, long frags));
/* pass4.c */ void freeino __P((ino_t ino));
void pass4 __P((void)); void freeinodebuf __P((void));
int pass4check __P((struct inodesc *idesc)); int ftypeok __P((struct dinode *dp));
void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
/* pass5.c */ struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
void pass5 __P((void)); struct inoinfo *getinoinfo __P((ino_t inumber));
struct dinode *getnextinode __P((ino_t inumber));
/* preen.c */ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
char *blockcheck __P((char *name)); struct dinode *ginode __P((ino_t inumber));
int checkfstab __P((int preen, int maxrun,int (*docheck)(), int (*chkit)())); void inocleanup __P((void));
void inodirty __P((void));
/* setup.c */ int linkup __P((ino_t orphan, ino_t parentdir));
int setup __P((char *dev)); int makeentry __P((ino_t parent, ino_t ino, char *name));
void panic __P((const char *fmt, ...));
/* utilities.c */ void pass1 __P((void));
int allocblk __P((long frags)); void pass1b __P((void));
int bread __P((int fd, char *buf, daddr_t blk, long size)); int pass1check __P((struct inodesc *));
void bufinit __P((void)); void pass2 __P((void));
void bwrite __P((int fd, char *buf, daddr_t blk, long size)); void pass3 __P((void));
void catch __P((int)); void pass4 __P((void));
void catchquit __P((int)); int pass4check __P((struct inodesc *));
void ckfini __P((void)); void pass5 __P((void));
int dofix __P((struct inodesc *idesc, char *msg)); void pfatal __P((const char *fmt, ...));
void errexit __P((const char *s1, ...)) __dead2; void pinode __P((ino_t ino));
void flush __P((int fd, struct bufarea *bp)); void propagate __P((void));
void freeblk __P((daddr_t blkno, long frags)); void pwarn __P((const char *fmt, ...));
int ftypeok __P((struct dinode *dp)); int reply __P((char *question));
void getblk __P((struct bufarea *bp, daddr_t blk, long size)); void resetinodebuf __P((void));
struct bufarea * getdatablk __P((daddr_t blkno, long size)); int setup __P((char *dev));
void getpathname __P((char *namebuf, ino_t curdir, ino_t ino)); void voidquit __P((int));
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));

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93 .\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id$ .|' $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 .Dt FSCK 8
.Os BSD 4 .Os BSD 4
.Sh NAME .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. to be the partition designator.
.Pp .Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that 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 .Fl f
option is specified, the filesystems option is specified, the filesystems
will be checked regardless of the state of their clean flag. 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. Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised. Note that the level of a filesystem can only be raised.
.Bl -tag -width indent .Bl -tag -width indent
There are currently three levels defined: There are currently four levels defined:
.It 0 .It 0
The filesystem is in the old (static table) format. The filesystem is in the old (static table) format.
.It 1 .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, The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode, short symbolic links are stored in the inode,
and directories have an added field showing the file type. 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 .El
.Pp .Pp
In interactive mode, In interactive mode,

View File

@ -32,32 +32,35 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <err.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static ino_t startinum; 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 int
ckinode(dp, idesc) ckinode(dp, idesc)
struct dinode *dp; struct dinode *dp;
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
int ret; long ret, n, ndb, offset;
long n, ndb, offset;
struct dinode dino; struct dinode dino;
quad_t remsize, sizepb; quad_t remsize, sizepb;
mode_t mode; mode_t mode;
@ -147,9 +150,9 @@ iblock(idesc, ilevel, isize)
long ilevel; long ilevel;
quad_t isize; quad_t isize;
{ {
register daddr_t *ap; ufs_daddr_t *ap;
register daddr_t *aplim; ufs_daddr_t *aplim;
register struct bufarea *bp; struct bufarea *bp;
int i, n, (*func)(), nif; int i, n, (*func)(), nif;
quad_t sizepb; quad_t sizepb;
char buf[BUFSIZ]; char buf[BUFSIZ];
@ -229,7 +232,7 @@ iblock(idesc, ilevel, isize)
*/ */
int int
chkrange(blk, cnt) chkrange(blk, cnt)
daddr_t blk; ufs_daddr_t blk;
int cnt; int cnt;
{ {
register int c; register int c;
@ -268,10 +271,10 @@ struct dinode *
ginode(inumber) ginode(inumber)
ino_t inumber; ino_t inumber;
{ {
daddr_t iblk; ufs_daddr_t iblk;
if (inumber < ROOTINO || inumber > maxino) 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 || if (startinum == 0 ||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) { inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
iblk = ino_to_fsba(&sblock, inumber); iblk = ino_to_fsba(&sblock, inumber);
@ -296,11 +299,11 @@ getnextinode(inumber)
ino_t inumber; ino_t inumber;
{ {
long size; long size;
daddr_t dblk; ufs_daddr_t dblk;
static struct dinode *dp; static struct dinode *dp;
if (inumber != nextino++ || inumber > maxino) 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) { if (inumber >= lastinum) {
readcnt++; readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
@ -338,7 +341,7 @@ resetinodebuf()
} }
if (inodebuf == NULL && if (inodebuf == NULL &&
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == 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) while (nextino < ROOTINO)
(void)getnextinode(nextino); (void)getnextinode(nextino);
} }
@ -372,7 +375,7 @@ cacheino(dp, inumber)
if (blks > NDADDR) if (blks > NDADDR)
blks = NDADDR + NIADDR; blks = NDADDR + NIADDR;
inp = (struct inoinfo *) inp = (struct inoinfo *)
malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t)); malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
if (inp == NULL) if (inp == NULL)
return; return;
inpp = &inphead[inumber % numdirs]; inpp = &inphead[inumber % numdirs];
@ -385,15 +388,14 @@ cacheino(dp, inumber)
inp->i_dotdot = (ino_t)0; inp->i_dotdot = (ino_t)0;
inp->i_number = inumber; inp->i_number = inumber;
inp->i_isize = dp->di_size; inp->i_isize = dp->di_size;
inp->i_numblks = blks * sizeof(daddr_t); inp->i_numblks = blks * sizeof(ufs_daddr_t);
bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0], memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
if (inplast == listmax) { if (inplast == listmax) {
listmax += 100; listmax += 100;
inpsort = (struct inoinfo **)realloc((char *)inpsort, inpsort = (struct inoinfo **)realloc((char *)inpsort,
(unsigned)listmax * sizeof(struct inoinfo *)); (unsigned)listmax * sizeof(struct inoinfo *));
if (inpsort == NULL) if (inpsort == NULL)
errexit("cannot increase directory list"); errx(EEXIT, "cannot increase directory list");
} }
inpsort[inplast++] = inp; inpsort[inplast++] = inp;
} }
@ -412,7 +414,7 @@ getinoinfo(inumber)
continue; continue;
return (inp); return (inp);
} }
errexit("cannot find inode %d\n", inumber); errx(EEXIT, "cannot find inode %d", inumber);
return ((struct inoinfo *)0); return ((struct inoinfo *)0);
} }
@ -472,7 +474,7 @@ findname(idesc)
if (dirp->d_ino != idesc->id_parent) if (dirp->d_ino != idesc->id_parent)
return (KEEPON); 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); return (STOP|FOUND);
} }
@ -514,7 +516,7 @@ pinode(ino)
if (preen) if (preen)
printf("%s: ", cdevname); printf("%s: ", cdevname);
printf("SIZE=%qu ", dp->di_size); 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]); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
} }
@ -522,7 +524,7 @@ void
blkerror(ino, type, blk) blkerror(ino, type, blk)
ino_t ino; ino_t ino;
char *type; char *type;
daddr_t blk; ufs_daddr_t blk;
{ {
pfatal("%ld %s I=%lu", blk, type, ino); pfatal("%ld %s I=%lu", blk, type, ino);
@ -542,7 +544,7 @@ blkerror(ino, type, blk)
return; return;
default: default:
errexit("BAD STATE %d TO BLKERR", statemap[ino]); errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@ -585,7 +587,7 @@ allocino(request, type)
return (0); return (0);
} }
dp->di_mode = type; 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_mtime = dp->di_ctime = dp->di_atime;
dp->di_size = sblock.fs_fsize; dp->di_size = sblock.fs_fsize;
dp->di_blocks = btodb(sblock.fs_fsize); dp->di_blocks = btodb(sblock.fs_fsize);
@ -606,7 +608,7 @@ freeino(ino)
struct inodesc idesc; struct inodesc idesc;
struct dinode *dp; struct dinode *dp;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
idesc.id_number = ino; idesc.id_number = ino;

View File

@ -38,25 +38,35 @@ static const char copyright[] =
#endif /* not lint */ #endif /* not lint */
#ifndef 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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <ctype.h>
#include <err.h>
#include <fstab.h> #include <fstab.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "fsck.h" #include "fsck.h"
static int argtoi __P((int flag, char *req, char *str, int base));
static int docheck __P((struct fstab *fsp)); int returntosingle;
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
int child)); 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 int
main(argc, argv) main(argc, argv)
@ -99,7 +109,7 @@ main(argc, argv)
case 'm': case 'm':
lfmode = argtoi('m', "mode", optarg, 8); lfmode = argtoi('m', "mode", optarg, 8);
if (lfmode &~ 07777) 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); printf("** lost+found creation mode %o\n", lfmode);
break; break;
@ -116,7 +126,7 @@ main(argc, argv)
break; break;
default: default:
errexit("%c option?\n", ch); errx(EEXIT, "%c option?", ch);
} }
} }
argc -= optind; argc -= optind;
@ -136,7 +146,7 @@ main(argc, argv)
exit(ret); exit(ret);
} }
int static int
argtoi(flag, req, str, base) argtoi(flag, req, str, base)
int flag; int flag;
char *req, *str; char *req, *str;
@ -147,14 +157,14 @@ argtoi(flag, req, str, base)
ret = (int)strtol(str, &cp, base); ret = (int)strtol(str, &cp, base);
if (cp == str || *cp) if (cp == str || *cp)
errexit("-%c flag requires a %s\n", flag, req); errx(EEXIT, "-%c flag requires a %s", flag, req);
return (ret); return (ret);
} }
/* /*
* Determine whether a filesystem should be checked. * Determine whether a filesystem should be checked.
*/ */
int static int
docheck(fsp) docheck(fsp)
register struct fstab *fsp; register struct fstab *fsp;
{ {
@ -171,25 +181,28 @@ docheck(fsp)
* Check the specified filesystem. * Check the specified filesystem.
*/ */
/* ARGSUSED */ /* ARGSUSED */
int static int
checkfilesys(filesys, mntpt, auxdata, child) checkfilesys(filesys, mntpt, auxdata, child)
char *filesys, *mntpt; char *filesys, *mntpt;
long auxdata; long auxdata;
int child; int child;
{ {
daddr_t n_ffree, n_bfree; ufs_daddr_t n_ffree, n_bfree;
struct dups *dp; struct dups *dp;
struct zlncnt *zlnp; struct zlncnt *zlnp;
int cylno; int cylno, flags;
if (preen && child) if (preen && child)
(void)signal(SIGQUIT, voidquit); (void)signal(SIGQUIT, voidquit);
cdevname = filesys; cdevname = filesys;
if (debug && preen) if (debug && preen)
pwarn("starting\n"); pwarn("starting\n");
if (setup(filesys) == 0) { switch (setup(filesys)) {
case 0:
if (preen) if (preen)
pfatal("CAN'T CHECK FILE SYSTEM."); pfatal("CAN'T CHECK FILE SYSTEM.");
/* fall through */
case -1:
return (0); return (0);
} }
@ -302,7 +315,19 @@ checkfilesys(filesys, mntpt, auxdata, child)
bwrite(fswritefd, (char *)&sblock, bwrite(fswritefd, (char *)&sblock,
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); 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(blockmap);
free(statemap); free(statemap);
free((char *)lncntp); free((char *)lncntp);
@ -313,25 +338,20 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (rerun) if (rerun)
printf("\n***** PLEASE RERUN FSCK *****\n"); printf("\n***** PLEASE RERUN FSCK *****\n");
if (hotroot) { if (hotroot) {
struct statfs stfs_buf; struct ufs_args args;
int ret;
/* /*
* We modified the root. Do a mount update on * We modified the root. Do a mount update on
* it, unless it is read-write, so we can continue. * it, unless it is read-write, so we can continue.
*/ */
if (statfs("/", &stfs_buf) == 0) { if (flags & MNT_RDONLY) {
long flags = stfs_buf.f_flags; args.fspec = 0;
struct ufs_args args; args.export.ex_flags = 0;
int ret; args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
if (flags & MNT_RDONLY) { ret = mount("ufs", "/", flags, &args);
args.fspec = 0; if (ret == 0)
args.export.ex_flags = 0; return (0);
args.export.ex_root = 0;
flags |= MNT_UPDATE | MNT_RELOAD;
ret = mount(MOUNT_UFS, "/", flags, &args);
if (ret == 0)
return(0);
}
} }
if (!preen) if (!preen)
printf("\n***** REBOOT NOW *****\n"); printf("\n***** REBOOT NOW *****\n");

View File

@ -32,23 +32,27 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
static daddr_t badblk; static ufs_daddr_t badblk;
static daddr_t dupblk; 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 void
pass1() pass1()
@ -73,7 +77,7 @@ pass1()
/* /*
* Find all allocated blocks. * Find all allocated blocks.
*/ */
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1check; idesc.id_func = pass1check;
inumber = 0; inumber = 0;
@ -89,7 +93,7 @@ pass1()
freeinodebuf(); freeinodebuf();
} }
void static void
checkinode(inumber, idesc) checkinode(inumber, idesc)
ino_t inumber; ino_t inumber;
register struct inodesc *idesc; register struct inodesc *idesc;
@ -103,10 +107,10 @@ checkinode(inumber, idesc)
dp = getnextinode(inumber); dp = getnextinode(inumber);
mode = dp->di_mode & IFMT; mode = dp->di_mode & IFMT;
if (mode == 0) { if (mode == 0) {
if (bcmp((char *)dp->di_db, (char *)zino.di_db, if (memcmp(dp->di_db, zino.di_db,
NDADDR * sizeof(daddr_t)) || NDADDR * sizeof(ufs_daddr_t)) ||
bcmp((char *)dp->di_ib, (char *)zino.di_ib, memcmp(dp->di_ib, zino.di_ib,
NIADDR * sizeof(daddr_t)) || NIADDR * sizeof(ufs_daddr_t)) ||
dp->di_mode || dp->di_size) { dp->di_mode || dp->di_size) {
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
if (reply("CLEAR") == 1) { if (reply("CLEAR") == 1) {
@ -120,7 +124,8 @@ checkinode(inumber, idesc)
} }
lastino = inumber; lastino = inumber;
if (/* dp->di_size < 0 || */ 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) if (debug)
printf("bad size %qu:", dp->di_size); printf("bad size %qu:", dp->di_size);
goto unknown; goto unknown;
@ -148,15 +153,14 @@ checkinode(inumber, idesc)
if (bread(fsreadfd, symbuf, if (bread(fsreadfd, symbuf,
fsbtodb(&sblock, dp->di_db[0]), fsbtodb(&sblock, dp->di_db[0]),
(long)secsize) != 0) (long)secsize) != 0)
errexit("cannot read symlink"); errx(EEXIT, "cannot read symlink");
if (debug) { if (debug) {
symbuf[dp->di_size] = 0; symbuf[dp->di_size] = 0;
printf("convert symlink %ld(%s) of size %ld\n", printf("convert symlink %ld(%s) of size %ld\n",
inumber, symbuf, (long)dp->di_size); inumber, symbuf, (long)dp->di_size);
} }
dp = ginode(inumber); dp = ginode(inumber);
bcopy(symbuf, (caddr_t)dp->di_shortlink, memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
(long)dp->di_size);
dp->di_blocks = 0; dp->di_blocks = 0;
inodirty(); inodirty();
} }
@ -165,7 +169,7 @@ checkinode(inumber, idesc)
* will detect any garbage after symlink string. * will detect any garbage after symlink string.
*/ */
if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { 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) { if (ndb > NDADDR) {
j = ndb - NDADDR; j = ndb - NDADDR;
for (ndb = 1; j > 1; j--) for (ndb = 1; j > 1; j--)
@ -198,7 +202,7 @@ checkinode(inumber, idesc)
if (zlnp == NULL) { if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW"); pfatal("LINK COUNT TABLE OVERFLOW");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
} else { } else {
zlnp->zlncnt = inumber; zlnp->zlncnt = inumber;
zlnp->next = zlnhead; zlnp->next = zlnhead;
@ -256,7 +260,7 @@ pass1check(idesc)
{ {
int res = KEEPON; int res = KEEPON;
int anyout, nfrags; int anyout, nfrags;
daddr_t blkno = idesc->id_blkno; ufs_daddr_t blkno = idesc->id_blkno;
register struct dups *dlp; register struct dups *dlp;
struct dups *new; struct dups *new;
@ -268,7 +272,7 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
} }
@ -286,14 +290,14 @@ pass1check(idesc)
if (preen) if (preen)
printf(" (SKIPPING)\n"); printf(" (SKIPPING)\n");
else if (reply("CONTINUE") == 0) else if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new = (struct dups *)malloc(sizeof(struct dups)); new = (struct dups *)malloc(sizeof(struct dups));
if (new == NULL) { if (new == NULL) {
pfatal("DUP TABLE OVERFLOW."); pfatal("DUP TABLE OVERFLOW.");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
return (STOP); return (STOP);
} }
new->dup = blkno; new->dup = blkno;

View File

@ -32,18 +32,21 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
int pass1bcheck();
static struct dups *duphead; static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void void
pass1b() pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc; struct inodesc idesc;
ino_t inumber; ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass1bcheck; idesc.id_func = pass1bcheck;
duphead = duplist; duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
} }
} }
int static int
pass1bcheck(idesc) pass1bcheck(idesc)
register struct inodesc *idesc; register struct inodesc *idesc;
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) if (chkrange(blkno, 1))

View File

@ -32,22 +32,26 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
#define MINDIRSIZE (sizeof (struct dirtemplate)) #define MINDIRSIZE (sizeof (struct dirtemplate))
int pass2check(), blksort(); static int blksort __P((const void *, const void *));
static int pass2check __P((struct inodesc *));
void void
pass2() pass2()
@ -64,9 +68,9 @@ pass2()
case USTATE: case USTATE:
pfatal("ROOT INODE UNALLOCATED"); pfatal("ROOT INODE UNALLOCATED");
if (reply("ALLOCATE") == 0) if (reply("ALLOCATE") == 0)
errexit(""); exit(EEXIT);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
case DCLEAR: case DCLEAR:
@ -74,11 +78,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
break; break;
case FSTATE: case FSTATE:
@ -87,11 +91,11 @@ pass2()
if (reply("REALLOCATE")) { if (reply("REALLOCATE")) {
freeino(ROOTINO); freeino(ROOTINO);
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errexit("CANNOT ALLOCATE ROOT INODE\n"); errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break; break;
} }
if (reply("FIX") == 0) if (reply("FIX") == 0)
errexit(""); exit(EEXIT);
dp = ginode(ROOTINO); dp = ginode(ROOTINO);
dp->di_mode &= ~IFMT; dp->di_mode &= ~IFMT;
dp->di_mode |= IFDIR; dp->di_mode |= IFDIR;
@ -102,9 +106,13 @@ pass2()
break; break;
default: default:
errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
} }
statemap[ROOTINO] = DFOUND; statemap[ROOTINO] = DFOUND;
if (newinofmt) {
statemap[WINO] = FSTATE;
typemap[WINO] = DT_WHT;
}
/* /*
* Sort the directory list into disk block order. * Sort the directory list into disk block order.
*/ */
@ -112,7 +120,7 @@ pass2()
/* /*
* Check the integrity of each directory. * Check the integrity of each directory.
*/ */
bzero((char *)&curino, sizeof(struct inodesc)); memset(&curino, 0, sizeof(struct inodesc));
curino.id_type = DATA; curino.id_type = DATA;
curino.id_func = pass2check; curino.id_func = pass2check;
dp = &dino; dp = &dino;
@ -144,11 +152,10 @@ pass2()
dp = &dino; dp = &dino;
} }
} }
bzero((char *)&dino, sizeof(struct dinode)); memset(&dino, 0, sizeof(struct dinode));
dino.di_mode = IFDIR; dino.di_mode = IFDIR;
dp->di_size = inp->i_isize; dp->di_size = inp->i_isize;
bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0], memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
(size_t)inp->i_numblks);
curino.id_number = inp->i_number; curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent; curino.id_parent = inp->i_parent;
(void)ckinode(dp, &curino); (void)ckinode(dp, &curino);
@ -191,7 +198,7 @@ pass2()
propagate(); propagate();
} }
int static int
pass2check(idesc) pass2check(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
@ -239,6 +246,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 1; proto.d_namlen = 1;
(void)strcpy(proto.d_name, "."); (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); entrysize = DIRSIZ(0, &proto);
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
@ -247,17 +263,17 @@ pass2check(idesc)
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp->d_reclen < 2 * entrysize) { } else if (dirp->d_reclen < 2 * entrysize) {
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} else { } else {
n = dirp->d_reclen - entrysize; n = dirp->d_reclen - entrysize;
proto.d_reclen = entrysize; proto.d_reclen = entrysize;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + entrysize); dirp = (struct direct *)((char *)(dirp) + entrysize);
bzero((char *)dirp, (size_t)n); memset(dirp, 0, (size_t)n);
dirp->d_reclen = n; dirp->d_reclen = n;
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
@ -273,6 +289,15 @@ pass2check(idesc)
proto.d_type = 0; proto.d_type = 0;
proto.d_namlen = 2; proto.d_namlen = 2;
(void)strcpy(proto.d_name, ".."); (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); entrysize = DIRSIZ(0, &proto);
if (idesc->id_entryno == 0) { if (idesc->id_entryno == 0) {
n = DIRSIZ(0, dirp); n = DIRSIZ(0, dirp);
@ -283,7 +308,7 @@ pass2check(idesc)
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->d_ino]--; lncntp[dirp->d_ino]--;
dirp = (struct direct *)((char *)(dirp) + n); 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; dirp->d_reclen = proto.d_reclen;
} }
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
@ -312,7 +337,7 @@ pass2check(idesc)
inp->i_dotdot = inp->i_parent; inp->i_dotdot = inp->i_parent;
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
proto.d_reclen = dirp->d_reclen; proto.d_reclen = dirp->d_reclen;
bcopy((char *)&proto, (char *)dirp, (size_t)entrysize); memmove(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
@ -346,6 +371,14 @@ pass2check(idesc)
if (dirp->d_ino > maxino) { if (dirp->d_ino > maxino) {
fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
n = reply("REMOVE"); 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 { } else {
again: again:
switch (statemap[dirp->d_ino]) { switch (statemap[dirp->d_ino]) {
@ -412,7 +445,7 @@ pass2check(idesc)
break; break;
default: 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); statemap[dirp->d_ino], dirp->d_ino);
} }
} }
@ -425,10 +458,11 @@ pass2check(idesc)
/* /*
* Routine to sort disk blocks. * Routine to sort disk blocks.
*/ */
int static int
blksort(inpp1, inpp2) blksort(arg1, arg2)
struct inoinfo **inpp1, **inpp2; 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]);
} }

View File

@ -32,13 +32,15 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include "fsck.h" #include "fsck.h"
void void

View File

@ -32,18 +32,19 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdlib.h>
#include <string.h>
#include "fsck.h"
int pass4check(); #include <err.h>
#include <string.h>
#include "fsck.h"
void void
pass4() pass4()
@ -54,7 +55,7 @@ pass4()
struct inodesc idesc; struct inodesc idesc;
int n; int n;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR; idesc.id_type = ADDR;
idesc.id_func = pass4check; idesc.id_func = pass4check;
for (inumber = ROOTINO; inumber <= lastino; inumber++) { for (inumber = ROOTINO; inumber <= lastino; inumber++) {
@ -98,7 +99,7 @@ pass4()
break; break;
default: default:
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[inumber], inumber); statemap[inumber], inumber);
} }
} }
@ -110,7 +111,7 @@ pass4check(idesc)
{ {
register struct dups *dlp; register struct dups *dlp;
int nfrags, res = KEEPON; 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--) { for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) { if (chkrange(blkno, 1)) {

View File

@ -32,26 +32,29 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <stdio.h> #include <stdio.h>
#include <err.h>
#include <string.h> #include <string.h>
#include "fsck.h" #include "fsck.h"
void void
pass5() pass5()
{ {
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
register struct fs *fs = &sblock; struct fs *fs = &sblock;
register struct cg *cg = &cgrp; struct cg *cg = &cgrp;
daddr_t dbase, dmax; ufs_daddr_t dbase, dmax;
register daddr_t d; ufs_daddr_t d;
register long i, j; long i, j;
struct csum *cs; struct csum *cs;
struct csum cstotal; struct csum cstotal;
struct inodesc idesc[3]; struct inodesc idesc[3];
@ -59,9 +62,10 @@ pass5()
register struct cg *newcg = (struct cg *)buf; register struct cg *newcg = (struct cg *)buf;
struct ocg *ocg = (struct ocg *)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; newcg->cg_niblk = fs->fs_ipg;
if (cvtlevel > 3) { if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen) if (preen)
pwarn("DELETING CLUSTERING MAPS\n"); pwarn("DELETING CLUSTERING MAPS\n");
@ -103,8 +107,9 @@ pass5()
switch ((int)fs->fs_postblformat) { switch ((int)fs->fs_postblformat) {
case FS_42POSTBLFMT: case FS_42POSTBLFMT:
basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); basesize = (char *)(&ocg->cg_btot[0]) -
sumsize = &ocg->cg_iused[0] - (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)] - mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
(u_char *)&ocg->cg_iused[0]; (u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -114,7 +119,7 @@ pass5()
case FS_DYNAMICPOSTBLFMT: case FS_DYNAMICPOSTBLFMT:
newcg->cg_btotoff = 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_boff =
newcg->cg_btotoff + fs->fs_cpg * sizeof(long); newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
newcg->cg_iusedoff = newcg->cg_boff + newcg->cg_iusedoff = newcg->cg_boff +
@ -136,22 +141,24 @@ pass5()
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
} }
newcg->cg_magic = CG_MAGIC; 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; sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
break; break;
default: default:
errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", sumsize = 0; /* keep lint happy */
errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
fs->fs_postblformat); fs->fs_postblformat);
} }
bzero((char *)&idesc[0], sizeof idesc); memset(&idesc[0], 0, sizeof idesc);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
idesc[i].id_type = ADDR; idesc[i].id_type = ADDR;
if (doinglevel2) if (doinglevel2)
idesc[i].id_fix = FIX; 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); j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
for (i = fs->fs_size; i < j; i++) for (i = fs->fs_size; i < j; i++)
setbmap(i); setbmap(i);
@ -188,8 +195,8 @@ pass5()
newcg->cg_irotor = cg->cg_irotor; newcg->cg_irotor = cg->cg_irotor;
else else
newcg->cg_irotor = 0; newcg->cg_irotor = 0;
bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
bzero((char *)&cg_blktot(newcg)[0], memset(&cg_blktot(newcg)[0], 0,
(size_t)(sumsize + mapsize)); (size_t)(sumsize + mapsize));
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
ocg->cg_magic = CG_MAGIC; ocg->cg_magic = CG_MAGIC;
@ -215,7 +222,7 @@ pass5()
default: default:
if (j < ROOTINO) if (j < ROOTINO)
break; break;
errexit("BAD STATE %d FOR INODE I=%d", errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
statemap[j], j); statemap[j], j);
} }
} }
@ -249,7 +256,7 @@ pass5()
} }
} }
if (fs->fs_contigsumsize > 0) { if (fs->fs_contigsumsize > 0) {
long *sump = cg_clustersum(newcg); int32_t *sump = cg_clustersum(newcg);
u_char *mapp = cg_clustersfree(newcg); u_char *mapp = cg_clustersfree(newcg);
int map = *mapp++; int map = *mapp++;
int bit = 1; int bit = 1;
@ -282,38 +289,38 @@ pass5()
cstotal.cs_nifree += newcg->cg_cs.cs_nifree; cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
cstotal.cs_ndir += newcg->cg_cs.cs_ndir; cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
cs = &fs->fs_cs(fs, c); 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")) { 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(); sbdirty();
} }
if (doinglevel1) { if (doinglevel1) {
bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); memmove(cg, newcg, (size_t)fs->fs_cgsize);
cgdirty(); cgdirty();
continue; continue;
} }
if (bcmp(cg_inosused(newcg), if (memcmp(cg_inosused(newcg),
cg_inosused(cg), mapsize) != 0 && cg_inosused(cg), mapsize) != 0 &&
dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 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); (size_t)mapsize);
cgdirty(); cgdirty();
} }
if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || if ((memcmp(newcg, cg, basesize) != 0 ||
bcmp((char *)&cg_blktot(newcg)[0], memcmp(&cg_blktot(newcg)[0],
(char *)&cg_blktot(cg)[0], sumsize) != 0) && &cg_blktot(cg)[0], sumsize) != 0) &&
dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
bcopy((char *)newcg, (char *)cg, (size_t)basesize); memmove(cg, newcg, (size_t)basesize);
bcopy((char *)&cg_blktot(newcg)[0], memmove(&cg_blktot(cg)[0],
(char *)&cg_blktot(cg)[0], (size_t)sumsize); &cg_blktot(newcg)[0], (size_t)sumsize);
cgdirty(); cgdirty();
} }
} }
if (fs->fs_postblformat == FS_42POSTBLFMT) if (fs->fs_postblformat == FS_42POSTBLFMT)
fs->fs_nrpos = savednrpos; 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")) { && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
fs->fs_ronly = 0; fs->fs_ronly = 0;
sbdirty(); sbdirty();
} }

View File

@ -32,7 +32,7 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93";
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <fstab.h>
#include "fsck.h" #include "fsck.h"
struct part { struct part {
@ -62,19 +62,22 @@ struct disk {
int pid; /* If != 0, pid of proc working on */ int pid; /* If != 0, pid of proc working on */
} *disks; } *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; int nrun, ndisks;
char hotroot; 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 int
checkfstab(preen, maxrun, docheck, chkit) checkfstab(preen, maxrun, docheck, chkit)
int preen, maxrun; int preen;
int (*docheck)(), (*chkit)(); int maxrun;
int (*docheck)(struct fstab *);
int (*chkit)(char *, char *, long, int);
{ {
register struct fstab *fsp; register struct fstab *fsp;
register struct disk *dk, *nextdisk; register struct disk *dk, *nextdisk;
@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit)
while ((fsp = getfsent()) != 0) { while ((fsp = getfsent()) != 0) {
if ((auxdata = (*docheck)(fsp)) == 0) if ((auxdata = (*docheck)(fsp)) == 0)
continue; continue;
if (!preen || (passno == 1 && fsp->fs_passno == 1)) { if (preen == 0 ||
name = blockcheck(fsp->fs_spec); (passno == 1 && fsp->fs_passno == 1)) {
if (name) { if ((name = blockcheck(fsp->fs_spec)) != 0) {
sumstatus = (*chkit)(name, if ((sumstatus = (*chkit)(name,
fsp->fs_file, auxdata, 0); fsp->fs_file, auxdata, 0)) != 0)
if (sumstatus)
return (sumstatus); return (sumstatus);
} else if (preen) } else if (preen)
return (8); return (8);
@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit)
return (0); return (0);
} }
struct disk * static struct disk *
finddisk(name) finddisk(name)
char *name; char *name;
{ {
@ -206,13 +208,11 @@ finddisk(name)
register char *p; register char *p;
size_t len = 0; 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)) { if (isdigit(*p)) {
len = p - name + 1; len = p - name + 1;
break; break;
} }
if (p < name)
len = strlen(name);
for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
if (strncmp(dk->name, name, len) == 0 && if (strncmp(dk->name, name, len) == 0 &&
@ -237,7 +237,7 @@ finddisk(name)
return (dk); return (dk);
} }
void static void
addpart(name, fsname, auxdata) addpart(name, fsname, auxdata)
char *name, *fsname; char *name, *fsname;
long auxdata; long auxdata;
@ -269,10 +269,10 @@ addpart(name, fsname, auxdata)
pt->auxdata = auxdata; pt->auxdata = auxdata;
} }
int static int
startdisk(dk, checkit) startdisk(dk, checkit)
register struct disk *dk; register struct disk *dk;
int (*checkit)(); int (*checkit)(char *, char *, long, int);
{ {
register struct part *pt = dk->part; register struct part *pt = dk->part;
@ -288,11 +288,11 @@ startdisk(dk, checkit)
} }
char * char *
blockcheck(name) blockcheck(origname)
char *name; char *origname;
{ {
struct stat stslash, stblock, stchar; struct stat stslash, stblock, stchar;
char *raw; char *newname, *raw;
struct fstab *fsinfo; struct fstab *fsinfo;
int retried = 0, l; int retried = 0, l;
@ -300,60 +300,63 @@ blockcheck(name)
if (stat("/", &stslash) < 0) { if (stat("/", &stslash) < 0) {
perror("/"); perror("/");
printf("Can't stat root\n"); printf("Can't stat root\n");
return (0); return (origname);
} }
newname = origname;
retry: retry:
if (stat(name, &stblock) < 0) { if (stat(newname, &stblock) < 0) {
perror(name); perror(newname);
printf("Can't stat %s\n", name); printf("Can't stat %s\n", newname);
return (0); return (origname);
} }
if ((stblock.st_mode & S_IFMT) == S_IFBLK) { if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
if (stslash.st_dev == stblock.st_rdev) if (stslash.st_dev == stblock.st_rdev)
hotroot++; hotroot++;
raw = rawname(name); raw = rawname(newname);
if (stat(raw, &stchar) < 0) { if (stat(raw, &stchar) < 0) {
perror(raw); perror(raw);
printf("Can't stat %s\n", raw); printf("Can't stat %s\n", raw);
return (name); return (origname);
} }
if ((stchar.st_mode & S_IFMT) == S_IFCHR) { if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
return (raw); return (raw);
} else { } else {
printf("%s is not a character device\n", raw); printf("%s is not a character device\n", raw);
return (name); return (origname);
} }
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
name = unrawname(name); newname = unrawname(origname);
retried++; retried++;
goto retry; goto retry;
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
l = strlen(name) - 1; l = strlen(origname) - 1;
if (l > 0 && name[l] == '/') if (l > 0 && origname[l] == '/')
/* remove trailing slash */ /* remove trailing slash */
name[l] = '\0'; origname[l] = '\0';
if(!(fsinfo=getfsfile(name))) { if(!(fsinfo=getfsfile(origname))) {
printf("Can't resolve %s to character special device", printf("Can't resolve %s to character special device",
name); origname);
return (0); return (0);
} }
name = fsinfo->fs_spec; newname = fsinfo->fs_spec;
retried++; retried++;
goto retry; goto retry;
} }
printf("Warning: Can't find blockdevice corresponding to name %s\n", /*
name); * Not a block or character device, just return name and
return (name); * let the user decide whether to use it.
*/
return (origname);
} }
char * static char *
unrawname(name) unrawname(name)
char *name; char *name;
{ {
char *dp; char *dp;
struct stat stb; struct stat stb;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (name); return (name);
if (stat(name, &stb) < 0) if (stat(name, &stb) < 0)
return (name); return (name);
@ -365,14 +368,14 @@ unrawname(name)
return (name); return (name);
} }
char * static char *
rawname(name) rawname(name)
char *name; char *name;
{ {
static char rawbuf[32]; static char rawbuf[32];
char *dp; char *dp;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (0); return (0);
*dp = 0; *dp = 0;
(void)strcpy(rawbuf, name); (void)strcpy(rawbuf, name);

View File

@ -32,41 +32,49 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#define DKTYPENAMES #define DKTYPENAMES
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/file.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 <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "fsck.h" #include "fsck.h"
struct bufarea asblk; struct bufarea asblk;
#define altsblock (*asblk.b_un.b_fs) #define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0) #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
static int readsb __P((int listerr)); static void badsb __P((int listerr, char *s));
static void badsb __P((int listerr, char *s)); static int calcsb __P((char *dev, int devfd, struct fs *fs));
static int calcsb __P((char *dev, int devfd, struct fs *fs)); static struct disklabel *getdisklabel __P((char *s, int fd));
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 int
setup(dev) setup(dev)
char *dev; char *dev;
{ {
long cg, size, asked, i, j; long cg, size, asked, i, j;
long bmapsize; long skipclean, bmapsize;
struct disklabel *lp; struct disklabel *lp;
off_t sizepb; off_t sizepb;
struct stat statb; struct stat statb;
@ -74,6 +82,7 @@ setup(dev)
havesb = 0; havesb = 0;
fswritefd = -1; fswritefd = -1;
skipclean = preen;
if (stat(dev, &statb) < 0) { if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno)); printf("Can't stat %s: %s\n", dev, strerror(errno));
return (0); return (0);
@ -104,7 +113,7 @@ setup(dev)
sblk.b_un.b_buf = malloc(SBSIZE); sblk.b_un.b_buf = malloc(SBSIZE);
asblk.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) 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); lp = getdisklabel((char *)NULL, fsreadfd);
if (lp) if (lp)
dev_bsize = secsize = lp->d_secsize; dev_bsize = secsize = lp->d_secsize;
@ -114,6 +123,7 @@ setup(dev)
* Read in the superblock, looking for alternates if necessary * Read in the superblock, looking for alternates if necessary
*/ */
if (readsb(1) == 0) { if (readsb(1) == 0) {
skipclean = 0;
if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
return(0); return(0);
if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
@ -137,6 +147,10 @@ setup(dev)
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag); pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
bflag = 0; bflag = 0;
} }
if (skipclean && sblock.fs_clean) {
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
return (-1);
}
maxfsblock = sblock.fs_size; maxfsblock = sblock.fs_size;
maxino = sblock.fs_ncg * sblock.fs_ipg; maxino = sblock.fs_ncg * sblock.fs_ipg;
/* /*
@ -223,17 +237,16 @@ setup(dev)
sblock.fs_nrpos = 8; sblock.fs_nrpos = 8;
sblock.fs_postbloff = sblock.fs_postbloff =
(char *)(&sblock.fs_opostbl[0][0]) - (char *)(&sblock.fs_opostbl[0][0]) -
(char *)(&sblock.fs_link); (char *)(&sblock.fs_firstfield);
sblock.fs_rotbloff = &sblock.fs_space[0] - sblock.fs_rotbloff = &sblock.fs_space[0] -
(u_char *)(&sblock.fs_link); (u_char *)(&sblock.fs_firstfield);
sblock.fs_cgsize = sblock.fs_cgsize =
fragroundup(&sblock, CGSIZE(&sblock)); fragroundup(&sblock, CGSIZE(&sblock));
sbdirty(); sbdirty();
dirty(&asblk); dirty(&asblk);
} }
if (asblk.b_dirty) { if (asblk.b_dirty && !bflag) {
bcopy((char *)&sblock, (char *)&altsblock, memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
(size_t)sblock.fs_sbsize);
flush(fswritefd, &asblk); flush(fswritefd, &asblk);
} }
/* /*
@ -249,7 +262,7 @@ setup(dev)
size) != 0 && !asked) { size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION"); pfatal("BAD SUMMARY INFORMATION");
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit(""); exit(EEXIT);
asked++; asked++;
} }
} }
@ -297,7 +310,7 @@ setup(dev)
return (1); return (1);
badsb: badsb:
ckfini(); ckfini(0);
return (0); return (0);
} }
@ -308,7 +321,7 @@ static int
readsb(listerr) readsb(listerr)
int 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) if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
return (0); return (0);
@ -348,8 +361,8 @@ readsb(listerr)
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
if (asblk.b_errs) if (asblk.b_errs)
return (0); return (0);
altsblock.fs_link = sblock.fs_link; altsblock.fs_firstfield = sblock.fs_firstfield;
altsblock.fs_rlink = sblock.fs_rlink; altsblock.fs_unused_1 = sblock.fs_unused_1;
altsblock.fs_time = sblock.fs_time; altsblock.fs_time = sblock.fs_time;
altsblock.fs_cstotal = sblock.fs_cstotal; altsblock.fs_cstotal = sblock.fs_cstotal;
altsblock.fs_cgrotor = sblock.fs_cgrotor; altsblock.fs_cgrotor = sblock.fs_cgrotor;
@ -362,12 +375,11 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim; altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay; altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg; altsblock.fs_maxbpg = sblock.fs_maxbpg;
bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
sizeof sblock.fs_csp); altsblock.fs_maxcluster = sblock.fs_maxcluster;
bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
sizeof sblock.fs_fsmnt); memmove(altsblock.fs_sparecon,
bcopy((char *)sblock.fs_sparecon, (char *)altsblock.fs_sparecon, sblock.fs_sparecon, sizeof sblock.fs_sparecon);
sizeof sblock.fs_sparecon);
/* /*
* The following should not have to be copied. * The following should not have to be copied.
*/ */
@ -375,11 +387,26 @@ readsb(listerr)
altsblock.fs_interleave = sblock.fs_interleave; altsblock.fs_interleave = sblock.fs_interleave;
altsblock.fs_npsect = sblock.fs_npsect; altsblock.fs_npsect = sblock.fs_npsect;
altsblock.fs_nrpos = sblock.fs_nrpos; altsblock.fs_nrpos = sblock.fs_nrpos;
altsblock.fs_state = sblock.fs_state;
altsblock.fs_qbmask = sblock.fs_qbmask; altsblock.fs_qbmask = sblock.fs_qbmask;
altsblock.fs_qfmask = sblock.fs_qfmask; altsblock.fs_qfmask = sblock.fs_qfmask;
altsblock.fs_state = sblock.fs_state; altsblock.fs_state = sblock.fs_state;
altsblock.fs_maxfilesize = sblock.fs_maxfilesize; 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, badsb(listerr,
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0); return (0);
@ -407,7 +434,7 @@ badsb(listerr, s)
* can be used. Do NOT attempt to use other macros without verifying that * can be used. Do NOT attempt to use other macros without verifying that
* their needed information is available! * their needed information is available!
*/ */
int static int
calcsb(dev, devfd, fs) calcsb(dev, devfd, fs)
char *dev; char *dev;
int devfd; int devfd;
@ -418,7 +445,7 @@ calcsb(dev, devfd, fs)
register char *cp; register char *cp;
int i; int i;
cp = index(dev, '\0') - 1; cp = strchr(dev, '\0') - 1;
if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) { if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev); pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0); return (0);
@ -434,7 +461,7 @@ calcsb(dev, devfd, fs)
fstypenames[pp->p_fstype] : "unknown"); fstypenames[pp->p_fstype] : "unknown");
return (0); return (0);
} }
bzero((char *)fs, sizeof(struct fs)); memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize; fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag; fs->fs_frag = pp->p_frag;
fs->fs_cpg = pp->p_cpg; fs->fs_cpg = pp->p_cpg;
@ -461,7 +488,7 @@ calcsb(dev, devfd, fs)
return (1); return (1);
} }
struct disklabel * static struct disklabel *
getdisklabel(s, fd) getdisklabel(s, fd)
char *s; char *s;
int fd; int fd;
@ -472,7 +499,7 @@ getdisklabel(s, fd)
if (s == NULL) if (s == NULL)
return ((struct disklabel *)NULL); return ((struct disklabel *)NULL);
pwarn("ioctl (GCINFO): %s\n", strerror(errno)); 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); return (&lab);
} }

View File

@ -32,11 +32,12 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h> #include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.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 <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <err.h>
#include "fsck.h" #include "fsck.h"
long diskreads, totalreads; /* Disk cache statistics */ 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 int
ftypeok(dp) ftypeok(dp)
@ -119,7 +123,7 @@ bufinit()
pbp = pdirbp = (struct bufarea *)0; pbp = pdirbp = (struct bufarea *)0;
bufp = malloc((unsigned int)sblock.fs_bsize); bufp = malloc((unsigned int)sblock.fs_bsize);
if (bufp == 0) if (bufp == 0)
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
cgblk.b_un.b_buf = bufp; cgblk.b_un.b_buf = bufp;
initbarea(&cgblk); initbarea(&cgblk);
bufhead.b_next = bufhead.b_prev = &bufhead; bufhead.b_next = bufhead.b_prev = &bufhead;
@ -132,7 +136,7 @@ bufinit()
if (bp == NULL || bufp == NULL) { if (bp == NULL || bufp == NULL) {
if (i >= MINBUFS) if (i >= MINBUFS)
break; break;
errexit("cannot allocate buffer pool\n"); errx(EEXIT, "cannot allocate buffer pool");
} }
bp->b_un.b_buf = bufp; bp->b_un.b_buf = bufp;
bp->b_prev = &bufhead; bp->b_prev = &bufhead;
@ -149,7 +153,7 @@ bufinit()
*/ */
struct bufarea * struct bufarea *
getdatablk(blkno, size) getdatablk(blkno, size)
daddr_t blkno; ufs_daddr_t blkno;
long size; long size;
{ {
register struct bufarea *bp; register struct bufarea *bp;
@ -161,7 +165,7 @@ getdatablk(blkno, size)
if ((bp->b_flags & B_INUSE) == 0) if ((bp->b_flags & B_INUSE) == 0)
break; break;
if (bp == &bufhead) if (bp == &bufhead)
errexit("deadlocked buffer pool\n"); errx(EEXIT, "deadlocked buffer pool");
getblk(bp, blkno, size); getblk(bp, blkno, size);
/* fall through */ /* fall through */
foundit: foundit:
@ -179,10 +183,10 @@ getdatablk(blkno, size)
void void
getblk(bp, blk, size) getblk(bp, blk, size)
register struct bufarea *bp; register struct bufarea *bp;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
daddr_t dblk; ufs_daddr_t dblk;
dblk = fsbtodb(&sblock, blk); dblk = fsbtodb(&sblock, blk);
if (bp->b_bno != dblk) { if (bp->b_bno != dblk) {
@ -220,24 +224,25 @@ flush(fd, bp)
} }
} }
void static void
rwerror(mesg, blk) rwerror(mesg, blk)
char *mesg; char *mesg;
daddr_t blk; ufs_daddr_t blk;
{ {
if (preen == 0) if (preen == 0)
printf("\n"); printf("\n");
pfatal("CANNOT %s: BLK %ld", mesg, blk); pfatal("CANNOT %s: BLK %ld", mesg, blk);
if (reply("CONTINUE") == 0) if (reply("CONTINUE") == 0)
errexit("Program terminated\n"); exit(EEXIT);
} }
void void
ckfini() ckfini(markclean)
int markclean;
{ {
register struct bufarea *bp, *nbp; register struct bufarea *bp, *nbp;
int cnt = 0; int ofsmodified, cnt = 0;
if (fswritefd < 0) { if (fswritefd < 0) {
(void)close(fsreadfd); (void)close(fsreadfd);
@ -260,8 +265,17 @@ ckfini()
free((char *)bp); free((char *)bp);
} }
if (bufhead.b_size != cnt) 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; 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) if (debug)
printf("cache missed %ld of %ld (%d%%)\n", diskreads, printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads)); totalreads, (int)(diskreads * 100 / totalreads));
@ -273,7 +287,7 @@ int
bread(fd, buf, blk, size) bread(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
char *cp; char *cp;
@ -290,7 +304,7 @@ bread(fd, buf, blk, size)
if (lseek(fd, offset, 0) < 0) if (lseek(fd, offset, 0) < 0)
rwerror("SEEK", blk); rwerror("SEEK", blk);
errs = 0; errs = 0;
bzero(buf, (size_t)size); memset(buf, 0, (size_t)size);
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
if (read(fd, cp, (int)secsize) != secsize) { if (read(fd, cp, (int)secsize) != secsize) {
@ -312,7 +326,7 @@ void
bwrite(fd, buf, blk, size) bwrite(fd, buf, blk, size)
int fd; int fd;
char *buf; char *buf;
daddr_t blk; ufs_daddr_t blk;
long size; long size;
{ {
int i; int i;
@ -345,7 +359,7 @@ bwrite(fd, buf, blk, size)
/* /*
* allocate a data block with the specified number of fragments * allocate a data block with the specified number of fragments
*/ */
int ufs_daddr_t
allocblk(frags) allocblk(frags)
long frags; long frags;
{ {
@ -378,7 +392,7 @@ allocblk(frags)
*/ */
void void
freeblk(blkno, frags) freeblk(blkno, frags)
daddr_t blkno; ufs_daddr_t blkno;
long frags; long frags;
{ {
struct inodesc idesc; struct inodesc idesc;
@ -411,7 +425,7 @@ getpathname(namebuf, curdir, ino)
return; return;
} }
busy = 1; busy = 1;
bzero((char *)&idesc, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = DATA; idesc.id_type = DATA;
idesc.id_fix = IGNORE; idesc.id_fix = IGNORE;
cp = &namebuf[MAXPATHLEN - 1]; cp = &namebuf[MAXPATHLEN - 1];
@ -435,7 +449,7 @@ getpathname(namebuf, curdir, ino)
break; break;
len = strlen(namebuf); len = strlen(namebuf);
cp -= len; cp -= len;
bcopy(namebuf, cp, (size_t)len); memmove(cp, namebuf, (size_t)len);
*--cp = '/'; *--cp = '/';
if (cp < &namebuf[MAXNAMLEN]) if (cp < &namebuf[MAXNAMLEN])
break; break;
@ -444,15 +458,15 @@ getpathname(namebuf, curdir, ino)
busy = 0; busy = 0;
if (ino != ROOTINO) if (ino != ROOTINO)
*--cp = '?'; *--cp = '?';
bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp)); memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp));
} }
void void
catch(x) catch(sig)
int x; int sig;
{ {
if (!doinglevel2) if (!doinglevel2)
ckfini(); ckfini(0);
exit(12); exit(12);
} }
@ -462,8 +476,8 @@ catch(x)
* so that reboot sequence may be interrupted. * so that reboot sequence may be interrupted.
*/ */
void void
catchquit(x) catchquit(sig)
int x; int sig;
{ {
printf("returning to single-user after filesystem check\n"); printf("returning to single-user after filesystem check\n");
returntosingle = 1; returntosingle = 1;
@ -475,8 +489,8 @@ catchquit(x)
* Used by child processes in preen. * Used by child processes in preen.
*/ */
void void
voidquit(x) voidquit(sig)
int x; int sig;
{ {
sleep(1); sleep(1);
@ -520,76 +534,95 @@ dofix(idesc, msg)
return (0); return (0);
default: default:
errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix);
return (0);
} }
/* NOTREACHED */ /* NOTREACHED */
return (0);
} }
/* VARARGS1 */ #if __STDC__
void #include <stdarg.h>
errexit(const char *s1, ...) #else
{ #include <varargs.h>
va_list ap; #endif
va_start(ap,s1);
vfprintf(stdout, s1, ap);
va_end(ap);
exit(8);
}
/* /*
* An unexpected inconsistency occured. * An unexpected inconsistency occured.
* Die if preening, otherwise just print message and continue. * Die if preening, otherwise just print message and continue.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
if (preen) { va_start(ap, fmt);
printf("%s: ", cdevname); #else
vfprintf(stdout, s, ap); va_start(ap);
printf("\n"); #endif
printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", if (!preen) {
cdevname); (void)vfprintf(stderr, fmt, ap);
exit(8); va_end(ap);
return;
} }
vfprintf(stdout, s, ap); (void)fprintf(stderr, "%s: ", cdevname);
va_end(ap); (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, * Pwarn just prints a message when not preening,
* or a warning (preceded by filename) when preening. * or a warning (preceded by filename) when preening.
*/ */
/* VARARGS1 */
void 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_list ap;
va_start(ap,s); #if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
if (preen) if (preen)
printf("%s: ", cdevname); (void)fprintf(stderr, "%s: ", cdevname);
vfprintf(stdout, s, ap); (void)vfprintf(stderr, fmt, ap);
va_end(ap); va_end(ap);
} }
#ifndef lint
/* /*
* Stub for routines from kernel. * Stub for routines from kernel.
*/ */
void void
#ifdef __STDC__ #if __STDC__
panic(const char *fmt, ...) panic(const char *fmt, ...)
#else #else
panic(fmt, va_alist) panic(fmt, va_alist)
char *fmt; char *fmt;
va_dcl
#endif #endif
{ {
va_list ap;
pfatal("INTERNAL INCONSISTENCY:"); #if __STDC__
errexit(fmt); va_start(ap, fmt);
} #else
va_start(ap);
#endif #endif
pfatal("INTERNAL INCONSISTENCY:");
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
exit(EEXIT);
}

View File

@ -32,7 +32,7 @@
*/ */
#ifndef lint #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 */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
@ -45,7 +45,7 @@ static const char sccsid[] = "@(#)preen.c 8.1 (Berkeley) 6/5/93";
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <fstab.h>
#include "fsck.h" #include "fsck.h"
struct part { struct part {
@ -62,19 +62,22 @@ struct disk {
int pid; /* If != 0, pid of proc working on */ int pid; /* If != 0, pid of proc working on */
} *disks; } *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; int nrun, ndisks;
char hotroot; 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 int
checkfstab(preen, maxrun, docheck, chkit) checkfstab(preen, maxrun, docheck, chkit)
int preen, maxrun; int preen;
int (*docheck)(), (*chkit)(); int maxrun;
int (*docheck)(struct fstab *);
int (*chkit)(char *, char *, long, int);
{ {
register struct fstab *fsp; register struct fstab *fsp;
register struct disk *dk, *nextdisk; register struct disk *dk, *nextdisk;
@ -93,12 +96,11 @@ checkfstab(preen, maxrun, docheck, chkit)
while ((fsp = getfsent()) != 0) { while ((fsp = getfsent()) != 0) {
if ((auxdata = (*docheck)(fsp)) == 0) if ((auxdata = (*docheck)(fsp)) == 0)
continue; continue;
if (!preen || (passno == 1 && fsp->fs_passno == 1)) { if (preen == 0 ||
name = blockcheck(fsp->fs_spec); (passno == 1 && fsp->fs_passno == 1)) {
if (name) { if ((name = blockcheck(fsp->fs_spec)) != 0) {
sumstatus = (*chkit)(name, if ((sumstatus = (*chkit)(name,
fsp->fs_file, auxdata, 0); fsp->fs_file, auxdata, 0)) != 0)
if (sumstatus)
return (sumstatus); return (sumstatus);
} else if (preen) } else if (preen)
return (8); return (8);
@ -198,7 +200,7 @@ checkfstab(preen, maxrun, docheck, chkit)
return (0); return (0);
} }
struct disk * static struct disk *
finddisk(name) finddisk(name)
char *name; char *name;
{ {
@ -206,13 +208,11 @@ finddisk(name)
register char *p; register char *p;
size_t len = 0; 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)) { if (isdigit(*p)) {
len = p - name + 1; len = p - name + 1;
break; break;
} }
if (p < name)
len = strlen(name);
for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
if (strncmp(dk->name, name, len) == 0 && if (strncmp(dk->name, name, len) == 0 &&
@ -237,7 +237,7 @@ finddisk(name)
return (dk); return (dk);
} }
void static void
addpart(name, fsname, auxdata) addpart(name, fsname, auxdata)
char *name, *fsname; char *name, *fsname;
long auxdata; long auxdata;
@ -269,10 +269,10 @@ addpart(name, fsname, auxdata)
pt->auxdata = auxdata; pt->auxdata = auxdata;
} }
int static int
startdisk(dk, checkit) startdisk(dk, checkit)
register struct disk *dk; register struct disk *dk;
int (*checkit)(); int (*checkit)(char *, char *, long, int);
{ {
register struct part *pt = dk->part; register struct part *pt = dk->part;
@ -288,11 +288,11 @@ startdisk(dk, checkit)
} }
char * char *
blockcheck(name) blockcheck(origname)
char *name; char *origname;
{ {
struct stat stslash, stblock, stchar; struct stat stslash, stblock, stchar;
char *raw; char *newname, *raw;
struct fstab *fsinfo; struct fstab *fsinfo;
int retried = 0, l; int retried = 0, l;
@ -300,60 +300,63 @@ blockcheck(name)
if (stat("/", &stslash) < 0) { if (stat("/", &stslash) < 0) {
perror("/"); perror("/");
printf("Can't stat root\n"); printf("Can't stat root\n");
return (0); return (origname);
} }
newname = origname;
retry: retry:
if (stat(name, &stblock) < 0) { if (stat(newname, &stblock) < 0) {
perror(name); perror(newname);
printf("Can't stat %s\n", name); printf("Can't stat %s\n", newname);
return (0); return (origname);
} }
if ((stblock.st_mode & S_IFMT) == S_IFBLK) { if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
if (stslash.st_dev == stblock.st_rdev) if (stslash.st_dev == stblock.st_rdev)
hotroot++; hotroot++;
raw = rawname(name); raw = rawname(newname);
if (stat(raw, &stchar) < 0) { if (stat(raw, &stchar) < 0) {
perror(raw); perror(raw);
printf("Can't stat %s\n", raw); printf("Can't stat %s\n", raw);
return (name); return (origname);
} }
if ((stchar.st_mode & S_IFMT) == S_IFCHR) { if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
return (raw); return (raw);
} else { } else {
printf("%s is not a character device\n", raw); printf("%s is not a character device\n", raw);
return (name); return (origname);
} }
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
name = unrawname(name); newname = unrawname(origname);
retried++; retried++;
goto retry; goto retry;
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) { } else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
l = strlen(name) - 1; l = strlen(origname) - 1;
if (l > 0 && name[l] == '/') if (l > 0 && origname[l] == '/')
/* remove trailing slash */ /* remove trailing slash */
name[l] = '\0'; origname[l] = '\0';
if(!(fsinfo=getfsfile(name))) { if(!(fsinfo=getfsfile(origname))) {
printf("Can't resolve %s to character special device", printf("Can't resolve %s to character special device",
name); origname);
return (0); return (0);
} }
name = fsinfo->fs_spec; newname = fsinfo->fs_spec;
retried++; retried++;
goto retry; goto retry;
} }
printf("Warning: Can't find blockdevice corresponding to name %s\n", /*
name); * Not a block or character device, just return name and
return (name); * let the user decide whether to use it.
*/
return (origname);
} }
char * static char *
unrawname(name) unrawname(name)
char *name; char *name;
{ {
char *dp; char *dp;
struct stat stb; struct stat stb;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (name); return (name);
if (stat(name, &stb) < 0) if (stat(name, &stb) < 0)
return (name); return (name);
@ -365,14 +368,14 @@ unrawname(name)
return (name); return (name);
} }
char * static char *
rawname(name) rawname(name)
char *name; char *name;
{ {
static char rawbuf[32]; static char rawbuf[32];
char *dp; char *dp;
if ((dp = rindex(name, '/')) == 0) if ((dp = strrchr(name, '/')) == 0)
return (0); return (0);
*dp = 0; *dp = 0;
(void)strcpy(rawbuf, name); (void)strcpy(rawbuf, name);