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
MAN8= fsck.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
CFLAGS+=-W
.PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk>

View File

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

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93
.|' $Id$
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $
.\"
.Dd December 11, 1993
.Dd May 9, 1995
.Dt FSCK 8
.Os BSD 4
.Sh NAME
@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed
to be the partition designator.
.Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that
are not marked clean are checked. If the
are not marked clean are checked.
Filesystems are marked clean when they are unmounted,
when they have been mounted read-only, or when
.Nm fsck
runs on them successfully.
If the
.Fl f
option is specified, the filesystems
will be checked regardless of the state of their clean flag.
@ -189,7 +194,7 @@ do not open the filesystem for writing.
Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised.
.Bl -tag -width indent
There are currently three levels defined:
There are currently four levels defined:
.It 0
The filesystem is in the old (static table) format.
.It 1
@ -198,6 +203,10 @@ The filesystem is in the new (dynamic table) format.
The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode,
and directories have an added field showing the file type.
.It 3
If maxcontig is greater than one,
build the free segment maps to aid in finding contiguous sets of blocks.
If maxcontig is equal to one, delete any existing segment maps.
.El
.Pp
In interactive mode,

View File

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

View File

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

View File

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

View File

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

View File

@ -32,18 +32,21 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <string.h>
#include "fsck.h"
int pass1bcheck();
static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void
pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc;
ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc));
memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1bcheck;
duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
}
}
int
static int
pass1bcheck(idesc)
register struct inodesc *idesc;
{
register struct dups *dlp;
int nfrags, res = KEEPON;
daddr_t blkno = idesc->id_blkno;
ufs_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1))

View File

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

View File

@ -32,13 +32,15 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include "fsck.h"
void

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93
.|' $Id$
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $
.\"
.Dd December 11, 1993
.Dd May 9, 1995
.Dt FSCK 8
.Os BSD 4
.Sh NAME
@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed
to be the partition designator.
.Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that
are not marked clean are checked. If the
are not marked clean are checked.
Filesystems are marked clean when they are unmounted,
when they have been mounted read-only, or when
.Nm fsck
runs on them successfully.
If the
.Fl f
option is specified, the filesystems
will be checked regardless of the state of their clean flag.
@ -189,7 +194,7 @@ do not open the filesystem for writing.
Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised.
.Bl -tag -width indent
There are currently three levels defined:
There are currently four levels defined:
.It 0
The filesystem is in the old (static table) format.
.It 1
@ -198,6 +203,10 @@ The filesystem is in the new (dynamic table) format.
The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode,
and directories have an added field showing the file type.
.It 3
If maxcontig is greater than one,
build the free segment maps to aid in finding contiguous sets of blocks.
If maxcontig is equal to one, delete any existing segment maps.
.El
.Pp
In interactive mode,

View File

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

View File

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

View File

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

View File

@ -32,18 +32,21 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <string.h>
#include "fsck.h"
int pass1bcheck();
static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void
pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc;
ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc));
memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1bcheck;
duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
}
}
int
static int
pass1bcheck(idesc)
register struct inodesc *idesc;
{
register struct dups *dlp;
int nfrags, res = KEEPON;
daddr_t blkno = idesc->id_blkno;
ufs_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1))

View File

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

View File

@ -32,13 +32,15 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include "fsck.h"
void

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,10 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)fsck.8 8.2 (Berkeley) 12/11/93
.|' $Id$
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
.|' $Id: fsck.8,v 1.8 1997/02/22 14:32:23 peter Exp $
.\"
.Dd December 11, 1993
.Dd May 9, 1995
.Dt FSCK 8
.Os BSD 4
.Sh NAME
@ -75,7 +75,12 @@ of the device name that ends in a digit; the remaining characters are assumed
to be the partition designator.
.Pp
The clean flag of each filesystem's superblock is examined and only those filesystems that
are not marked clean are checked. If the
are not marked clean are checked.
Filesystems are marked clean when they are unmounted,
when they have been mounted read-only, or when
.Nm fsck
runs on them successfully.
If the
.Fl f
option is specified, the filesystems
will be checked regardless of the state of their clean flag.
@ -189,7 +194,7 @@ do not open the filesystem for writing.
Convert the filesystem to the specified level.
Note that the level of a filesystem can only be raised.
.Bl -tag -width indent
There are currently three levels defined:
There are currently four levels defined:
.It 0
The filesystem is in the old (static table) format.
.It 1
@ -198,6 +203,10 @@ The filesystem is in the new (dynamic table) format.
The filesystem supports 32-bit uid's and gid's,
short symbolic links are stored in the inode,
and directories have an added field showing the file type.
.It 3
If maxcontig is greater than one,
build the free segment maps to aid in finding contiguous sets of blocks.
If maxcontig is equal to one, delete any existing segment maps.
.El
.Pp
In interactive mode,

View File

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

View File

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

View File

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

View File

@ -32,18 +32,21 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <string.h>
#include "fsck.h"
int pass1bcheck();
static struct dups *duphead;
static int pass1bcheck __P((struct inodesc *));
void
pass1b()
@ -53,7 +56,7 @@ pass1b()
struct inodesc idesc;
ino_t inumber;
bzero((char *)&idesc, sizeof(struct inodesc));
memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1bcheck;
duphead = duplist;
@ -73,13 +76,13 @@ pass1b()
}
}
int
static int
pass1bcheck(idesc)
register struct inodesc *idesc;
{
register struct dups *dlp;
int nfrags, res = KEEPON;
daddr_t blkno = idesc->id_blkno;
ufs_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1))

View File

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

View File

@ -32,13 +32,15 @@
*/
#ifndef lint
static const char sccsid[] = "@(#)pass3.c 8.1 (Berkeley) 6/5/93";
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include "fsck.h"
void

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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