Ext2 metadata are always stored on disk in little-endian byte order,

so do byte-swapping on big-endian system. The byte-swap routines are in
fsck/bswap.c because they will also be used in fsck_ffs in future.
Tested on i386 and sparc.
This commit is contained in:
bouyer 1997-10-09 13:19:32 +00:00
parent deff7d5471
commit 7052d78b8d
10 changed files with 372 additions and 252 deletions

47
sbin/fsck/bswap.c Normal file
View File

@ -0,0 +1,47 @@
/* $NetBSD: bswap.c,v 1.1 1997/10/09 13:19:32 bouyer Exp $ */
/*
* Written by Manuel Bouyer <bouyer@netbsd.org>.
* Public domain.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$NetBSD: bswap.c,v 1.1 1997/10/09 13:19:32 bouyer Exp $";
#endif
#include <sys/types.h>
#undef bswap64
#ifndef bswap16
u_int16_t
bswap16(x)
u_int16_t x;
{
return ((x << 8) & 0xff00) | ((x >> 8) & 0x00ff);
}
#endif
#ifndef bswap32
u_int32_t
bswap32(x)
u_int32_t x;
{
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}
#endif
u_int64_t
bswap64(x)
u_int64_t x;
{
u_int32_t *p = (u_int32_t*)&x;
u_int32_t t;
t = bswap32(p[0]);
p[0] = bswap32(p[1]);
p[1] = t;
return x;
}

View File

@ -1,10 +1,10 @@
# $NetBSD: Makefile,v 1.2 1997/06/16 08:10:35 bouyer Exp $ # $NetBSD: Makefile,v 1.3 1997/10/09 13:19:33 bouyer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93 # @(#)Makefile 8.1 (Berkeley) 6/5/93
PROG= fsck_ext2fs PROG= fsck_ext2fs
MAN= fsck_ext2fs.8 MAN= fsck_ext2fs.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c fsutil.c setup.c utilities.c# ext2fs_subr.c pass5.c fsutil.c setup.c utilities.c bswap.c
.PATH: ${.CURDIR}/../../sys/ufs/ext2fs ${.CURDIR}/../fsck .PATH: ${.CURDIR}/../../sys/ufs/ext2fs ${.CURDIR}/../fsck
CFLAGS+= -I${.CURDIR}/../fsck CFLAGS+= -I${.CURDIR}/../fsck

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.2 1997/09/14 14:27:23 lukem Exp $ */ /* $NetBSD: dir.c,v 1.3 1997/10/09 13:19:34 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94";
#else #else
__RCSID("$NetBSD: dir.c,v 1.2 1997/09/14 14:27:23 lukem Exp $"); __RCSID("$NetBSD: dir.c,v 1.3 1997/10/09 13:19:34 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -144,7 +144,7 @@ dirscan(idesc)
} }
idesc->id_loc = 0; idesc->id_loc = 0;
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
dsize = dp->e2d_reclen; dsize = fs2h16(dp->e2d_reclen);
memcpy(dbuf, dp, (size_t)dsize); memcpy(dbuf, dp, (size_t)dsize);
idesc->id_dirp = (struct ext2fs_direct *)dbuf; idesc->id_dirp = (struct ext2fs_direct *)dbuf;
if ((n = (*idesc->id_func)(idesc)) & ALTERED) { if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
@ -186,7 +186,7 @@ fsck_readdir(idesc)
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); dp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc);
dp->e2d_reclen = sblock.e2fs_bsize; dp->e2d_reclen = h2fs16(sblock.e2fs_bsize);
dp->e2d_ino = 0; dp->e2d_ino = 0;
dp->e2d_namlen = 0; dp->e2d_namlen = 0;
dp->e2d_name[0] = '\0'; dp->e2d_name[0] = '\0';
@ -201,8 +201,8 @@ dpok:
return NULL; return NULL;
dploc = idesc->id_loc; dploc = idesc->id_loc;
dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc); dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc);
idesc->id_loc += dp->e2d_reclen; idesc->id_loc += fs2h16(dp->e2d_reclen);
idesc->id_filesize -= dp->e2d_reclen; idesc->id_filesize -= fs2h16(dp->e2d_reclen);
if ((idesc->id_loc % sblock.e2fs_bsize) == 0) if ((idesc->id_loc % sblock.e2fs_bsize) == 0)
return (dp); return (dp);
ndp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); ndp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc);
@ -216,7 +216,7 @@ dpok:
fix = dofix(idesc, "DIRECTORY CORRUPTED"); fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz); bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc); dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc);
dp->e2d_reclen += size; dp->e2d_reclen = h2fs16(fs2h16(dp->e2d_reclen) + size);
if (fix) if (fix)
dirty(bp); dirty(bp);
} }
@ -234,20 +234,21 @@ dircheck(idesc, dp)
{ {
int size; int size;
char *cp; char *cp;
u_char namlen;
int spaceleft; int spaceleft;
u_int16_t namlen;
u_int16_t reclen = fs2h16(dp->e2d_reclen);
spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize); spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize);
if (dp->e2d_ino > maxino || if (fs2h32(dp->e2d_ino) > maxino ||
dp->e2d_reclen == 0 || reclen == 0 ||
dp->e2d_reclen > spaceleft || reclen > spaceleft ||
(dp->e2d_reclen & 0x3) != 0) (reclen & 0x3) != 0)
return (0); return (0);
if (dp->e2d_ino == 0) if (dp->e2d_ino == 0)
return (1); return (1);
size = EXT2FS_DIRSIZ(dp->e2d_namlen); namlen = fs2h16(dp->e2d_namlen);
namlen = dp->e2d_namlen; size = EXT2FS_DIRSIZ(namlen);
if (dp->e2d_reclen < size || if (reclen < size ||
idesc->id_filesize < size || idesc->id_filesize < size ||
namlen > EXT2FS_MAXNAMLEN) namlen > EXT2FS_MAXNAMLEN)
return (0); return (0);
@ -285,7 +286,7 @@ fileerror(cwd, ino, errmesg)
dp = ginode(ino); dp = ginode(ino);
if (ftypeok(dp)) if (ftypeok(dp))
pfatal("%s=%s\n", pfatal("%s=%s\n",
(dp->e2di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf);
else else
pfatal("NAME=%s\n", pathbuf); pfatal("NAME=%s\n", pathbuf);
} }
@ -298,15 +299,15 @@ adjust(idesc, lcnt)
struct ext2fs_dinode *dp; struct ext2fs_dinode *dp;
dp = ginode(idesc->id_number); dp = ginode(idesc->id_number);
if (dp->e2di_nlink == lcnt) { if (fs2h16(dp->e2di_nlink) == lcnt) {
if (linkup(idesc->id_number, (ino_t)0) == 0) if (linkup(idesc->id_number, (ino_t)0) == 0)
clri(idesc, "UNREF", 0); clri(idesc, "UNREF", 0);
} else { } else {
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
((dp->e2di_mode & IFMT) == IFDIR ? "DIR" : "FILE")); ((fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"));
pinode(idesc->id_number); pinode(idesc->id_number);
printf(" COUNT %d SHOULD BE %d", printf(" COUNT %d SHOULD BE %d",
dp->e2di_nlink, dp->e2di_nlink - lcnt); fs2h16(dp->e2di_nlink), fs2h16(dp->e2di_nlink) - lcnt);
if (preen) { if (preen) {
if (lcnt < 0) { if (lcnt < 0) {
printf("\n"); printf("\n");
@ -315,7 +316,7 @@ adjust(idesc, lcnt)
printf(" (ADJUSTED)\n"); printf(" (ADJUSTED)\n");
} }
if (preen || reply("ADJUST") == 1) { if (preen || reply("ADJUST") == 1) {
dp->e2di_nlink -= lcnt; dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - lcnt);
inodirty(); inodirty();
} }
} }
@ -329,21 +330,21 @@ mkentry(idesc)
struct ext2fs_direct newent; struct ext2fs_direct newent;
int newlen, oldlen; int newlen, oldlen;
newent.e2d_namlen = strlen(idesc->id_name); newent.e2d_namlen = h2fs16(strlen(idesc->id_name));
newlen = EXT2FS_DIRSIZ(newent.e2d_namlen); newlen = EXT2FS_DIRSIZ(fs2h16(newent.e2d_namlen));
if (dirp->e2d_ino != 0) if (dirp->e2d_ino != 0)
oldlen = EXT2FS_DIRSIZ(dirp->e2d_namlen); oldlen = EXT2FS_DIRSIZ(fs2h16(dirp->e2d_namlen));
else else
oldlen = 0; oldlen = 0;
if (dirp->e2d_reclen - oldlen < newlen) if (fs2h16(dirp->e2d_reclen) - oldlen < newlen)
return (KEEPON); return (KEEPON);
newent.e2d_reclen = dirp->e2d_reclen - oldlen; newent.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - oldlen);
dirp->e2d_reclen = oldlen; dirp->e2d_reclen = h2fs16(oldlen);
dirp = (struct ext2fs_direct *)(((char *)dirp) + oldlen); dirp = (struct ext2fs_direct *)(((char *)dirp) + oldlen);
dirp->e2d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ dirp->e2d_ino = h2fs32(idesc->id_parent); /* ino to be entered is in id_parent */
dirp->e2d_reclen = newent.e2d_reclen; dirp->e2d_reclen = newent.e2d_reclen;
dirp->e2d_namlen = newent.e2d_namlen; dirp->e2d_namlen = newent.e2d_namlen;
memcpy(dirp->e2d_name, idesc->id_name, (size_t)dirp->e2d_namlen); memcpy(dirp->e2d_name, idesc->id_name, (size_t)fs2h16(dirp->e2d_namlen));
return (ALTERED|STOP); return (ALTERED|STOP);
} }
@ -352,11 +353,12 @@ chgino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
struct ext2fs_direct *dirp = idesc->id_dirp; struct ext2fs_direct *dirp = idesc->id_dirp;
u_int16_t namlen = fs2h16(dirp->e2d_namlen);
if (strlen(idesc->id_name) != dirp->e2d_namlen || if (strlen(idesc->id_name) != namlen ||
strncmp(dirp->e2d_name, idesc->id_name, (int)dirp->e2d_namlen)) strncmp(dirp->e2d_name, idesc->id_name, (int)namlen))
return (KEEPON); return (KEEPON);
dirp->e2d_ino = idesc->id_parent; dirp->e2d_ino = h2fs32(idesc->id_parent);
return (ALTERED|STOP); return (ALTERED|STOP);
} }
@ -373,10 +375,10 @@ linkup(orphan, parentdir)
memset(&idesc, 0, sizeof(struct inodesc)); memset(&idesc, 0, sizeof(struct inodesc));
dp = ginode(orphan); dp = ginode(orphan);
lostdir = (dp->e2di_mode & IFMT) == IFDIR; lostdir = (fs2h16(dp->e2di_mode) & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
pinode(orphan); pinode(orphan);
if (preen && dp->e2di_size == 0) if (preen && fs2h32(dp->e2di_size) == 0)
return (0); return (0);
if (preen) if (preen)
printf(" (RECONNECTED)\n"); printf(" (RECONNECTED)\n");
@ -415,7 +417,7 @@ linkup(orphan, parentdir)
} }
} }
dp = ginode(lfdir); dp = ginode(lfdir);
if ((dp->e2di_mode & IFMT) != IFDIR) { if ((fs2h16(dp->e2di_mode) & IFMT) != IFDIR) {
pfatal("lost+found IS NOT A DIRECTORY"); pfatal("lost+found IS NOT A DIRECTORY");
if (reply("REALLOCATE") == 0) if (reply("REALLOCATE") == 0)
return (0); return (0);
@ -452,7 +454,7 @@ linkup(orphan, parentdir)
parentdir != (ino_t)-1) parentdir != (ino_t)-1)
(void)makeentry(orphan, lfdir, ".."); (void)makeentry(orphan, lfdir, "..");
dp = ginode(lfdir); dp = ginode(lfdir);
dp->e2di_nlink++; dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) +1);
inodirty(); inodirty();
lncntp[lfdir]++; lncntp[lfdir]++;
pwarn("DIR I=%u CONNECTED. ", orphan); pwarn("DIR I=%u CONNECTED. ", orphan);
@ -509,8 +511,9 @@ makeentry(parent, ino, name)
idesc.id_fix = DONTKNOW; idesc.id_fix = DONTKNOW;
idesc.id_name = name; idesc.id_name = name;
dp = ginode(parent); dp = ginode(parent);
if (dp->e2di_size % sblock.e2fs_bsize) { if (fs2h32(dp->e2di_size) % sblock.e2fs_bsize) {
dp->e2di_size = roundup(dp->e2di_size, sblock.e2fs_bsize); dp->e2di_size =
h2fs32(roundup(fs2h32(dp->e2di_size), sblock.e2fs_bsize));
inodirty(); inodirty();
} }
if ((ckinode(dp, &idesc) & ALTERED) != 0) if ((ckinode(dp, &idesc) & ALTERED) != 0)
@ -532,24 +535,24 @@ expanddir(dp, name)
{ {
daddr_t lastbn, newblk; daddr_t lastbn, newblk;
struct bufarea *bp; struct bufarea *bp;
char *cp, *firstblk; char *firstblk;
if ((firstblk = malloc(sblock.e2fs_bsize)) == NULL) { if ((firstblk = malloc(sblock.e2fs_bsize)) == NULL) {
fprintf(stderr, "out of memory"); fprintf(stderr, "out of memory");
exit(8); exit(8);
} }
lastbn = lblkno(&sblock, dp->e2di_size); lastbn = lblkno(&sblock, fs2h32(dp->e2di_size));
if (lastbn >= NDADDR - 1 || dp->e2di_blocks[lastbn] == 0 || if (lastbn >= NDADDR - 1 || fs2h32(dp->e2di_blocks[lastbn]) == 0 ||
dp->e2di_size == 0) fs2h32(dp->e2di_size) == 0)
return (0); return (0);
if ((newblk = allocblk()) == 0) if ((newblk = allocblk()) == 0)
return (0); return (0);
dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn]; dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn];
dp->e2di_blocks[lastbn] = newblk; dp->e2di_blocks[lastbn] = h2fs32(newblk);
dp->e2di_size += sblock.e2fs_bsize; dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) + sblock.e2fs_bsize);
dp->e2di_nblock += 1; dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) + 1);
bp = getdirblk(dp->e2di_blocks[lastbn + 1], bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]),
sblock.e2fs_bsize); sblock.e2fs_bsize);
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
@ -558,16 +561,12 @@ expanddir(dp, name)
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
memcpy(bp->b_un.b_buf, firstblk, sblock.e2fs_bsize); memcpy(bp->b_un.b_buf, firstblk, sblock.e2fs_bsize);
emptydir.dot_reclen = sblock.e2fs_bsize;
for (cp = &bp->b_un.b_buf[sblock.e2fs_bsize];
cp < &bp->b_un.b_buf[sblock.e2fs_bsize];
cp += sblock.e2fs_bsize)
memcpy(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
bp = getdirblk(dp->e2di_blocks[lastbn + 1], bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]),
sblock.e2fs_bsize); sblock.e2fs_bsize);
if (bp->b_errs) if (bp->b_errs)
goto bad; goto bad;
emptydir.dot_reclen = h2fs16(sblock.e2fs_bsize);
memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir); memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir);
pwarn("NO SPACE LEFT IN %s", name); pwarn("NO SPACE LEFT IN %s", name);
if (preen) if (preen)
@ -580,8 +579,8 @@ expanddir(dp, name)
bad: bad:
dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1]; dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1];
dp->e2di_blocks[lastbn + 1] = 0; dp->e2di_blocks[lastbn + 1] = 0;
dp->e2di_size -= sblock.e2fs_bsize; dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - sblock.e2fs_bsize);
dp->e2di_nblock -= sblock.e2fs_bsize; dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) - 1);
freeblk(newblk); freeblk(newblk);
return (0); return (0);
} }
@ -595,34 +594,30 @@ allocdir(parent, request, mode)
int mode; int mode;
{ {
ino_t ino; ino_t ino;
char *cp;
struct ext2fs_dinode *dp; struct ext2fs_dinode *dp;
struct bufarea *bp; struct bufarea *bp;
struct ext2fs_dirtemplate *dirp; struct ext2fs_dirtemplate *dirp;
ino = allocino(request, IFDIR|mode); ino = allocino(request, IFDIR|mode);
dirhead.dot_reclen = 12; /* XXX */ dirhead.dot_reclen = h2fs16(12); /* XXX */
dirhead.dotdot_reclen = sblock.e2fs_bsize - 12; /* XXX */ dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */
dirhead.dot_namlen = h2fs16(1);
dirhead.dotdot_namlen = h2fs16(2);
dirp = &dirhead; dirp = &dirhead;
dirp->dot_ino = ino; dirp->dot_ino = h2fs32(ino);
dirp->dotdot_ino = parent; dirp->dotdot_ino = h2fs32(parent);
dp = ginode(ino); dp = ginode(ino);
bp = getdirblk(dp->e2di_blocks[0], sblock.e2fs_bsize); bp = getdirblk(fs2h32(dp->e2di_blocks[0]), sblock.e2fs_bsize);
if (bp->b_errs) { if (bp->b_errs) {
freeino(ino); freeino(ino);
return (0); return (0);
} }
emptydir.dot_reclen = sblock.e2fs_bsize;
memcpy(bp->b_un.b_buf, dirp, sizeof(struct ext2fs_dirtemplate)); memcpy(bp->b_un.b_buf, dirp, sizeof(struct ext2fs_dirtemplate));
for (cp = &bp->b_un.b_buf[sblock.e2fs_bsize];
cp < &bp->b_un.b_buf[sblock.e2fs_bsize];
cp += sblock.e2fs_bsize)
memcpy(cp, &emptydir, sizeof emptydir);
dirty(bp); dirty(bp);
dp->e2di_nlink = 2; dp->e2di_nlink = h2fs16(2);
inodirty(); inodirty();
if (ino == EXT2_ROOTINO) { if (ino == EXT2_ROOTINO) {
lncntp[ino] = dp->e2di_nlink; lncntp[ino] = fs2h16(dp->e2di_nlink);
cacheino(dp, ino); cacheino(dp, ino);
return(ino); return(ino);
} }
@ -633,11 +628,11 @@ allocdir(parent, request, mode)
cacheino(dp, ino); cacheino(dp, ino);
statemap[ino] = statemap[parent]; statemap[ino] = statemap[parent];
if (statemap[ino] == DSTATE) { if (statemap[ino] == DSTATE) {
lncntp[ino] = dp->e2di_nlink; lncntp[ino] = fs2h16(dp->e2di_nlink);
lncntp[parent]++; lncntp[parent]++;
} }
dp = ginode(parent); dp = ginode(parent);
dp->e2di_nlink++; dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) + 1);
inodirty(); inodirty();
return (ino); return (ino);
} }
@ -653,7 +648,7 @@ freedir(ino, parent)
if (ino != parent) { if (ino != parent) {
dp = ginode(parent); dp = ginode(parent);
dp->e2di_nlink--; dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - 1);
inodirty(); inodirty();
} }
freeino(ino); freeino(ino);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsck.h,v 1.1 1997/06/11 11:21:47 bouyer Exp $ */ /* $NetBSD: fsck.h,v 1.2 1997/10/09 13:19:35 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -65,7 +65,7 @@ struct bufarea {
union { union {
char *b_buf; /* buffer space */ char *b_buf; /* buffer space */
daddr_t *b_indir; /* indirect block */ daddr_t *b_indir; /* indirect block */
struct m_ext2fs *b_fs; /* super block */ struct ext2fs *b_fs; /* super block */
struct ext2_gd *b_cgd; /* cylinder group descriptor */ struct ext2_gd *b_cgd; /* cylinder group descriptor */
struct ext2fs_dinode *b_dinode; /* inode block */ struct ext2fs_dinode *b_dinode; /* inode block */
} b_un; } b_un;
@ -77,9 +77,11 @@ struct bufarea {
#define MINBUFS 5 /* minimum number of buffers required */ #define MINBUFS 5 /* minimum number of buffers required */
struct bufarea bufhead; /* head of list of other blks in filesys */ struct bufarea bufhead; /* head of list of other blks in filesys */
struct bufarea sblk; /* file system superblock */ struct bufarea sblk; /* file system superblock */
struct bufarea asblk; /* first alternate superblock */
struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */ struct bufarea *pbp; /* current inode block */
struct bufarea *getdatablk __P((daddr_t, long)); struct bufarea *getdatablk __P((daddr_t, long));
struct m_ext2fs sblock;
#define dirty(bp) (bp)->b_dirty = 1 #define dirty(bp) (bp)->b_dirty = 1
#define initbarea(bp) \ #define initbarea(bp) \
@ -87,10 +89,7 @@ struct bufarea *getdatablk __P((daddr_t, long));
(bp)->b_bno = (daddr_t)-1; \ (bp)->b_bno = (daddr_t)-1; \
(bp)->b_flags = 0; (bp)->b_flags = 0;
#define sbdirty() sblk.b_dirty = 1 #define sbdirty() copyback_sb(&sblk); sblk.b_dirty = 1
#define cgdirty() cgblk.b_dirty = 1
#define sblock (*sblk.b_un.b_fs)
#define cgrp (*cgblk.b_un.b_cg)
enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
@ -211,3 +210,4 @@ struct ext2fs_dinode *ginode __P((ino_t));
struct inoinfo *getinoinfo __P((ino_t)); struct inoinfo *getinoinfo __P((ino_t));
void getblk __P((struct bufarea *, daddr_t, long)); void getblk __P((struct bufarea *, daddr_t, long));
ino_t allocino __P((ino_t, int)); ino_t allocino __P((ino_t, int));
void copyback_sb __P((struct bufarea*));

View File

@ -1,4 +1,4 @@
/* $NetBSD: inode.c,v 1.2 1997/09/14 14:27:24 lukem Exp $ */ /* $NetBSD: inode.c,v 1.3 1997/10/09 13:19:36 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
#else #else
__RCSID("$NetBSD: inode.c,v 1.2 1997/09/14 14:27:24 lukem Exp $"); __RCSID("$NetBSD: inode.c,v 1.3 1997/10/09 13:19:36 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -61,6 +61,16 @@ __RCSID("$NetBSD: inode.c,v 1.2 1997/09/14 14:27:24 lukem Exp $");
#include "fsutil.h" #include "fsutil.h"
#include "extern.h" #include "extern.h"
/*
* CG is stored in fs byte order in memory, so we can't use ino_to_fsba
* here.
*/
#define fsck_ino_to_fsba(fs, x) \
(fs2h32((fs)->e2fs_gd[ino_to_cg(fs, x)].ext2bgd_i_tables) + \
(((x)-1) % (fs)->e2fs.e2fs_ipg)/(fs)->e2fs_ipb)
static ino_t startinum; static ino_t startinum;
static int iblock __P((struct inodesc *, long, u_int64_t)); static int iblock __P((struct inodesc *, long, u_int64_t));
@ -80,13 +90,13 @@ ckinode(dp, idesc)
if (idesc->id_fix != IGNORE) if (idesc->id_fix != IGNORE)
idesc->id_fix = DONTKNOW; idesc->id_fix = DONTKNOW;
idesc->id_entryno = 0; idesc->id_entryno = 0;
idesc->id_filesize = dp->e2di_size; idesc->id_filesize = fs2h32(dp->e2di_size);
mode = dp->e2di_mode & IFMT; mode = fs2h16(dp->e2di_mode) & IFMT;
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
(dp->e2di_size < EXT2_MAXSYMLINKLEN))) (fs2h32(dp->e2di_size) < EXT2_MAXSYMLINKLEN)))
return (KEEPON); return (KEEPON);
dino = *dp; dino = *dp;
ndb = howmany(dino.e2di_size, sblock.e2fs_bsize); ndb = howmany(fs2h32(dino.e2di_size), sblock.e2fs_bsize);
for (ap = &dino.e2di_blocks[0]; ap < &dino.e2di_blocks[NDADDR]; for (ap = &dino.e2di_blocks[0]; ap < &dino.e2di_blocks[NDADDR];
ap++,ndb--) { ap++,ndb--) {
idesc->id_numfrags = 1; idesc->id_numfrags = 1;
@ -99,8 +109,8 @@ ckinode(dp, idesc)
pathbuf); pathbuf);
if (reply("ADJUST LENGTH") == 1) { if (reply("ADJUST LENGTH") == 1) {
dp = ginode(idesc->id_number); dp = ginode(idesc->id_number);
dp->e2di_size = (ap - &dino.e2di_blocks[0]) * dp->e2di_size = h2fs32((ap - &dino.e2di_blocks[0]) *
sblock.e2fs_bsize; sblock.e2fs_bsize);
printf( printf(
"YOU MUST RERUN FSCK AFTERWARDS\n"); "YOU MUST RERUN FSCK AFTERWARDS\n");
rerun = 1; rerun = 1;
@ -109,7 +119,7 @@ ckinode(dp, idesc)
} }
continue; continue;
} }
idesc->id_blkno = *ap; idesc->id_blkno = fs2h32(*ap);
if (idesc->id_type == ADDR) if (idesc->id_type == ADDR)
ret = (*idesc->id_func)(idesc); ret = (*idesc->id_func)(idesc);
else else
@ -118,11 +128,11 @@ ckinode(dp, idesc)
return (ret); return (ret);
} }
idesc->id_numfrags = 1; idesc->id_numfrags = 1;
remsize = dino.e2di_size - sblock.e2fs_bsize * NDADDR; remsize = fs2h32(dino.e2di_size) - sblock.e2fs_bsize * NDADDR;
sizepb = sblock.e2fs_bsize; sizepb = sblock.e2fs_bsize;
for (ap = &dino.e2di_blocks[NDADDR], n = 1; n <= NIADDR; ap++, n++) { for (ap = &dino.e2di_blocks[NDADDR], n = 1; n <= NIADDR; ap++, n++) {
if (*ap) { if (*ap) {
idesc->id_blkno = *ap; idesc->id_blkno = fs2h32(*ap);
ret = iblock(idesc, n, remsize); ret = iblock(idesc, n, remsize);
if (ret & STOP) if (ret & STOP)
return (ret); return (ret);
@ -135,7 +145,7 @@ ckinode(dp, idesc)
pathbuf); pathbuf);
if (reply("ADJUST LENGTH") == 1) { if (reply("ADJUST LENGTH") == 1) {
dp = ginode(idesc->id_number); dp = ginode(idesc->id_number);
dp->e2di_size -= remsize; dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - remsize);
remsize = 0; remsize = 0;
printf( printf(
"YOU MUST RERUN FSCK AFTERWARDS\n"); "YOU MUST RERUN FSCK AFTERWARDS\n");
@ -200,7 +210,7 @@ iblock(idesc, ilevel, isize)
aplim = &bp->b_un.b_indir[nif]; aplim = &bp->b_un.b_indir[nif];
for (ap = bp->b_un.b_indir; ap < aplim; ap++) { for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
if (*ap) { if (*ap) {
idesc->id_blkno = *ap; idesc->id_blkno = fs2h32(*ap);
if (ilevel == 0) if (ilevel == 0)
n = (*func)(idesc); n = (*func)(idesc);
else else
@ -218,7 +228,7 @@ iblock(idesc, ilevel, isize)
pathbuf); pathbuf);
if (reply("ADJUST LENGTH") == 1) { if (reply("ADJUST LENGTH") == 1) {
dp = ginode(idesc->id_number); dp = ginode(idesc->id_number);
dp->e2di_size -= isize; dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - isize);
isize = 0; isize = 0;
printf( printf(
"YOU MUST RERUN FSCK AFTERWARDS\n"); "YOU MUST RERUN FSCK AFTERWARDS\n");
@ -294,7 +304,7 @@ ginode(inumber)
errexit("bad inode number %d to ginode\n", inumber); errexit("bad inode number %d to ginode\n", inumber);
if (startinum == 0 || if (startinum == 0 ||
inumber < startinum || inumber >= startinum + sblock.e2fs_ipb) { inumber < startinum || inumber >= startinum + sblock.e2fs_ipb) {
iblk = ino_to_fsba(&sblock, inumber); iblk = fsck_ino_to_fsba(&sblock, inumber);
if (pbp != 0) if (pbp != 0)
pbp->b_flags &= ~B_INUSE; pbp->b_flags &= ~B_INUSE;
pbp = getdatablk(iblk, sblock.e2fs_bsize); pbp = getdatablk(iblk, sblock.e2fs_bsize);
@ -323,7 +333,7 @@ getnextinode(inumber)
errexit("bad inode number %d to nextinode\n", inumber); errexit("bad inode number %d to nextinode\n", inumber);
if (inumber >= lastinum) { if (inumber >= lastinum) {
readcnt++; readcnt++;
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); dblk = fsbtodb(&sblock, fsck_ino_to_fsba(&sblock, lastinum));
if (readcnt % readpercg == 0) { if (readcnt % readpercg == 0) {
size = partialsize; size = partialsize;
lastinum += partialcnt; lastinum += partialcnt;
@ -389,7 +399,7 @@ cacheino(dp, inumber)
struct inoinfo **inpp; struct inoinfo **inpp;
unsigned int blks; unsigned int blks;
blks = howmany(dp->e2di_size, sblock.e2fs_bsize); blks = howmany(fs2h32(dp->e2di_size), sblock.e2fs_bsize);
if (blks > NDADDR) if (blks > NDADDR)
blks = NDADDR + NIADDR; blks = NDADDR + NIADDR;
inp = (struct inoinfo *) inp = (struct inoinfo *)
@ -406,7 +416,7 @@ cacheino(dp, inumber)
inp->i_parent = (ino_t)0; inp->i_parent = (ino_t)0;
inp->i_dotdot = (ino_t)0; inp->i_dotdot = (ino_t)0;
inp->i_number = inumber; inp->i_number = inumber;
inp->i_isize = dp->e2di_size; inp->i_isize = fs2h32(dp->e2di_size);
inp->i_numblks = blks * sizeof(daddr_t); inp->i_numblks = blks * sizeof(daddr_t);
memcpy(&inp->i_blks[0], &dp->e2di_blocks[0], (size_t)inp->i_numblks); memcpy(&inp->i_blks[0], &dp->e2di_blocks[0], (size_t)inp->i_numblks);
if (inplast == listmax) { if (inplast == listmax) {
@ -491,11 +501,12 @@ findname(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
struct ext2fs_direct *dirp = idesc->id_dirp; struct ext2fs_direct *dirp = idesc->id_dirp;
u_int16_t namlen = fs2h16(dirp->e2d_namlen);
if (dirp->e2d_ino != idesc->id_parent) if (fs2h32(dirp->e2d_ino) != idesc->id_parent)
return (KEEPON); return (KEEPON);
memcpy(idesc->id_name, dirp->e2d_name, (size_t)dirp->e2d_namlen); memcpy(idesc->id_name, dirp->e2d_name, (size_t)namlen);
idesc->id_name[dirp->e2d_namlen] = '\0'; idesc->id_name[namlen] = '\0';
return (STOP|FOUND); return (STOP|FOUND);
} }
@ -504,13 +515,14 @@ findino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
struct ext2fs_direct *dirp = idesc->id_dirp; struct ext2fs_direct *dirp = idesc->id_dirp;
u_int32_t ino = fs2h32(dirp->e2d_ino);
if (dirp->e2d_ino == 0) if (ino == 0)
return (KEEPON); return (KEEPON);
if (strcmp(dirp->e2d_name, idesc->id_name) == 0 && if (strcmp(dirp->e2d_name, idesc->id_name) == 0 &&
(dirp->e2d_ino == EXT2_ROOTINO || dirp->e2d_ino >= EXT2_FIRSTINO) (ino == EXT2_ROOTINO || ino >= EXT2_FIRSTINO)
&& dirp->e2d_ino <= maxino) { && ino <= maxino) {
idesc->id_parent = dirp->e2d_ino; idesc->id_parent = ino;
return (STOP|FOUND); return (STOP|FOUND);
} }
return (KEEPON); return (KEEPON);
@ -535,12 +547,12 @@ pinode(ino)
printf("%s ", pw->pw_name); printf("%s ", pw->pw_name);
else else
#endif #endif
printf("%u ", (unsigned)dp->e2di_uid); printf("%u ", (unsigned)fs2h16(dp->e2di_uid));
printf("MODE=%o\n", dp->e2di_mode); printf("MODE=%o\n", fs2h16(dp->e2di_mode));
if (preen) if (preen)
printf("%s: ", cdevname()); printf("%s: ", cdevname());
printf("SIZE=%u ", dp->e2di_size); printf("SIZE=%u ", fs2h32(dp->e2di_size));
t = dp->e2di_mtime; t = fs2h32(dp->e2di_mtime);
p = ctime(&t); p = ctime(&t);
printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
} }
@ -610,18 +622,18 @@ allocino(request, type)
return (0); return (0);
} }
dp = ginode(ino); dp = ginode(ino);
dp->e2di_blocks[0] = allocblk(); dp->e2di_blocks[0] = h2fs32(allocblk());
if (dp->e2di_blocks[0] == 0) { if (dp->e2di_blocks[0] == 0) {
statemap[ino] = USTATE; statemap[ino] = USTATE;
return (0); return (0);
} }
dp->e2di_mode = type; dp->e2di_mode = h2fs16(type);
(void)time(&t); (void)time(&t);
dp->e2di_atime = t; dp->e2di_atime = h2fs32(t);
dp->e2di_mtime = dp->e2di_ctime = dp->e2di_atime; dp->e2di_mtime = dp->e2di_ctime = dp->e2di_atime;
dp->e2di_dtime = 0; dp->e2di_dtime = 0;
dp->e2di_size = sblock.e2fs_bsize; dp->e2di_size = h2fs32(sblock.e2fs_bsize);
dp->e2di_nblock = btodb(sblock.e2fs_bsize); dp->e2di_nblock = h2fs32(btodb(sblock.e2fs_bsize));
n_files++; n_files++;
inodirty(); inodirty();
return (ino); return (ino);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass1.c,v 1.3 1997/09/14 14:27:26 lukem Exp $ */ /* $NetBSD: pass1.c,v 1.4 1997/10/09 13:19:37 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93";
#else #else
__RCSID("$NetBSD: pass1.c,v 1.3 1997/09/14 14:27:26 lukem Exp $"); __RCSID("$NetBSD: pass1.c,v 1.4 1997/10/09 13:19:37 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -118,7 +118,7 @@ checkinode(inumber, idesc)
if (inumber < EXT2_FIRSTINO && inumber != EXT2_ROOTINO) if (inumber < EXT2_FIRSTINO && inumber != EXT2_ROOTINO)
return; return;
mode = dp->e2di_mode & IFMT; mode = fs2h16(dp->e2di_mode) & IFMT;
if (mode == 0 || (dp->e2di_dtime != 0 && dp->e2di_nlink == 0)) { if (mode == 0 || (dp->e2di_dtime != 0 && dp->e2di_nlink == 0)) {
if (mode == 0 && ( if (mode == 0 && (
memcmp(dp->e2di_blocks, zino.e2di_blocks, memcmp(dp->e2di_blocks, zino.e2di_blocks,
@ -140,7 +140,7 @@ checkinode(inumber, idesc)
if (preen || reply("CORRECT")) { if (preen || reply("CORRECT")) {
time_t t; time_t t;
time(&t); time(&t);
dp->e2di_dtime = t; dp->e2di_dtime = h2fs32(t);
dp = ginode(inumber); dp = ginode(inumber);
inodirty(); inodirty();
} }
@ -151,7 +151,7 @@ checkinode(inumber, idesc)
} }
lastino = inumber; lastino = inumber;
if (dp->e2di_dtime != 0) { if (dp->e2di_dtime != 0) {
time_t t = dp->e2di_dtime; time_t t = fs2h32(dp->e2di_dtime);
char *p = ctime(&t); char *p = ctime(&t);
pwarn("INODE I=%u HAS DTIME=%12.12s %4.4s", inumber, &p[4], &p[20]); pwarn("INODE I=%u HAS DTIME=%12.12s %4.4s", inumber, &p[4], &p[20]);
if (preen) { if (preen) {
@ -164,22 +164,23 @@ checkinode(inumber, idesc)
} }
} }
if (/* dp->di_size < 0 || */ if (/* dp->di_size < 0 || */
dp->e2di_size + sblock.e2fs_bsize - 1 < dp->e2di_size) { fs2h32(dp->e2di_size) + sblock.e2fs_bsize - 1 <
fs2h32(dp->e2di_size)) {
if (debug) if (debug)
printf("bad size %lu:", (u_long)dp->e2di_size); printf("bad size %lu:", (u_long)fs2h32(dp->e2di_size));
goto unknown; goto unknown;
} }
if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
dp = ginode(inumber); dp = ginode(inumber);
dp->e2di_size = sblock.e2fs_bsize; dp->e2di_size = h2fs32(sblock.e2fs_bsize);
dp->e2di_mode = IFREG|0600; dp->e2di_mode = h2fs16(IFREG|0600);
inodirty(); inodirty();
} }
ndb = howmany(dp->e2di_size, sblock.e2fs_bsize); ndb = howmany(fs2h32(dp->e2di_size), sblock.e2fs_bsize);
if (ndb < 0) { if (ndb < 0) {
if (debug) if (debug)
printf("bad size %lu ndb %d:", printf("bad size %lu ndb %d:",
(u_long)dp->e2di_size, ndb); (u_long)fs2h32(dp->e2di_size), ndb);
goto unknown; goto unknown;
} }
if (mode == IFBLK || mode == IFCHR) if (mode == IFBLK || mode == IFCHR)
@ -189,9 +190,9 @@ checkinode(inumber, idesc)
* Fake ndb value so direct/indirect block checks below * Fake ndb value so direct/indirect block checks below
* will detect any garbage after symlink string. * will detect any garbage after symlink string.
*/ */
if (dp->e2di_size < EXT2_MAXSYMLINKLEN || if (fs2h32(dp->e2di_size) < EXT2_MAXSYMLINKLEN ||
(EXT2_MAXSYMLINKLEN == 0 && dp->e2di_blocks == 0)) { (EXT2_MAXSYMLINKLEN == 0 && dp->e2di_blocks == 0)) {
ndb = howmany(dp->e2di_size, sizeof(u_int32_t)); ndb = howmany(fs2h32(dp->e2di_size), sizeof(u_int32_t));
if (ndb > NDADDR) { if (ndb > NDADDR) {
j = ndb - NDADDR; j = ndb - NDADDR;
for (ndb = 1; j > 1; j--) for (ndb = 1; j > 1; j--)
@ -203,7 +204,7 @@ checkinode(inumber, idesc)
for (j = ndb; j < NDADDR; j++) for (j = ndb; j < NDADDR; j++)
if (dp->e2di_blocks[j] != 0) { if (dp->e2di_blocks[j] != 0) {
if (debug) if (debug)
printf("bad direct addr: %d\n", dp->e2di_blocks[j]); printf("bad direct addr: %d\n", fs2h32(dp->e2di_blocks[j]));
goto unknown; goto unknown;
} }
for (j = 0, ndb -= NDADDR; ndb > 0; j++) for (j = 0, ndb -= NDADDR; ndb > 0; j++)
@ -212,14 +213,14 @@ checkinode(inumber, idesc)
if (dp->e2di_blocks[j+NDADDR] != 0) { if (dp->e2di_blocks[j+NDADDR] != 0) {
if (debug) if (debug)
printf("bad indirect addr: %d\n", printf("bad indirect addr: %d\n",
dp->e2di_blocks[j+NDADDR]); fs2h32(dp->e2di_blocks[j+NDADDR]));
goto unknown; goto unknown;
} }
if (ftypeok(dp) == 0) if (ftypeok(dp) == 0)
goto unknown; goto unknown;
n_files++; n_files++;
lncntp[inumber] = dp->e2di_nlink; lncntp[inumber] = fs2h16(dp->e2di_nlink);
if (dp->e2di_nlink <= 0) { if (dp->e2di_nlink == 0) {
zlnp = (struct zlncnt *)malloc(sizeof *zlnp); zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
if (zlnp == NULL) { if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW"); pfatal("LINK COUNT TABLE OVERFLOW");
@ -244,15 +245,15 @@ checkinode(inumber, idesc)
idesc->id_number = inumber; idesc->id_number = inumber;
(void)ckinode(dp, idesc); (void)ckinode(dp, idesc);
idesc->id_entryno *= btodb(sblock.e2fs_bsize); idesc->id_entryno *= btodb(sblock.e2fs_bsize);
if (dp->e2di_nblock != idesc->id_entryno) { if (fs2h32(dp->e2di_nblock) != idesc->id_entryno) {
pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)", pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)",
inumber, dp->e2di_nblock, idesc->id_entryno); inumber, fs2h32(dp->e2di_nblock), idesc->id_entryno);
if (preen) if (preen)
printf(" (CORRECTED)\n"); printf(" (CORRECTED)\n");
else if (reply("CORRECT") == 0) else if (reply("CORRECT") == 0)
return; return;
dp = ginode(inumber); dp = ginode(inumber);
dp->e2di_nblock = idesc->id_entryno; dp->e2di_nblock = h2fs32(idesc->id_entryno);
inodirty(); inodirty();
} }
return; return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass2.c,v 1.3 1997/09/16 08:37:03 mrg Exp $ */ /* $NetBSD: pass2.c,v 1.4 1997/10/09 13:19:38 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94";
#else #else
__RCSID("$NetBSD: pass2.c,v 1.3 1997/09/16 08:37:03 mrg Exp $"); __RCSID("$NetBSD: pass2.c,v 1.4 1997/10/09 13:19:38 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -108,8 +108,7 @@ pass2()
if (reply("FIX") == 0) if (reply("FIX") == 0)
errexit("%s\n", ""); errexit("%s\n", "");
dp = ginode(EXT2_ROOTINO); dp = ginode(EXT2_ROOTINO);
dp->e2di_mode &= ~IFMT; dp->e2di_mode = h2fs16((fs2h16(dp->e2di_mode) & ~IFMT) | IFDIR);
dp->e2di_mode |= IFDIR;
inodirty(); inodirty();
break; break;
@ -140,7 +139,7 @@ pass2()
inp->i_isize = roundup(MINDIRSIZE, sblock.e2fs_bsize); inp->i_isize = roundup(MINDIRSIZE, sblock.e2fs_bsize);
if (reply("FIX") == 1) { if (reply("FIX") == 1) {
dp = ginode(inp->i_number); dp = ginode(inp->i_number);
dp->e2di_size = inp->i_isize; dp->e2di_size = h2fs32(inp->i_isize);
inodirty(); inodirty();
} }
} else if ((inp->i_isize & (sblock.e2fs_bsize - 1)) != 0) { } else if ((inp->i_isize & (sblock.e2fs_bsize - 1)) != 0) {
@ -152,13 +151,13 @@ pass2()
inp->i_isize = roundup(inp->i_isize, sblock.e2fs_bsize); inp->i_isize = roundup(inp->i_isize, sblock.e2fs_bsize);
if (preen || reply("ADJUST") == 1) { if (preen || reply("ADJUST") == 1) {
dp = ginode(inp->i_number); dp = ginode(inp->i_number);
dp->e2di_size = inp->i_isize; dp->e2di_size = h2fs32(inp->i_isize);
inodirty(); inodirty();
} }
} }
memset(&dino, 0, sizeof(struct ext2fs_dinode)); memset(&dino, 0, sizeof(struct ext2fs_dinode));
dino.e2di_mode = IFDIR; dino.e2di_mode = h2fs16(IFDIR);
dino.e2di_size = inp->i_isize; dino.e2di_size = h2fs32(inp->i_isize);
memcpy(&dino.e2di_blocks[0], &inp->i_blks[0], (size_t)inp->i_numblks); memcpy(&dino.e2di_blocks[0], &inp->i_blks[0], (size_t)inp->i_numblks);
curino.id_number = inp->i_number; curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent; curino.id_parent = inp->i_parent;
@ -217,40 +216,40 @@ pass2check(idesc)
*/ */
if (idesc->id_entryno != 0) if (idesc->id_entryno != 0)
goto chk1; goto chk1;
if (dirp->e2d_ino != 0 && dirp->e2d_namlen == 1 && if (fs2h32(dirp->e2d_ino) != 0 && fs2h16(dirp->e2d_namlen) == 1 &&
dirp->e2d_name[0] == '.') { dirp->e2d_name[0] == '.') {
if (dirp->e2d_ino != idesc->id_number) { if (fs2h32(dirp->e2d_ino) != idesc->id_number) {
direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'"); direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
dirp->e2d_ino = idesc->id_number; dirp->e2d_ino = h2fs32(idesc->id_number);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
goto chk1; goto chk1;
} }
direrror(idesc->id_number, "MISSING '.'"); direrror(idesc->id_number, "MISSING '.'");
proto.e2d_ino = idesc->id_number; proto.e2d_ino = h2fs32(idesc->id_number);
proto.e2d_namlen = 1; proto.e2d_namlen = h2fs16(1);
(void)strcpy(proto.e2d_name, "."); (void)strcpy(proto.e2d_name, ".");
entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen); entrysize = EXT2FS_DIRSIZ(fs2h16(proto.e2d_namlen));
if (dirp->e2d_ino != 0 && strcmp(dirp->e2d_name, "..") != 0) { if (fs2h32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
dirp->e2d_name); dirp->e2d_name);
} else if (dirp->e2d_reclen < entrysize) { } else if (fs2h16(dirp->e2d_reclen) < entrysize) {
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
} else if (dirp->e2d_reclen < 2 * entrysize) { } else if (fs2h16(dirp->e2d_reclen) < 2 * entrysize) {
proto.e2d_reclen = dirp->e2d_reclen; proto.e2d_reclen = dirp->e2d_reclen;
memcpy(dirp, &proto, (size_t)entrysize); memcpy(dirp, &proto, (size_t)entrysize);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} else { } else {
n = dirp->e2d_reclen - entrysize; n = fs2h16(dirp->e2d_reclen) - entrysize;
proto.e2d_reclen = entrysize; proto.e2d_reclen = h2fs16(entrysize);
memcpy(dirp, &proto, (size_t)entrysize); memcpy(dirp, &proto, (size_t)entrysize);
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->e2d_ino]--; lncntp[fs2h32(dirp->e2d_ino)]--;
dirp = (struct ext2fs_direct *)((char *)(dirp) + entrysize); dirp = (struct ext2fs_direct *)((char *)(dirp) + entrysize);
memset(dirp, 0, (size_t)n); memset(dirp, 0, (size_t)n);
dirp->e2d_reclen = n; dirp->e2d_reclen = h2fs16(n);
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
@ -258,36 +257,36 @@ chk1:
if (idesc->id_entryno > 1) if (idesc->id_entryno > 1)
goto chk2; goto chk2;
inp = getinoinfo(idesc->id_number); inp = getinoinfo(idesc->id_number);
proto.e2d_ino = inp->i_parent; proto.e2d_ino = h2fs32(inp->i_parent);
proto.e2d_namlen = 2; proto.e2d_namlen = h2fs16(2);
(void)strcpy(proto.e2d_name, ".."); (void)strcpy(proto.e2d_name, "..");
entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen); entrysize = EXT2FS_DIRSIZ(2);
if (idesc->id_entryno == 0) { if (idesc->id_entryno == 0) {
n = EXT2FS_DIRSIZ(dirp->e2d_namlen); n = EXT2FS_DIRSIZ(fs2h16(dirp->e2d_namlen));
if (dirp->e2d_reclen < n + entrysize) if (fs2h16(dirp->e2d_reclen) < n + entrysize)
goto chk2; goto chk2;
proto.e2d_reclen = dirp->e2d_reclen - n; proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n);
dirp->e2d_reclen = n; dirp->e2d_reclen = h2fs16(n);
idesc->id_entryno++; idesc->id_entryno++;
lncntp[dirp->e2d_ino]--; lncntp[fs2h32(dirp->e2d_ino)]--;
dirp = (struct ext2fs_direct *)((char *)(dirp) + n); dirp = (struct ext2fs_direct *)((char *)(dirp) + n);
memset(dirp, 0, (size_t)proto.e2d_reclen); memset(dirp, 0, (size_t)fs2h16(proto.e2d_reclen));
dirp->e2d_reclen = proto.e2d_reclen; dirp->e2d_reclen = proto.e2d_reclen;
} }
if (dirp->e2d_ino != 0 && if (fs2h32(dirp->e2d_ino) != 0 &&
dirp->e2d_namlen == 2 && fs2h16(dirp->e2d_namlen) == 2 &&
strncmp(dirp->e2d_name, "..", dirp->e2d_namlen) == 0) { strncmp(dirp->e2d_name, "..", 2) == 0) {
inp->i_dotdot = dirp->e2d_ino; inp->i_dotdot = fs2h32(dirp->e2d_ino);
goto chk2; goto chk2;
} }
if (dirp->e2d_ino != 0 && if (fs2h32(dirp->e2d_ino) != 0 &&
dirp->e2d_namlen == 1 && fs2h16(dirp->e2d_namlen) == 1 &&
strncmp(dirp->e2d_name, ".", dirp->e2d_namlen) != 0) { strncmp(dirp->e2d_name, ".", 1) != 0) {
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
dirp->e2d_name); dirp->e2d_name);
inp->i_dotdot = (ino_t)-1; inp->i_dotdot = (ino_t)-1;
} else if (dirp->e2d_reclen < entrysize) { } else if (fs2h16(dirp->e2d_reclen) < entrysize) {
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
inp->i_dotdot = (ino_t)-1; inp->i_dotdot = (ino_t)-1;
@ -303,16 +302,16 @@ chk1:
ret |= ALTERED; ret |= ALTERED;
} }
idesc->id_entryno++; idesc->id_entryno++;
if (dirp->e2d_ino != 0) if (fs2h32(dirp->e2d_ino) != 0)
lncntp[dirp->e2d_ino]--; lncntp[fs2h32(dirp->e2d_ino)]--;
return (ret|KEEPON); return (ret|KEEPON);
chk2: chk2:
if (dirp->e2d_ino == 0) if (fs2h32(dirp->e2d_ino) == 0)
return (ret|KEEPON); return (ret|KEEPON);
if (dirp->e2d_namlen <= 2 && if (fs2h16(dirp->e2d_namlen) <= 2 &&
dirp->e2d_name[0] == '.' && dirp->e2d_name[0] == '.' &&
idesc->id_entryno >= 2) { idesc->id_entryno >= 2) {
if (dirp->e2d_namlen == 1) { if (fs2h16(dirp->e2d_namlen) == 1) {
direrror(idesc->id_number, "EXTRA '.' ENTRY"); direrror(idesc->id_number, "EXTRA '.' ENTRY");
dirp->e2d_ino = 0; dirp->e2d_ino = 0;
if (reply("FIX") == 1) if (reply("FIX") == 1)
@ -329,17 +328,18 @@ chk2:
} }
idesc->id_entryno++; idesc->id_entryno++;
n = 0; n = 0;
if (dirp->e2d_ino > maxino || if (fs2h32(dirp->e2d_ino) > maxino ||
(dirp->e2d_ino < EXT2_FIRSTINO && dirp->e2d_ino != EXT2_ROOTINO)) { (fs2h32(dirp->e2d_ino) < EXT2_FIRSTINO &&
fileerror(idesc->id_number, dirp->e2d_ino, "I OUT OF RANGE"); fs2h32(dirp->e2d_ino) != EXT2_ROOTINO)) {
fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "I OUT OF RANGE");
n = reply("REMOVE"); n = reply("REMOVE");
} else { } else {
again: again:
switch (statemap[dirp->e2d_ino]) { switch (statemap[fs2h32(dirp->e2d_ino)]) {
case USTATE: case USTATE:
if (idesc->id_entryno <= 2) if (idesc->id_entryno <= 2)
break; break;
fileerror(idesc->id_number, dirp->e2d_ino, "UNALLOCATED"); fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "UNALLOCATED");
n = reply("REMOVE"); n = reply("REMOVE");
break; break;
@ -347,7 +347,7 @@ again:
case FCLEAR: case FCLEAR:
if (idesc->id_entryno <= 2) if (idesc->id_entryno <= 2)
break; break;
if (statemap[dirp->e2d_ino] == FCLEAR) if (statemap[fs2h32(dirp->e2d_ino)] == FCLEAR)
errmsg = "DUP/BAD"; errmsg = "DUP/BAD";
else if (!preen) else if (!preen)
errmsg = "ZERO LENGTH DIRECTORY"; errmsg = "ZERO LENGTH DIRECTORY";
@ -355,22 +355,23 @@ again:
n = 1; n = 1;
break; break;
} }
fileerror(idesc->id_number, dirp->e2d_ino, errmsg); fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), errmsg);
if ((n = reply("REMOVE")) == 1) if ((n = reply("REMOVE")) == 1)
break; break;
dp = ginode(dirp->e2d_ino); dp = ginode(fs2h32(dirp->e2d_ino));
statemap[dirp->e2d_ino] = statemap[fs2h32(dirp->e2d_ino)] =
(dp->e2di_mode & IFMT) == IFDIR ? DSTATE : FSTATE; (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE;
lncntp[dirp->e2d_ino] = dp->e2di_nlink; lncntp[fs2h32(dirp->e2d_ino)] = fs2h16(dp->e2di_nlink);
goto again; goto again;
case DSTATE: case DSTATE:
case DFOUND: case DFOUND:
inp = getinoinfo(dirp->e2d_ino); inp = getinoinfo(fs2h32(dirp->e2d_ino));
if (inp->i_parent != 0 && idesc->id_entryno > 2) { if (inp->i_parent != 0 && idesc->id_entryno > 2) {
getpathname(pathbuf, idesc->id_number, getpathname(pathbuf, idesc->id_number,
idesc->id_number); idesc->id_number);
getpathname(namebuf, dirp->e2d_ino, dirp->e2d_ino); getpathname(namebuf, fs2h32(dirp->e2d_ino),
fs2h32(dirp->e2d_ino));
pwarn("%s %s %s\n", pathbuf, pwarn("%s %s %s\n", pathbuf,
"IS AN EXTRANEOUS HARD LINK TO DIRECTORY", "IS AN EXTRANEOUS HARD LINK TO DIRECTORY",
namebuf); namebuf);
@ -384,12 +385,12 @@ again:
/* fall through */ /* fall through */
case FSTATE: case FSTATE:
lncntp[dirp->e2d_ino]--; lncntp[fs2h32(dirp->e2d_ino)]--;
break; break;
default: default:
errexit("BAD STATE %d FOR INODE I=%d\n", errexit("BAD STATE %d FOR INODE I=%d\n",
statemap[dirp->e2d_ino], dirp->e2d_ino); statemap[fs2h32(dirp->e2d_ino)], fs2h32(dirp->e2d_ino));
} }
} }
if (n == 0) if (n == 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass5.c,v 1.3 1997/09/14 14:27:29 lukem Exp $ */ /* $NetBSD: pass5.c,v 1.4 1997/10/09 13:19:39 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94"; static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94";
#else #else
__RCSID("$NetBSD: pass5.c,v 1.3 1997/09/14 14:27:29 lukem Exp $"); __RCSID("$NetBSD: pass5.c,v 1.4 1997/10/09 13:19:39 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -93,17 +93,17 @@ pass5()
ndirs = 0; ndirs = 0;
if (blk_bitmap == NULL) { if (blk_bitmap == NULL) {
blk_bitmap = getdatablk(fs->e2fs_gd[c].ext2bgd_b_bitmap, blk_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
fs->e2fs_bsize); fs->e2fs_bsize);
} else { } else {
getblk(blk_bitmap, fs->e2fs_gd[c].ext2bgd_b_bitmap, getblk(blk_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
fs->e2fs_bsize); fs->e2fs_bsize);
} }
if (ino_bitmap == NULL) { if (ino_bitmap == NULL) {
ino_bitmap = getdatablk(fs->e2fs_gd[c].ext2bgd_i_bitmap, ino_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
fs->e2fs_bsize); fs->e2fs_bsize);
} else { } else {
getblk(ino_bitmap, fs->e2fs_gd[c].ext2bgd_i_bitmap, getblk(ino_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
fs->e2fs_bsize); fs->e2fs_bsize);
} }
memset(bbmap, 0, fs->e2fs_bsize); memset(bbmap, 0, fs->e2fs_bsize);
@ -173,26 +173,26 @@ pass5()
cs_nifree += nifree; cs_nifree += nifree;
cs_ndir += ndirs; cs_ndir += ndirs;
if (debug && (fs->e2fs_gd[c].ext2bgd_nbfree != nbfree || if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
fs->e2fs_gd[c].ext2bgd_nifree != nifree || fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
fs->e2fs_gd[c].ext2bgd_ndirs != ndirs)) { fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) {
printf("summary info for cg %d is %d, %d, %d," printf("summary info for cg %d is %d, %d, %d,"
"should be %d, %d, %d\n", c, "should be %d, %d, %d\n", c,
fs->e2fs_gd[c].ext2bgd_nbfree, fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree),
fs->e2fs_gd[c].ext2bgd_nifree, fs2h16(fs->e2fs_gd[c].ext2bgd_nifree),
fs->e2fs_gd[c].ext2bgd_ndirs, fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs),
nbfree, nbfree,
nifree, nifree,
ndirs); ndirs);
} }
snprintf(msg, 255, "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); snprintf(msg, 255, "SUMMARY INFORMATIONS WRONG FOR CG #%d", c);
if ((fs->e2fs_gd[c].ext2bgd_nbfree != nbfree || if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
fs->e2fs_gd[c].ext2bgd_nifree != nifree || fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
fs->e2fs_gd[c].ext2bgd_ndirs != ndirs) && fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) &&
dofix(&idesc[0], msg)) { dofix(&idesc[0], msg)) {
fs->e2fs_gd[c].ext2bgd_nbfree = nbfree; fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree);
fs->e2fs_gd[c].ext2bgd_nifree = nifree; fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree);
fs->e2fs_gd[c].ext2bgd_ndirs = ndirs; fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs);
sbdirty(); sbdirty();
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.5 1997/09/16 08:37:04 mrg Exp $ */ /* $NetBSD: setup.c,v 1.6 1997/10/09 13:19:40 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
#else #else
__RCSID("$NetBSD: setup.c,v 1.5 1997/09/16 08:37:04 mrg Exp $"); __RCSID("$NetBSD: setup.c,v 1.6 1997/10/09 13:19:40 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -63,8 +63,6 @@ __RCSID("$NetBSD: setup.c,v 1.5 1997/09/16 08:37:04 mrg Exp $");
#include "extern.h" #include "extern.h"
#include "fsutil.h" #include "fsutil.h"
struct bufarea asblk;
#define altsblock (*asblk.b_un.b_fs)
#define POWEROF2(num) (((num) & ((num) - 1)) == 0) #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
void badsb __P((int, char *)); void badsb __P((int, char *));
@ -115,8 +113,8 @@ setup(dev)
lfdir = 0; lfdir = 0;
initbarea(&sblk); initbarea(&sblk);
initbarea(&asblk); initbarea(&asblk);
sblk.b_un.b_buf = malloc(sizeof(struct m_ext2fs)); sblk.b_un.b_buf = malloc(SBSIZE);
asblk.b_un.b_buf = malloc(sizeof(struct m_ext2fs)); asblk.b_un.b_buf = malloc(SBSIZE);
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
errexit("cannot allocate space for superblock\n"); errexit("cannot allocate space for superblock\n");
if ((lp = getdisklabel((char *)NULL, fsreadfd)) != NULL) if ((lp = getdisklabel((char *)NULL, fsreadfd)) != NULL)
@ -179,6 +177,7 @@ setup(dev)
if (reply("SET TO DEFAULT") == 1) { if (reply("SET TO DEFAULT") == 1) {
sblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_bcount * 0.1; sblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_bcount * 0.1;
sbdirty(); sbdirty();
dirty(&asblk);
} }
} }
if (sblock.e2fs.e2fs_bpg != sblock.e2fs.e2fs_fpg) { if (sblock.e2fs.e2fs_bpg != sblock.e2fs.e2fs_fpg) {
@ -187,7 +186,7 @@ setup(dev)
return 0; return 0;
} }
if (asblk.b_dirty && !bflag) { if (asblk.b_dirty && !bflag) {
memcpy(&altsblock, &sblock, (size_t)SBSIZE); copyback_sb(&asblk);
flush(fswritefd, &asblk); flush(fswritefd, &asblk);
} }
/* /*
@ -230,7 +229,7 @@ setup(dev)
goto badsblabel; goto badsblabel;
} }
for (numdirs = 0, cg = 0; cg < sblock.e2fs_ncg; cg++) { for (numdirs = 0, cg = 0; cg < sblock.e2fs_ncg; cg++) {
numdirs += sblock.e2fs_gd[cg].ext2bgd_ndirs; numdirs += fs2h16(sblock.e2fs_gd[cg].ext2bgd_ndirs);
} }
inplast = 0; inplast = 0;
listmax = numdirs + 10; listmax = numdirs + 10;
@ -252,7 +251,7 @@ badsblabel:
} }
/* /*
* Read in the super block and its summary info. * Read in the super block and its summary info, convert to host byte order.
*/ */
static int static int
readsb(listerr) readsb(listerr)
@ -260,10 +259,37 @@ readsb(listerr)
{ {
daddr_t super = bflag ? bflag : SBOFF / dev_bsize; daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
if (bread(fsreadfd, (char *)&sblock.e2fs, super, (long)SBSIZE) != 0) if (bread(fsreadfd, (char *)sblk.b_un.b_fs, super, (long)SBSIZE) != 0)
return (0); return (0);
sblk.b_bno = super; sblk.b_bno = super;
sblk.b_size = SBSIZE; sblk.b_size = SBSIZE;
/* Copy the superblock in memory */
sblock.e2fs.e2fs_icount = fs2h32(sblk.b_un.b_fs->e2fs_icount);
sblock.e2fs.e2fs_bcount = fs2h32(sblk.b_un.b_fs->e2fs_bcount);
sblock.e2fs.e2fs_rbcount = fs2h32(sblk.b_un.b_fs->e2fs_rbcount);
sblock.e2fs.e2fs_fbcount = fs2h32(sblk.b_un.b_fs->e2fs_fbcount);
sblock.e2fs.e2fs_ficount = fs2h32(sblk.b_un.b_fs->e2fs_ficount);
sblock.e2fs.e2fs_first_dblock = fs2h32(sblk.b_un.b_fs->e2fs_first_dblock);
sblock.e2fs.e2fs_log_bsize = fs2h32(sblk.b_un.b_fs->e2fs_log_bsize);
sblock.e2fs.e2fs_fsize = fs2h32(sblk.b_un.b_fs->e2fs_fsize);
sblock.e2fs.e2fs_bpg = fs2h32(sblk.b_un.b_fs->e2fs_bpg);
sblock.e2fs.e2fs_fpg = fs2h32(sblk.b_un.b_fs->e2fs_fpg);
sblock.e2fs.e2fs_ipg = fs2h32(sblk.b_un.b_fs->e2fs_ipg);
sblock.e2fs.e2fs_mtime = fs2h32(sblk.b_un.b_fs->e2fs_mtime);
sblock.e2fs.e2fs_wtime = fs2h32(sblk.b_un.b_fs->e2fs_wtime);
sblock.e2fs.e2fs_lastfsck = fs2h32(sblk.b_un.b_fs->e2fs_lastfsck);
sblock.e2fs.e2fs_fsckintv = fs2h32(sblk.b_un.b_fs->e2fs_fsckintv);
sblock.e2fs.e2fs_creator = fs2h32(sblk.b_un.b_fs->e2fs_creator);
sblock.e2fs.e2fs_rev = fs2h32(sblk.b_un.b_fs->e2fs_rev);
sblock.e2fs.e2fs_mnt_count = fs2h16(sblk.b_un.b_fs->e2fs_mnt_count);
sblock.e2fs.e2fs_max_mnt_count = fs2h16(sblk.b_un.b_fs->e2fs_max_mnt_count);
sblock.e2fs.e2fs_magic = fs2h16(sblk.b_un.b_fs->e2fs_magic);
sblock.e2fs.e2fs_state = fs2h16(sblk.b_un.b_fs->e2fs_state);
sblock.e2fs.e2fs_beh = fs2h16(sblk.b_un.b_fs->e2fs_beh);
sblock.e2fs.e2fs_ruid = fs2h16(sblk.b_un.b_fs->e2fs_ruid);
sblock.e2fs.e2fs_rgid = fs2h16(sblk.b_un.b_fs->e2fs_rgid);
/* /*
* run a few consistency checks of the super block * run a few consistency checks of the super block
*/ */
@ -306,6 +332,11 @@ readsb(listerr)
super *= dev_bsize; super *= dev_bsize;
dev_bsize = sblock.e2fs_bsize / fsbtodb(&sblock, 1); dev_bsize = sblock.e2fs_bsize / fsbtodb(&sblock, 1);
sblk.b_bno = super / dev_bsize; sblk.b_bno = super / dev_bsize;
getblk(&asblk, 1 * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock,
(long)SBSIZE);
if (asblk.b_errs)
return (0);
if (bflag) { if (bflag) {
havesb = 1; havesb = 1;
return (1); return (1);
@ -316,36 +347,34 @@ readsb(listerr)
* of whole super block against an alternate super block. * of whole super block against an alternate super block.
* When an alternate super-block is specified this check is skipped. * When an alternate super-block is specified this check is skipped.
*/ */
getblk(&asblk, 1 * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock, asblk.b_un.b_fs->e2fs_rbcount = sblk.b_un.b_fs->e2fs_rbcount;
(long)SBSIZE); asblk.b_un.b_fs->e2fs_fbcount = sblk.b_un.b_fs->e2fs_fbcount;
if (asblk.b_errs) asblk.b_un.b_fs->e2fs_ficount = sblk.b_un.b_fs->e2fs_ficount;
return (0); asblk.b_un.b_fs->e2fs_mtime = sblk.b_un.b_fs->e2fs_mtime;
altsblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_rbcount; asblk.b_un.b_fs->e2fs_wtime = sblk.b_un.b_fs->e2fs_wtime;
altsblock.e2fs.e2fs_fbcount = sblock.e2fs.e2fs_fbcount; asblk.b_un.b_fs->e2fs_mnt_count = sblk.b_un.b_fs->e2fs_mnt_count;
altsblock.e2fs.e2fs_ficount = sblock.e2fs.e2fs_ficount; asblk.b_un.b_fs->e2fs_max_mnt_count = sblk.b_un.b_fs->e2fs_max_mnt_count;
altsblock.e2fs.e2fs_mtime = sblock.e2fs.e2fs_mtime; asblk.b_un.b_fs->e2fs_state = sblk.b_un.b_fs->e2fs_state;
altsblock.e2fs.e2fs_wtime = sblock.e2fs.e2fs_wtime; asblk.b_un.b_fs->e2fs_beh = sblk.b_un.b_fs->e2fs_beh;
altsblock.e2fs.e2fs_mnt_count = sblock.e2fs.e2fs_mnt_count; asblk.b_un.b_fs->e2fs_lastfsck = sblk.b_un.b_fs->e2fs_lastfsck;
altsblock.e2fs.e2fs_max_mnt_count = sblock.e2fs.e2fs_max_mnt_count; asblk.b_un.b_fs->e2fs_fsckintv = sblk.b_un.b_fs->e2fs_fsckintv;
altsblock.e2fs.e2fs_state = sblock.e2fs.e2fs_state; asblk.b_un.b_fs->e2fs_ruid = sblk.b_un.b_fs->e2fs_ruid;
altsblock.e2fs.e2fs_beh = sblock.e2fs.e2fs_beh; asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid;
altsblock.e2fs.e2fs_lastfsck = sblock.e2fs.e2fs_lastfsck; if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) {
altsblock.e2fs.e2fs_fsckintv = sblock.e2fs.e2fs_fsckintv;
altsblock.e2fs.e2fs_ruid = sblock.e2fs.e2fs_ruid;
altsblock.e2fs.e2fs_rgid = sblock.e2fs.e2fs_rgid;
if (memcmp(&(sblock.e2fs), &(altsblock.e2fs), (int)SBSIZE)) {
if (debug) { if (debug) {
long *nlp, *olp, *endlp; u_int32_t *nlp, *olp, *endlp;
printf("superblock mismatches\n"); printf("superblock mismatches\n");
nlp = (long *)&altsblock; nlp = (u_int32_t *)asblk.b_un.b_fs;
olp = (long *)&sblock; olp = (u_int32_t *)sblk.b_un.b_fs;
endlp = olp + (SBSIZE / sizeof *olp); endlp = olp + (SBSIZE / sizeof *olp);
for ( ; olp < endlp; olp++, nlp++) { for ( ; olp < endlp; olp++, nlp++) {
if (*olp == *nlp) if (*olp == *nlp)
continue; continue;
printf("offset %ld, original %ld, alternate %ld\n", printf("offset %ld, original %ld, alternate %ld\n",
(long)(olp - (long *)&sblock), *olp, *nlp); (long)(olp - (u_int32_t *)sblk.b_un.b_fs),
(long)fs2h32(*olp),
(long)fs2h32(*nlp));
} }
} }
badsb(listerr, badsb(listerr,
@ -356,6 +385,39 @@ readsb(listerr)
return (1); return (1);
} }
void
copyback_sb(bp)
struct bufarea *bp;
{
/* Copy the in-memory superblock back to buffer */
bp->b_un.b_fs->e2fs_icount = fs2h32(sblock.e2fs.e2fs_icount);
bp->b_un.b_fs->e2fs_bcount = fs2h32(sblock.e2fs.e2fs_bcount);
bp->b_un.b_fs->e2fs_rbcount = fs2h32(sblock.e2fs.e2fs_rbcount);
bp->b_un.b_fs->e2fs_fbcount = fs2h32(sblock.e2fs.e2fs_fbcount);
bp->b_un.b_fs->e2fs_ficount = fs2h32(sblock.e2fs.e2fs_ficount);
bp->b_un.b_fs->e2fs_first_dblock =
fs2h32(sblock.e2fs.e2fs_first_dblock);
bp->b_un.b_fs->e2fs_log_bsize = fs2h32(sblock.e2fs.e2fs_log_bsize);
bp->b_un.b_fs->e2fs_fsize = fs2h32(sblock.e2fs.e2fs_fsize);
bp->b_un.b_fs->e2fs_bpg = fs2h32(sblock.e2fs.e2fs_bpg);
bp->b_un.b_fs->e2fs_fpg = fs2h32(sblock.e2fs.e2fs_fpg);
bp->b_un.b_fs->e2fs_ipg = fs2h32(sblock.e2fs.e2fs_ipg);
bp->b_un.b_fs->e2fs_mtime = fs2h32(sblock.e2fs.e2fs_mtime);
bp->b_un.b_fs->e2fs_wtime = fs2h32(sblock.e2fs.e2fs_wtime);
bp->b_un.b_fs->e2fs_lastfsck = fs2h32(sblock.e2fs.e2fs_lastfsck);
bp->b_un.b_fs->e2fs_fsckintv = fs2h32(sblock.e2fs.e2fs_fsckintv);
bp->b_un.b_fs->e2fs_creator = fs2h32(sblock.e2fs.e2fs_creator);
bp->b_un.b_fs->e2fs_rev = fs2h32(sblock.e2fs.e2fs_rev);
bp->b_un.b_fs->e2fs_mnt_count = fs2h16(sblock.e2fs.e2fs_mnt_count);
bp->b_un.b_fs->e2fs_max_mnt_count =
fs2h16(sblock.e2fs.e2fs_max_mnt_count);
bp->b_un.b_fs->e2fs_magic = fs2h16(sblock.e2fs.e2fs_magic);
bp->b_un.b_fs->e2fs_state = fs2h16(sblock.e2fs.e2fs_state);
bp->b_un.b_fs->e2fs_beh = fs2h16(sblock.e2fs.e2fs_beh);
bp->b_un.b_fs->e2fs_ruid = fs2h16(sblock.e2fs.e2fs_ruid);
bp->b_un.b_fs->e2fs_rgid = fs2h16(sblock.e2fs.e2fs_rgid);
}
void void
badsb(listerr, s) badsb(listerr, s)
int listerr; int listerr;
@ -396,17 +458,17 @@ calcsb(dev, devfd, fs)
pp = &lp->d_partitions[0]; pp = &lp->d_partitions[0];
else else
pp = &lp->d_partitions[*cp - 'a']; pp = &lp->d_partitions[*cp - 'a'];
if (pp->p_fstype != FS_BSDFFS) { if (pp->p_fstype != FS_EX2FS) {
pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n", pfatal("%s: NOT LABELED AS A EXT2 FILE SYSTEM (%s)\n",
dev, pp->p_fstype < FSMAXTYPES ? dev, pp->p_fstype < FSMAXTYPES ?
fstypenames[pp->p_fstype] : "unknown"); fstypenames[pp->p_fstype] : "unknown");
return (0); return (0);
} }
memset(fs, 0, sizeof(struct m_ext2fs)); memset(fs, 0, sizeof(struct m_ext2fs));
fs->e2fs_bsize = 1024; /* XXX to look for altenate SP */ fs->e2fs_bsize = pp->p_fsize;
fs->e2fs.e2fs_log_bsize = 0; fs->e2fs.e2fs_log_bsize = pp->p_fsize / 1024;
fs->e2fs.e2fs_bcount = (pp->p_size * DEV_BSIZE) / fs->e2fs_bsize; fs->e2fs.e2fs_bcount = (pp->p_size * DEV_BSIZE) / fs->e2fs_bsize;
fs->e2fs.e2fs_first_dblock = 1; fs->e2fs.e2fs_first_dblock = (fs->e2fs.e2fs_log_bsize == 0) ? 1 : 0;
fs->e2fs.e2fs_bpg = fs->e2fs_bsize * NBBY; fs->e2fs.e2fs_bpg = fs->e2fs_bsize * NBBY;
fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize; fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize;
fs->e2fs_qbmask = fs->e2fs_bsize - 1; fs->e2fs_qbmask = fs->e2fs_bsize - 1;
@ -418,8 +480,6 @@ calcsb(dev, devfd, fs)
fs->e2fs_ngdb = howmany(fs->e2fs_ncg, fs->e2fs_ngdb = howmany(fs->e2fs_ncg,
fs->e2fs_bsize / sizeof(struct ext2_gd)); fs->e2fs_bsize / sizeof(struct ext2_gd));
return (1); return (1);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: utilities.c,v 1.2 1997/09/14 14:27:31 lukem Exp $ */ /* $NetBSD: utilities.c,v 1.3 1997/10/09 13:19:41 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93";
#else #else
__RCSID("$NetBSD: utilities.c,v 1.2 1997/09/14 14:27:31 lukem Exp $"); __RCSID("$NetBSD: utilities.c,v 1.3 1997/10/09 13:19:41 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -67,7 +67,7 @@ int
ftypeok(dp) ftypeok(dp)
struct ext2fs_dinode *dp; struct ext2fs_dinode *dp;
{ {
switch (dp->e2di_mode & IFMT) { switch (fs2h16(dp->e2di_mode) & IFMT) {
case IFDIR: case IFDIR:
case IFREG: case IFREG:
@ -80,7 +80,7 @@ ftypeok(dp)
default: default:
if (debug) if (debug)
printf("bad file type 0%o\n", dp->e2di_mode); printf("bad file type 0%o\n", fs2h16(dp->e2di_mode));
return (0); return (0);
} }
} }
@ -128,6 +128,7 @@ bufinit()
long bufcnt, i; long bufcnt, i;
char *bufp; char *bufp;
diskreads = totalreads = 0;
pbp = pdirbp = (struct bufarea *)0; pbp = pdirbp = (struct bufarea *)0;
bufhead.b_next = bufhead.b_prev = &bufhead; bufhead.b_next = bufhead.b_prev = &bufhead;
bufcnt = MAXBUFSPACE / sblock.e2fs_bsize; bufcnt = MAXBUFSPACE / sblock.e2fs_bsize;
@ -170,6 +171,7 @@ getdatablk(blkno, size)
if (bp == &bufhead) if (bp == &bufhead)
errexit("deadlocked buffer pool\n"); errexit("deadlocked buffer pool\n");
getblk(bp, blkno, size); getblk(bp, blkno, size);
diskreads++;
/* fall through */ /* fall through */
foundit: foundit:
totalreads++; totalreads++;
@ -194,7 +196,6 @@ getblk(bp, blk, size)
dblk = fsbtodb(&sblock, blk); dblk = fsbtodb(&sblock, blk);
if (bp->b_bno != dblk) { if (bp->b_bno != dblk) {
flush(fswritefd, bp); flush(fswritefd, bp);
diskreads++;
bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size); bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
bp->b_bno = dblk; bp->b_bno = dblk;
bp->b_size = size; bp->b_size = size;
@ -253,10 +254,13 @@ ckfini(markclean)
} }
flush(fswritefd, &sblk); flush(fswritefd, &sblk);
if (havesb && sblk.b_bno != SBOFF / dev_bsize && if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
!preen && reply("UPDATE STANDARD SUPERBLOCK")) { !preen && reply("UPDATE STANDARD SUPERBLOCKS")) {
sblk.b_bno = SBOFF / dev_bsize; sblk.b_bno = SBOFF / dev_bsize;
sbdirty(); sbdirty();
flush(fswritefd, &sblk); flush(fswritefd, &sblk);
copyback_sb(&asblk);
asblk.b_dirty = 1;
flush(fswritefd, &asblk);
} }
for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) {
cnt++; cnt++;