From 65348f21f42480920975088c4671426e8bd34550 Mon Sep 17 00:00:00 2001 From: jasoni Date: Wed, 26 Apr 2000 23:25:33 +0000 Subject: [PATCH] Support for ext2fs rev. 1 --- bin/df/ext2fs_df.c | 2 +- sbin/fsck_ext2fs/dir.c | 153 +++++++++++++++++-------------- sbin/fsck_ext2fs/fsck.h | 15 +-- sbin/fsck_ext2fs/inode.c | 75 ++++++++------- sbin/fsck_ext2fs/main.c | 37 +++----- sbin/fsck_ext2fs/pass1.c | 154 ++++++++++++++++++------------- sbin/fsck_ext2fs/pass2.c | 146 ++++++++++++++++++----------- sbin/fsck_ext2fs/pass5.c | 60 ++++++------ sbin/fsck_ext2fs/setup.c | 173 ++++++++++++++++++++++++----------- sbin/fsck_ext2fs/utilities.c | 19 ++-- 10 files changed, 497 insertions(+), 337 deletions(-) diff --git a/bin/df/ext2fs_df.c b/bin/df/ext2fs_df.c index 48a30d41380..66314853ccd 100644 --- a/bin/df/ext2fs_df.c +++ b/bin/df/ext2fs_df.c @@ -75,7 +75,7 @@ e2fs_df(rfd, file, sfsp) return (-1); } if ((sblock.e2fs_magic != E2FS_MAGIC) || - (sblock.e2fs_rev != E2FS_REV)) { + (sblock.e2fs_rev != E2FS_REV0 && sblock.e2fs_rev != E2FS_REV1)) { return (-1); } sfsp->f_flags = 0; /* The fs is not mapped, so no flags */ diff --git a/sbin/fsck_ext2fs/dir.c b/sbin/fsck_ext2fs/dir.c index 1a146eb0700..934a004be5f 100644 --- a/sbin/fsck_ext2fs/dir.c +++ b/sbin/fsck_ext2fs/dir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dir.c,v 1.3 1997/06/14 04:16:50 downsj Exp $ */ +/* $OpenBSD: dir.c,v 1.4 2000/04/26 23:26:05 jasoni Exp $ */ /* $NetBSD: dir.c,v 1.1 1997/06/11 11:21:46 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; #if 0 static char rcsid[] = "$NetBSD: dir.c,v 1.1 1997/06/11 11:21:46 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: dir.c,v 1.3 1997/06/14 04:16:50 downsj Exp $"; +static char rcsid[] = "$OpenBSD: dir.c,v 1.4 2000/04/26 23:26:05 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -69,8 +69,8 @@ int lfmode = 01777; #define DIRBLKSIZ 0 /* just for now */ struct ext2fs_dirtemplate emptydir = { 0, DIRBLKSIZ }; struct ext2fs_dirtemplate dirhead = { - 0, 12, 1, ".", - 0, DIRBLKSIZ - 12, 2, ".." + 0, 12, 1, EXT2_FT_DIR, ".", + 0, DIRBLKSIZ - 12, 2, EXT2_FT_DIR, ".." }; #undef DIRBLKSIZ @@ -148,7 +148,7 @@ dirscan(idesc) } idesc->id_loc = 0; 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); idesc->id_dirp = (struct ext2fs_direct *)dbuf; if ((n = (*idesc->id_func)(idesc)) & ALTERED) { @@ -190,9 +190,10 @@ fsck_readdir(idesc) fix = dofix(idesc, "DIRECTORY CORRUPTED"); bp = getdirblk(idesc->id_blkno, blksiz); 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_namlen = 0; + dp->e2d_type = 0; dp->e2d_name[0] = '\0'; if (fix) dirty(bp); @@ -205,8 +206,8 @@ dpok: return NULL; dploc = idesc->id_loc; dp = (struct ext2fs_direct *)(bp->b_un.b_buf + dploc); - idesc->id_loc += dp->e2d_reclen; - idesc->id_filesize -= dp->e2d_reclen; + idesc->id_loc += fs2h16(dp->e2d_reclen); + idesc->id_filesize -= fs2h16(dp->e2d_reclen); if ((idesc->id_loc % sblock.e2fs_bsize) == 0) return (dp); ndp = (struct ext2fs_direct *)(bp->b_un.b_buf + idesc->id_loc); @@ -220,7 +221,7 @@ dpok: fix = dofix(idesc, "DIRECTORY CORRUPTED"); bp = getdirblk(idesc->id_blkno, blksiz); 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) dirty(bp); } @@ -238,24 +239,27 @@ dircheck(idesc, dp) { int size; char *cp; - u_char namlen; int spaceleft; + u_int16_t reclen = fs2h16(dp->e2d_reclen); spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize); - if (dp->e2d_ino > maxino || - dp->e2d_reclen == 0 || - dp->e2d_reclen > spaceleft || - (dp->e2d_reclen & 0x3) != 0) + if (fs2h32(dp->e2d_ino) > maxino || + reclen == 0 || + reclen > spaceleft || + (reclen & 0x3) != 0) return (0); if (dp->e2d_ino == 0) return (1); + if (sblock.e2fs.e2fs_rev < E2FS_REV1 || + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) == 0) + if (dp->e2d_type != 0) + return (1); size = EXT2FS_DIRSIZ(dp->e2d_namlen); - namlen = dp->e2d_namlen; - if (dp->e2d_reclen < size || + if (reclen < size || idesc->id_filesize < size || - namlen > EXT2FS_MAXNAMLEN) + dp->e2d_namlen > EXT2FS_MAXNAMLEN) return (0); - for (cp = dp->e2d_name, size = 0; size < namlen; size++) + for (cp = dp->e2d_name, size = 0; size < dp->e2d_namlen; size++) if (*cp == '\0' || (*cp++ == '/')) return (0); return (1); @@ -289,7 +293,7 @@ fileerror(cwd, ino, errmesg) dp = ginode(ino); if (ftypeok(dp)) pfatal("%s=%s\n", - (dp->e2di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); + (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); else pfatal("NAME=%s\n", pathbuf); } @@ -302,15 +306,15 @@ adjust(idesc, lcnt) register struct ext2fs_dinode *dp; 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) clri(idesc, "UNREF", 0); } else { 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); 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 (lcnt < 0) { printf("\n"); @@ -319,7 +323,7 @@ adjust(idesc, lcnt) printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { - dp->e2di_nlink -= lcnt; + dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - lcnt); inodirty(); } } @@ -334,20 +338,24 @@ mkentry(idesc) int newlen, oldlen; newent.e2d_namlen = strlen(idesc->id_name); + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + newent.e2d_type = inot2ext2dt(typemap[idesc->id_parent]); newlen = EXT2FS_DIRSIZ(newent.e2d_namlen); if (dirp->e2d_ino != 0) oldlen = EXT2FS_DIRSIZ(dirp->e2d_namlen); else oldlen = 0; - if (dirp->e2d_reclen - oldlen < newlen) + if (fs2h16(dirp->e2d_reclen) - oldlen < newlen) return (KEEPON); - newent.e2d_reclen = dirp->e2d_reclen - oldlen; - dirp->e2d_reclen = oldlen; + newent.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - oldlen); + dirp->e2d_reclen = h2fs16(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_namlen = newent.e2d_namlen; - memcpy(dirp->e2d_name, idesc->id_name, (size_t)dirp->e2d_namlen); + dirp->e2d_type = newent.e2d_type; + memcpy(dirp->e2d_name, idesc->id_name, (size_t)(dirp->e2d_namlen)); return (ALTERED|STOP); } @@ -356,11 +364,17 @@ chgino(idesc) struct inodesc *idesc; { register struct ext2fs_direct *dirp = idesc->id_dirp; + u_int16_t namlen = dirp->e2d_namlen; - if (strlen(idesc->id_name) != dirp->e2d_namlen || - strncmp(dirp->e2d_name, idesc->id_name, (int)dirp->e2d_namlen)) + if (strlen(idesc->id_name) != namlen || + strncmp(dirp->e2d_name, idesc->id_name, (int)namlen)) return (KEEPON); - dirp->e2d_ino = idesc->id_parent; + dirp->e2d_ino = h2fs32(idesc->id_parent); + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + dirp->e2d_type = inot2ext2dt(typemap[idesc->id_parent]); + else + dirp->e2d_type = 0; return (ALTERED|STOP); } @@ -377,10 +391,10 @@ linkup(orphan, parentdir) memset(&idesc, 0, sizeof(struct inodesc)); dp = ginode(orphan); - lostdir = (dp->e2di_mode & IFMT) == IFDIR; + lostdir = (fs2h16(dp->e2di_mode) & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pinode(orphan); - if (preen && dp->e2di_size == 0) + if (preen && fs2h32(dp->e2di_size) == 0) return (0); if (preen) printf(" (RECONNECTED)\n"); @@ -419,7 +433,7 @@ linkup(orphan, parentdir) } } dp = ginode(lfdir); - if ((dp->e2di_mode & IFMT) != IFDIR) { + if ((fs2h16(dp->e2di_mode) & IFMT) != IFDIR) { pfatal("lost+found IS NOT A DIRECTORY"); if (reply("REALLOCATE") == 0) return (0); @@ -456,7 +470,7 @@ linkup(orphan, parentdir) parentdir != (ino_t)-1) (void)makeentry(orphan, lfdir, ".."); dp = ginode(lfdir); - dp->e2di_nlink++; + dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) +1); inodirty(); lncntp[lfdir]++; pwarn("DIR I=%u CONNECTED. ", orphan); @@ -513,8 +527,9 @@ makeentry(parent, ino, name) idesc.id_fix = DONTKNOW; idesc.id_name = name; dp = ginode(parent); - if (dp->e2di_size % sblock.e2fs_bsize) { - dp->e2di_size = roundup(dp->e2di_size, sblock.e2fs_bsize); + if (fs2h32(dp->e2di_size) % sblock.e2fs_bsize) { + dp->e2di_size = + h2fs32(roundup(fs2h32(dp->e2di_size), sblock.e2fs_bsize)); inodirty(); } if ((ckinode(dp, &idesc) & ALTERED) != 0) @@ -543,17 +558,17 @@ expanddir(dp, name) exit(8); } - lastbn = lblkno(&sblock, dp->e2di_size); - if (lastbn >= NDADDR - 1 || dp->e2di_blocks[lastbn] == 0 || - dp->e2di_size == 0) + lastbn = lblkno(&sblock, fs2h32(dp->e2di_size)); + if (lastbn >= NDADDR - 1 || fs2h32(dp->e2di_blocks[lastbn]) == 0 || + fs2h32(dp->e2di_size) == 0) return (0); if ((newblk = allocblk()) == 0) return (0); dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn]; - dp->e2di_blocks[lastbn] = newblk; - dp->e2di_size += sblock.e2fs_bsize; - dp->e2di_nblock += 1; - bp = getdirblk(dp->e2di_blocks[lastbn + 1], + dp->e2di_blocks[lastbn] = h2fs32(newblk); + dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) + sblock.e2fs_bsize); + dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) + 1); + bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), sblock.e2fs_bsize); if (bp->b_errs) goto bad; @@ -562,16 +577,12 @@ expanddir(dp, name) if (bp->b_errs) goto bad; 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); - bp = getdirblk(dp->e2di_blocks[lastbn + 1], + bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]), sblock.e2fs_bsize); if (bp->b_errs) goto bad; + emptydir.dot_reclen = h2fs16(sblock.e2fs_bsize); memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir); pwarn("NO SPACE LEFT IN %s", name); if (preen) @@ -584,8 +595,8 @@ expanddir(dp, name) bad: dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1]; dp->e2di_blocks[lastbn + 1] = 0; - dp->e2di_size -= sblock.e2fs_bsize; - dp->e2di_nblock -= sblock.e2fs_bsize; + dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - sblock.e2fs_bsize); + dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) - 1); freeblk(newblk); return (0); } @@ -599,34 +610,40 @@ allocdir(parent, request, mode) int mode; { ino_t ino; - char *cp; struct ext2fs_dinode *dp; register struct bufarea *bp; struct ext2fs_dirtemplate *dirp; ino = allocino(request, IFDIR|mode); - dirhead.dot_reclen = 12; /* XXX */ - dirhead.dotdot_reclen = sblock.e2fs_bsize - 12; /* XXX */ + dirhead.dot_reclen = h2fs16(12); /* XXX */ + dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */ + dirhead.dot_namlen = 1; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + dirhead.dot_type = EXT2_FT_DIR; + else + dirhead.dot_type = 0; + dirhead.dotdot_namlen = 2; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + dirhead.dotdot_type = EXT2_FT_DIR; + else + dirhead.dotdot_type = 0; dirp = &dirhead; - dirp->dot_ino = ino; - dirp->dotdot_ino = parent; + dirp->dot_ino = h2fs32(ino); + dirp->dotdot_ino = h2fs32(parent); 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) { freeino(ino); return (0); } - emptydir.dot_reclen = sblock.e2fs_bsize; 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); - dp->e2di_nlink = 2; + dp->e2di_nlink = h2fs16(2); inodirty(); if (ino == EXT2_ROOTINO) { - lncntp[ino] = dp->e2di_nlink; + lncntp[ino] = fs2h16(dp->e2di_nlink); cacheino(dp, ino); return(ino); } @@ -637,11 +654,11 @@ allocdir(parent, request, mode) cacheino(dp, ino); statemap[ino] = statemap[parent]; if (statemap[ino] == DSTATE) { - lncntp[ino] = dp->e2di_nlink; + lncntp[ino] = fs2h16(dp->e2di_nlink); lncntp[parent]++; } dp = ginode(parent); - dp->e2di_nlink++; + dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) + 1); inodirty(); return (ino); } @@ -657,7 +674,7 @@ freedir(ino, parent) if (ino != parent) { dp = ginode(parent); - dp->e2di_nlink--; + dp->e2di_nlink = h2fs16(fs2h16(dp->e2di_nlink) - 1); inodirty(); } freeino(ino); diff --git a/sbin/fsck_ext2fs/fsck.h b/sbin/fsck_ext2fs/fsck.h index fd8f5a784e4..63a3b45a683 100644 --- a/sbin/fsck_ext2fs/fsck.h +++ b/sbin/fsck_ext2fs/fsck.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fsck.h,v 1.3 1997/06/14 04:16:51 downsj Exp $ */ +/* $OpenBSD: fsck.h,v 1.4 2000/04/26 23:26:05 jasoni Exp $ */ /* $NetBSD: fsck.h,v 1.1 1997/06/11 11:21:47 bouyer Exp $ */ /* @@ -66,7 +66,7 @@ struct bufarea { union { char *b_buf; /* buffer space */ 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 ext2fs_dinode *b_dinode; /* inode block */ } b_un; @@ -78,9 +78,11 @@ struct bufarea { #define MINBUFS 5 /* minimum number of buffers required */ struct bufarea bufhead; /* head of list of other blks in filesys */ struct bufarea sblk; /* file system superblock */ +struct bufarea asblk; /* first alternate superblock */ struct bufarea *pdirbp; /* current directory contents */ struct bufarea *pbp; /* current inode block */ struct bufarea *getdatablk __P((daddr_t, long)); +struct m_ext2fs sblock; #define dirty(bp) (bp)->b_dirty = 1 #define initbarea(bp) \ @@ -88,10 +90,7 @@ struct bufarea *getdatablk __P((daddr_t, long)); (bp)->b_bno = (daddr_t)-1; \ (bp)->b_flags = 0; -#define sbdirty() sblk.b_dirty = 1 -#define cgdirty() cgblk.b_dirty = 1 -#define sblock (*sblk.b_un.b_fs) -#define cgrp (*cgblk.b_un.b_cg) +#define sbdirty() copyback_sb(&sblk); sblk.b_dirty = 1 enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE}; @@ -181,11 +180,11 @@ int fswritefd; /* file descriptor for writing file system */ int rerun; /* rerun fsck. Only used in non-preen mode */ daddr_t maxfsblock; /* number of blocks in the file system */ -daddr_t cgoverhead; /* overhead per cg */ 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 */ +u_char *typemap; /* ptr to inode type table */ int16_t *lncntp; /* ptr to link count table */ ino_t lfdir; /* lost & found directory inode number */ @@ -212,3 +211,5 @@ struct ext2fs_dinode *ginode __P((ino_t)); struct inoinfo *getinoinfo __P((ino_t)); void getblk __P((struct bufarea *, daddr_t, long)); ino_t allocino __P((ino_t, int)); +void copyback_sb __P((struct bufarea*)); +daddr_t cgoverhead __P((int)); /* overhead per cg */ diff --git a/sbin/fsck_ext2fs/inode.c b/sbin/fsck_ext2fs/inode.c index 48c0c3fc803..2d50031ba6e 100644 --- a/sbin/fsck_ext2fs/inode.c +++ b/sbin/fsck_ext2fs/inode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inode.c,v 1.5 1999/08/06 20:41:05 deraadt Exp $ */ +/* $OpenBSD: inode.c,v 1.6 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: inode.c,v 1.1 1997/06/11 11:21:49 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; #if 0 static char rcsid[] = "$NetBSD: inode.c,v 1.1 1997/06/11 11:21:49 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: inode.c,v 1.5 1999/08/06 20:41:05 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: inode.c,v 1.6 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -65,6 +65,15 @@ static char rcsid[] = "$OpenBSD: inode.c,v 1.5 1999/08/06 20:41:05 deraadt Exp $ #include "fsutil.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 int iblock __P((struct inodesc *, long, u_int64_t)); @@ -75,7 +84,7 @@ ckinode(dp, idesc) register struct inodesc *idesc; { register u_int32_t *ap; - long ret, n, ndb, offset; + long ret, n, ndb; struct ext2fs_dinode dino; u_int64_t remsize, sizepb; mode_t mode; @@ -84,13 +93,13 @@ ckinode(dp, idesc) if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_entryno = 0; - idesc->id_filesize = dp->e2di_size; - mode = dp->e2di_mode & IFMT; - if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && - (dp->e2di_size < EXT2_MAXSYMLINKLEN))) + idesc->id_filesize = fs2h32(dp->e2di_size); + mode = fs2h16(dp->e2di_mode) & IFMT; + if (mode == IFBLK || mode == IFCHR || mode == IFIFO || + (mode == IFLNK && (fs2h32(dp->e2di_size) < EXT2_MAXSYMLINKLEN))) return (KEEPON); 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]; ap++,ndb--) { idesc->id_numfrags = 1; @@ -103,8 +112,8 @@ ckinode(dp, idesc) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->e2di_size = (ap - &dino.e2di_blocks[0]) * - sblock.e2fs_bsize; + dp->e2di_size = h2fs32((ap - &dino.e2di_blocks[0]) * + sblock.e2fs_bsize); printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; @@ -113,7 +122,7 @@ ckinode(dp, idesc) } continue; } - idesc->id_blkno = *ap; + idesc->id_blkno = fs2h32(*ap); if (idesc->id_type == ADDR) ret = (*idesc->id_func)(idesc); else @@ -122,11 +131,11 @@ ckinode(dp, idesc) return (ret); } 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; for (ap = &dino.e2di_blocks[NDADDR], n = 1; n <= NIADDR; ap++, n++) { if (*ap) { - idesc->id_blkno = *ap; + idesc->id_blkno = fs2h32(*ap); ret = iblock(idesc, n, remsize); if (ret & STOP) return (ret); @@ -139,7 +148,7 @@ ckinode(dp, idesc) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->e2di_size -= remsize; + dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - remsize); remsize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); @@ -192,8 +201,8 @@ iblock(idesc, ilevel, isize) for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) { if (*ap == 0) continue; - (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%u", - idesc->id_number); + (void)snprintf(buf, sizeof(buf), + "PARTIALLY TRUNCATED INODE I=%u", idesc->id_number); if (dofix(idesc, buf)) { *ap = 0; dirty(bp); @@ -204,7 +213,7 @@ iblock(idesc, ilevel, isize) aplim = &bp->b_un.b_indir[nif]; for (ap = bp->b_un.b_indir; ap < aplim; ap++) { if (*ap) { - idesc->id_blkno = *ap; + idesc->id_blkno = fs2h32(*ap); if (ilevel == 0) n = (*func)(idesc); else @@ -222,7 +231,7 @@ iblock(idesc, ilevel, isize) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->e2di_size -= isize; + dp->e2di_size = h2fs32(fs2h32(dp->e2di_size) - isize); isize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); @@ -249,34 +258,36 @@ chkrange(blk, cnt) int cnt; { register int c; + int overh; if ((unsigned)(blk + cnt) > maxfsblock) return (1); c = dtog(&sblock, blk); - if (blk < sblock.e2fs.e2fs_bpg * c + cgoverhead + - sblock.e2fs.e2fs_first_dblock) { - if ((blk + cnt) > sblock.e2fs.e2fs_bpg * c + cgoverhead + - sblock.e2fs.e2fs_first_dblock) { + overh = cgoverhead(c); + if (blk < sblock.e2fs.e2fs_bpg * c + overh + + sblock.e2fs.e2fs_first_dblock) { + if ((blk + cnt) > sblock.e2fs.e2fs_bpg * c + overh + + sblock.e2fs.e2fs_first_dblock) { if (debug) { printf("blk %d < cgdmin %d;", - blk, sblock.e2fs.e2fs_bpg * c + cgoverhead + - sblock.e2fs.e2fs_first_dblock); + blk, sblock.e2fs.e2fs_bpg * c + overh + + sblock.e2fs.e2fs_first_dblock); printf(" blk + cnt %d > cgsbase %d\n", - blk + cnt, sblock.e2fs.e2fs_bpg * c + cgoverhead + - sblock.e2fs.e2fs_first_dblock); + blk + cnt, sblock.e2fs.e2fs_bpg * c + + overh + sblock.e2fs.e2fs_first_dblock); } return (1); } } else { - if ((blk + cnt) > sblock.e2fs.e2fs_bpg * (c + 1) + cgoverhead + - sblock.e2fs.e2fs_first_dblock) { + if ((blk + cnt) > sblock.e2fs.e2fs_bpg * (c + 1) + overh + + sblock.e2fs.e2fs_first_dblock) { if (debug) { printf("blk %d >= cgdmin %d;", - blk, sblock.e2fs.e2fs_bpg * c + cgoverhead + - sblock.e2fs.e2fs_first_dblock); + blk, sblock.e2fs.e2fs_bpg * c + overh + + sblock.e2fs.e2fs_first_dblock); printf(" blk + cnt %d > cgdmax %d\n", - blk+cnt, sblock.e2fs.e2fs_bpg * (c + 1) + cgoverhead + - sblock.e2fs.e2fs_first_dblock); + blk+cnt, sblock.e2fs.e2fs_bpg * (c + 1) + + overh + sblock.e2fs.e2fs_first_dblock); } return (1); } diff --git a/sbin/fsck_ext2fs/main.c b/sbin/fsck_ext2fs/main.c index 3ddd9b31a12..5806a97dd3d 100644 --- a/sbin/fsck_ext2fs/main.c +++ b/sbin/fsck_ext2fs/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.6 2000/01/22 20:24:55 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.7 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: main.c,v 1.1 1997/06/11 11:21:50 bouyer Exp $ */ /* @@ -48,7 +48,7 @@ static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; #if 0 static char rcsid[] = "$NetBSD: main.c,v 1.1 1997/06/11 11:21:50 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: main.c,v 1.6 2000/01/22 20:24:55 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: main.c,v 1.7 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -63,6 +63,7 @@ static char rcsid[] = "$OpenBSD: main.c,v 1.6 2000/01/22 20:24:55 deraadt Exp $" #include #include #include +#include #include #include "fsck.h" @@ -75,7 +76,6 @@ int main __P((int, char *[])); static int argtoi __P((int, char *, char *, int)); static int checkfilesys __P((char *, char *, long, int)); -static int docheck __P((struct fstab *)); static void usage __P((void)); @@ -166,22 +166,6 @@ argtoi(flag, req, str, base) return (ret); } -/* - * Determine whether a filesystem should be checked. - */ -static int -docheck(fsp) - register struct fstab *fsp; -{ - - if ( strcmp(fsp->fs_vfstype, "ext2fs") || - (strcmp(fsp->fs_type, FSTAB_RW) && - strcmp(fsp->fs_type, FSTAB_RO)) || - fsp->fs_passno == 0) - return (0); - return (1); -} - /* * Check the specified filesystem. */ @@ -195,7 +179,7 @@ checkfilesys(filesys, mntpt, auxdata, child) daddr_t n_bfree; struct dups *dp; struct zlncnt *zlnp; - int cylno; + int i; if (preen && child) (void)signal(SIGQUIT, voidquit); @@ -213,6 +197,10 @@ checkfilesys(filesys, mntpt, auxdata, child) * 1: scan inodes tallying blocks used */ if (preen == 0) { + if (sblock.e2fs.e2fs_rev > E2FS_REV0) { + printf("** Last Mounted on %s\n", + sblock.e2fs.e2fs_fsmnt); + } if (hotroot()) printf("** Root file system\n"); printf("** Phase 1 - Check Blocks and Sizes\n"); @@ -269,7 +257,8 @@ checkfilesys(filesys, mntpt, auxdata, child) (n_files -= maxino - 9 - sblock.e2fs.e2fs_ficount)) printf("%d files missing\n", n_files); if (debug) { - n_blks += sblock.e2fs_ncg * cgoverhead; + for (i = 0; i < sblock.e2fs_ncg; i++) + n_blks += cgoverhead(i); n_blks += sblock.e2fs.e2fs_first_dblock; if (n_blks -= maxfsblock - n_bfree) printf("%d blocks missing\n", n_blks); @@ -286,9 +275,9 @@ checkfilesys(filesys, mntpt, auxdata, child) printf("\n"); } } - zlnhead = NULL; - duplist = NULL; - muldup = NULL; + zlnhead = (struct zlncnt *)0; + duplist = (struct dups *)0; + muldup = (struct dups *)0; inocleanup(); if (fsmodified) { time_t t; diff --git a/sbin/fsck_ext2fs/pass1.c b/sbin/fsck_ext2fs/pass1.c index e753290ab8d..b949d49f304 100644 --- a/sbin/fsck_ext2fs/pass1.c +++ b/sbin/fsck_ext2fs/pass1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.c,v 1.4 1998/11/11 08:10:36 deraadt Exp $ */ +/* $OpenBSD: pass1.c,v 1.5 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: pass1.c,v 1.1 1997/06/11 11:21:51 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; #if 0 static char rcsid[] = "$NetBSD: pass1.c,v 1.1 1997/06/11 11:21:51 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: pass1.c,v 1.4 1998/11/11 08:10:36 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: pass1.c,v 1.5 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -58,6 +58,7 @@ static char rcsid[] = "$OpenBSD: pass1.c,v 1.4 1998/11/11 08:10:36 deraadt Exp $ #include #include #include +#include #include "fsck.h" #include "extern.h" @@ -71,20 +72,45 @@ void pass1() { ino_t inumber; - int c, i, cgd; + int c, i; + daddr_t dbase; struct inodesc idesc; /* * Set file system reserved blocks in used block map. */ for (c = 0; c < sblock.e2fs_ncg; c++) { - i = c * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock; - cgd = i + cgoverhead; + dbase = c * sblock.e2fs.e2fs_bpg + + sblock.e2fs.e2fs_first_dblock; + /* Mark the blocks used for the inode table */ + if (fs2h32(sblock.e2fs_gd[c].ext2bgd_i_tables) >= dbase) { + for (i = 0; i < sblock.e2fs_itpg; i++) + setbmap( + fs2h32(sblock.e2fs_gd[c].ext2bgd_i_tables) + + i); + } + /* Mark the blocks used for the block bitmap */ + if (fs2h32(sblock.e2fs_gd[c].ext2bgd_b_bitmap) >= dbase) + setbmap(fs2h32(sblock.e2fs_gd[c].ext2bgd_b_bitmap)); + /* Mark the blocks used for the inode bitmap */ + if (fs2h32(sblock.e2fs_gd[c].ext2bgd_i_bitmap) >= dbase) + setbmap(fs2h32(sblock.e2fs_gd[c].ext2bgd_i_bitmap)); + + if (sblock.e2fs.e2fs_rev == E2FS_REV0 || + (sblock.e2fs.e2fs_features_rocompat & + EXT2F_ROCOMPAT_SPARSESUPER) == 0 || + cg_has_sb(c)) { + /* Mark copuy of SB and descriptors */ + setbmap(dbase); + for (i = 1; i <= sblock.e2fs_ngdb; i++) + setbmap(dbase+i); + } - if (c == 0) - i = 0; - for (; i < cgd; i++) - setbmap(i); + + if (c == 0) { + for(i = 0; i < dbase; i++) + setbmap(i); + } } /* @@ -108,8 +134,6 @@ pass1() freeinodebuf(); } -#define MODE_USES_BLOCKS( mode ) (mode == IFREG || mode == IFDIR || mode == IFLNK) - static void checkinode(inumber, idesc) ino_t inumber; @@ -119,13 +143,12 @@ checkinode(inumber, idesc) struct zlncnt *zlnp; int ndb, j; mode_t mode; - char *symbuf; dp = getnextinode(inumber); if (inumber < EXT2_FIRSTINO && inumber != EXT2_ROOTINO) 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 && ( memcmp(dp->e2di_blocks, zino.e2di_blocks, @@ -147,7 +170,7 @@ checkinode(inumber, idesc) if (preen || reply("CORRECT")) { time_t t; time(&t); - dp->e2di_dtime = t; + dp->e2di_dtime = h2fs32(t); dp = ginode(inumber); inodirty(); } @@ -158,7 +181,7 @@ checkinode(inumber, idesc) } lastino = inumber; if (dp->e2di_dtime != 0) { - time_t t = dp->e2di_dtime; + time_t t = fs2h32(dp->e2di_dtime); char *p = ctime(&t); pwarn("INODE I=%u HAS DTIME=%12.12s %4.4s", inumber, &p[4], &p[20]); if (preen) { @@ -171,64 +194,68 @@ checkinode(inumber, idesc) } } 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) - printf("bad size %qu:", dp->e2di_size); + printf("bad size %lu:", (u_long)fs2h32(dp->e2di_size)); goto unknown; } if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { dp = ginode(inumber); - dp->e2di_size = sblock.e2fs_bsize; - dp->e2di_mode = IFREG|0600; + dp->e2di_size = h2fs32(sblock.e2fs_bsize); + dp->e2di_mode = h2fs16(IFREG|0600); inodirty(); } - if (MODE_USES_BLOCKS( mode )) { - ndb = howmany(dp->e2di_size, sblock.e2fs_bsize); - if (ndb < 0) { - if (debug) - printf("bad size %qu ndb %d:", - dp->e2di_size, ndb); - goto unknown; - } - if (mode == IFBLK || mode == IFCHR) - ndb++; - if (mode == IFLNK) { - /* - * Fake ndb value so direct/indirect block checks below - * will detect any garbage after symlink string. - */ - if (dp->e2di_size < EXT2_MAXSYMLINKLEN || - (EXT2_MAXSYMLINKLEN == 0 && dp->e2di_blocks == 0)) { - ndb = howmany(dp->e2di_size, sizeof(u_int32_t)); - if (ndb > NDADDR) { - j = ndb - NDADDR; - for (ndb = 1; j > 1; j--) - ndb *= NINDIR(&sblock); - ndb += NDADDR; - } + ndb = howmany(fs2h32(dp->e2di_size), sblock.e2fs_bsize); + if (ndb < 0) { + if (debug) + printf("bad size %lu ndb %d:", + (u_long)fs2h32(dp->e2di_size), ndb); + goto unknown; + } + if (mode == IFBLK || mode == IFCHR) + ndb++; + if (mode == IFLNK) { + /* + * Fake ndb value so direct/indirect block checks below + * will detect any garbage after symlink string. + */ + if (fs2h32(dp->e2di_size) < EXT2_MAXSYMLINKLEN || + (EXT2_MAXSYMLINKLEN == 0 && dp->e2di_blocks == 0)) { + ndb = howmany(fs2h32(dp->e2di_size), sizeof(u_int32_t)); + if (ndb > NDADDR) { + j = ndb - NDADDR; + for (ndb = 1; j > 1; j--) + ndb *= NINDIR(&sblock); + ndb += NDADDR; } } + } + /* Linux puts things in blocks for FIFO, so skip this check */ + if (mode != IFIFO) { for (j = ndb; j < NDADDR; j++) if (dp->e2di_blocks[j] != 0) { 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; } for (j = 0, ndb -= NDADDR; ndb > 0; j++) ndb /= NINDIR(&sblock); - for (; j < NIADDR; j++) + for (; j < NIADDR; j++) { if (dp->e2di_blocks[j+NDADDR] != 0) { if (debug) printf("bad indirect addr: %d\n", - dp->e2di_blocks[j+NDADDR]); + fs2h32(dp->e2di_blocks[j+NDADDR])); goto unknown; } + } } if (ftypeok(dp) == 0) goto unknown; n_files++; - lncntp[inumber] = dp->e2di_nlink; - if (dp->e2di_nlink <= 0) { + lncntp[inumber] = fs2h16(dp->e2di_nlink); + if (dp->e2di_nlink == 0) { zlnp = (struct zlncnt *)malloc(sizeof *zlnp); if (zlnp == NULL) { pfatal("LINK COUNT TABLE OVERFLOW"); @@ -249,22 +276,21 @@ checkinode(inumber, idesc) } else { statemap[inumber] = FSTATE; } - if (MODE_USES_BLOCKS( mode )) { - badblk = dupblk = 0; - idesc->id_number = inumber; - (void)ckinode(dp, idesc); - idesc->id_entryno *= btodb(sblock.e2fs_bsize); - if (dp->e2di_nblock != idesc->id_entryno) { - pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)", - inumber, dp->e2di_nblock, idesc->id_entryno); - if (preen) - printf(" (CORRECTED)\n"); - else if (reply("CORRECT") == 0) - return; - dp = ginode(inumber); - dp->e2di_nblock = idesc->id_entryno; - inodirty(); - } + typemap[inumber] = E2IFTODT(mode); + badblk = dupblk = 0; + idesc->id_number = inumber; + (void)ckinode(dp, idesc); + idesc->id_entryno *= btodb(sblock.e2fs_bsize); + if (fs2h32(dp->e2di_nblock) != idesc->id_entryno) { + pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)", + inumber, fs2h32(dp->e2di_nblock), idesc->id_entryno); + if (preen) + printf(" (CORRECTED)\n"); + else if (reply("CORRECT") == 0) + return; + dp = ginode(inumber); + dp->e2di_nblock = h2fs32(idesc->id_entryno); + inodirty(); } return; unknown: diff --git a/sbin/fsck_ext2fs/pass2.c b/sbin/fsck_ext2fs/pass2.c index 5a930f89afc..82adaef078e 100644 --- a/sbin/fsck_ext2fs/pass2.c +++ b/sbin/fsck_ext2fs/pass2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass2.c,v 1.3 1997/06/14 04:16:56 downsj Exp $ */ +/* $OpenBSD: pass2.c,v 1.4 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: pass2.c,v 1.1 1997/06/11 11:21:53 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; #if 0 static char rcsid[] = "$NetBSD: pass2.c,v 1.1 1997/06/11 11:21:53 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: pass2.c,v 1.3 1997/06/14 04:16:56 downsj Exp $"; +static char rcsid[] = "$OpenBSD: pass2.c,v 1.4 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -112,8 +112,7 @@ pass2() if (reply("FIX") == 0) errexit("%s\n", ""); dp = ginode(EXT2_ROOTINO); - dp->e2di_mode &= ~IFMT; - dp->e2di_mode |= IFDIR; + dp->e2di_mode = h2fs16((fs2h16(dp->e2di_mode) & ~IFMT) | IFDIR); inodirty(); break; @@ -144,25 +143,25 @@ pass2() inp->i_isize = roundup(MINDIRSIZE, sblock.e2fs_bsize); if (reply("FIX") == 1) { dp = ginode(inp->i_number); - dp->e2di_size = inp->i_isize; + dp->e2di_size = h2fs32(inp->i_isize); inodirty(); } } else if ((inp->i_isize & (sblock.e2fs_bsize - 1)) != 0) { getpathname(pathbuf, inp->i_number, inp->i_number); - pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d", - pathbuf, inp->i_isize, sblock.e2fs_bsize); + pwarn("DIRECTORY %s: LENGTH %lu NOT MULTIPLE OF %d", + pathbuf, (u_long)inp->i_isize, sblock.e2fs_bsize); if (preen) printf(" (ADJUSTED)\n"); inp->i_isize = roundup(inp->i_isize, sblock.e2fs_bsize); if (preen || reply("ADJUST") == 1) { dp = ginode(inp->i_number); - dp->e2di_size = inp->i_isize; + dp->e2di_size = h2fs32(inp->i_isize); inodirty(); } } memset(&dino, 0, sizeof(struct ext2fs_dinode)); - dino.e2di_mode = IFDIR; - dino.e2di_size = inp->i_isize; + dino.e2di_mode = h2fs16(IFDIR); + dino.e2di_size = h2fs32(inp->i_isize); memcpy(&dino.e2di_blocks[0], &inp->i_blks[0], (size_t)inp->i_numblks); curino.id_number = inp->i_number; curino.id_parent = inp->i_parent; @@ -221,40 +220,53 @@ pass2check(idesc) */ if (idesc->id_entryno != 0) goto chk1; - if (dirp->e2d_ino != 0 && dirp->e2d_namlen == 1 && + if (fs2h32(dirp->e2d_ino) != 0 && dirp->e2d_namlen == 1 && 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 '.'"); - dirp->e2d_ino = idesc->id_number; + dirp->e2d_ino = h2fs32(idesc->id_number); + if (reply("FIX") == 1) + ret |= ALTERED; + } + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) + && (dirp->e2d_type != EXT2_FT_DIR)) { + direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'"); + dirp->e2d_type = EXT2_FT_DIR; if (reply("FIX") == 1) ret |= ALTERED; } goto chk1; } direrror(idesc->id_number, "MISSING '.'"); - proto.e2d_ino = idesc->id_number; + proto.e2d_ino = h2fs32(idesc->id_number); proto.e2d_namlen = 1; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + proto.e2d_type = EXT2_FT_DIR; + else + proto.e2d_type = 0; (void)strcpy(proto.e2d_name, "."); entrysize = EXT2FS_DIRSIZ(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", dirp->e2d_name); - } else if (dirp->e2d_reclen < entrysize) { + } else if (fs2h16(dirp->e2d_reclen) < entrysize) { 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; memcpy(dirp, &proto, (size_t)entrysize); if (reply("FIX") == 1) ret |= ALTERED; } else { - n = dirp->e2d_reclen - entrysize; - proto.e2d_reclen = entrysize; + n = fs2h16(dirp->e2d_reclen) - entrysize; + proto.e2d_reclen = h2fs16(entrysize); memcpy(dirp, &proto, (size_t)entrysize); idesc->id_entryno++; - lncntp[dirp->e2d_ino]--; + lncntp[fs2h32(dirp->e2d_ino)]--; dirp = (struct ext2fs_direct *)((char *)(dirp) + entrysize); memset(dirp, 0, (size_t)n); - dirp->e2d_reclen = n; + dirp->e2d_reclen = h2fs16(n); if (reply("FIX") == 1) ret |= ALTERED; } @@ -262,36 +274,49 @@ chk1: if (idesc->id_entryno > 1) goto chk2; inp = getinoinfo(idesc->id_number); - proto.e2d_ino = inp->i_parent; + proto.e2d_ino = h2fs32(inp->i_parent); proto.e2d_namlen = 2; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) + proto.e2d_type = EXT2_FT_DIR; + else + proto.e2d_type = 0; (void)strcpy(proto.e2d_name, ".."); - entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen); + entrysize = EXT2FS_DIRSIZ(2); if (idesc->id_entryno == 0) { n = EXT2FS_DIRSIZ(dirp->e2d_namlen); - if (dirp->e2d_reclen < n + entrysize) + if (fs2h16(dirp->e2d_reclen) < n + entrysize) goto chk2; - proto.e2d_reclen = dirp->e2d_reclen - n; - dirp->e2d_reclen = n; + proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n); + dirp->e2d_reclen = h2fs16(n); idesc->id_entryno++; - lncntp[dirp->e2d_ino]--; + lncntp[fs2h32(dirp->e2d_ino)]--; 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; } - if (dirp->e2d_ino != 0 && - dirp->e2d_namlen == 2 && - strncmp(dirp->e2d_name, "..", dirp->e2d_namlen) == 0) { - inp->i_dotdot = dirp->e2d_ino; + if (fs2h32(dirp->e2d_ino) != 0 && + dirp->e2d_namlen == 2 && + strncmp(dirp->e2d_name, "..", 2) == 0) { + inp->i_dotdot = fs2h32(dirp->e2d_ino); + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) + && dirp->e2d_type != EXT2_FT_DIR) { + direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'"); + dirp->e2d_type = EXT2_FT_DIR; + if (reply("FIX") == 1) + ret |= ALTERED; + } goto chk2; } - if (dirp->e2d_ino != 0 && + if (fs2h32(dirp->e2d_ino) != 0 && 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 '..'"); pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", dirp->e2d_name); 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 '..'"); pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n"); inp->i_dotdot = (ino_t)-1; @@ -307,11 +332,11 @@ chk1: ret |= ALTERED; } idesc->id_entryno++; - if (dirp->e2d_ino != 0) - lncntp[dirp->e2d_ino]--; + if (fs2h32(dirp->e2d_ino) != 0) + lncntp[fs2h32(dirp->e2d_ino)]--; return (ret|KEEPON); chk2: - if (dirp->e2d_ino == 0) + if (fs2h32(dirp->e2d_ino) == 0) return (ret|KEEPON); if (dirp->e2d_namlen <= 2 && dirp->e2d_name[0] == '.' && @@ -333,17 +358,18 @@ chk2: } idesc->id_entryno++; n = 0; - if (dirp->e2d_ino > maxino || - (dirp->e2d_ino < EXT2_FIRSTINO && dirp->e2d_ino != EXT2_ROOTINO)) { - fileerror(idesc->id_number, dirp->e2d_ino, "I OUT OF RANGE"); + if (fs2h32(dirp->e2d_ino) > maxino || + (fs2h32(dirp->e2d_ino) < EXT2_FIRSTINO && + fs2h32(dirp->e2d_ino) != EXT2_ROOTINO)) { + fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "I OUT OF RANGE"); n = reply("REMOVE"); } else { again: - switch (statemap[dirp->e2d_ino]) { + switch (statemap[fs2h32(dirp->e2d_ino)]) { case USTATE: if (idesc->id_entryno <= 2) break; - fileerror(idesc->id_number, dirp->e2d_ino, "UNALLOCATED"); + fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), "UNALLOCATED"); n = reply("REMOVE"); break; @@ -351,7 +377,7 @@ again: case FCLEAR: if (idesc->id_entryno <= 2) break; - if (statemap[dirp->e2d_ino] == FCLEAR) + if (statemap[fs2h32(dirp->e2d_ino)] == FCLEAR) errmsg = "DUP/BAD"; else if (!preen) errmsg = "ZERO LENGTH DIRECTORY"; @@ -359,22 +385,23 @@ again: n = 1; break; } - fileerror(idesc->id_number, dirp->e2d_ino, errmsg); + fileerror(idesc->id_number, fs2h32(dirp->e2d_ino), errmsg); if ((n = reply("REMOVE")) == 1) break; - dp = ginode(dirp->e2d_ino); - statemap[dirp->e2d_ino] = - (dp->e2di_mode & IFMT) == IFDIR ? DSTATE : FSTATE; - lncntp[dirp->e2d_ino] = dp->e2di_nlink; + dp = ginode(fs2h32(dirp->e2d_ino)); + statemap[fs2h32(dirp->e2d_ino)] = + (fs2h16(dp->e2di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE; + lncntp[fs2h32(dirp->e2d_ino)] = fs2h16(dp->e2di_nlink); goto again; case DSTATE: case DFOUND: - inp = getinoinfo(dirp->e2d_ino); + inp = getinoinfo(fs2h32(dirp->e2d_ino)); if (inp->i_parent != 0 && idesc->id_entryno > 2) { getpathname(pathbuf, 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, "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", namebuf); @@ -388,12 +415,25 @@ again: /* fall through */ case FSTATE: - lncntp[dirp->e2d_ino]--; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + (sblock.e2fs.e2fs_features_incompat & + EXT2F_INCOMPAT_FTYPE) && + dirp->e2d_type != + inot2ext2dt(typemap[fs2h32(dirp->e2d_ino)])) { + dirp->e2d_type = + inot2ext2dt(typemap[fs2h32(dirp->e2d_ino)]); + fileerror(idesc->id_number, + fs2h32(dirp->e2d_ino), + "BAD TYPE VALUE"); + if (reply("FIX") == 1) + ret |= ALTERED; + } + lncntp[fs2h32(dirp->e2d_ino)]--; break; default: 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) diff --git a/sbin/fsck_ext2fs/pass5.c b/sbin/fsck_ext2fs/pass5.c index 586c8c6d692..e6d2f0a0af4 100644 --- a/sbin/fsck_ext2fs/pass5.c +++ b/sbin/fsck_ext2fs/pass5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass5.c,v 1.4 1997/06/14 05:04:12 downsj Exp $ */ +/* $OpenBSD: pass5.c,v 1.5 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: pass5.c,v 1.1 1997/06/11 11:21:58 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94"; #if 0 static char rcsid[] = "$NetBSD: pass5.c,v 1.1 1997/06/11 11:21:58 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: pass5.c,v 1.4 1997/06/14 05:04:12 downsj Exp $"; +static char rcsid[] = "$OpenBSD: pass5.c,v 1.5 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -66,7 +66,7 @@ void print_bmap __P((u_char *,u_int32_t)); void pass5() { - int c, blk, frags, basesize, sumsize, mapsize, savednrpos; + int c; register struct m_ext2fs *fs = &sblock; daddr_t dbase, dmax; register daddr_t d; @@ -97,17 +97,17 @@ pass5() ndirs = 0; 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); } 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); } 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); } 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); } memset(bbmap, 0, fs->e2fs_bsize); @@ -147,7 +147,7 @@ pass5() break; default: - errexit("BAD STATE %d FOR INODE I=%d\n", + errexit("BAD STATE %d FOR INODE I=%ld\n", statemap[j], j); } } @@ -156,13 +156,12 @@ pass5() for (i = fs->e2fs.e2fs_ipg / NBBY; i < fs->e2fs_bsize; i++) ibmap[i] = 0xff; - dbase = c * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock + - cgoverhead; - dmax = (c+1) * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock; + dbase = c * sblock.e2fs.e2fs_bpg + + sblock.e2fs.e2fs_first_dblock; + dmax = (c+1) * sblock.e2fs.e2fs_bpg + + sblock.e2fs.e2fs_first_dblock; - for (i = 0; i < cgoverhead; i++) - setbit(bbmap, i); /* blks allocated to fs metadata */ - for (i = cgoverhead, d = dbase; + for (i = 0, d = dbase; d < dmax; d ++, i ++) { if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) { @@ -177,26 +176,27 @@ pass5() cs_nifree += nifree; cs_ndir += ndirs; - if (debug && (fs->e2fs_gd[c].ext2bgd_nbfree != nbfree || - fs->e2fs_gd[c].ext2bgd_nifree != nifree || - fs->e2fs_gd[c].ext2bgd_ndirs != ndirs)) { + if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || + fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || + fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) { printf("summary info for cg %d is %d, %d, %d," "should be %d, %d, %d\n", c, - fs->e2fs_gd[c].ext2bgd_nbfree, - fs->e2fs_gd[c].ext2bgd_nifree, - fs->e2fs_gd[c].ext2bgd_ndirs, + fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree), + fs2h16(fs->e2fs_gd[c].ext2bgd_nifree), + fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs), nbfree, nifree, ndirs); } - snprintf(msg, 255, "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); - if ((fs->e2fs_gd[c].ext2bgd_nbfree != nbfree || - fs->e2fs_gd[c].ext2bgd_nifree != nifree || - fs->e2fs_gd[c].ext2bgd_ndirs != ndirs) && + (void)snprintf(msg, sizeof(msg), + "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); + if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || + fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || + fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) && dofix(&idesc[0], msg)) { - fs->e2fs_gd[c].ext2bgd_nbfree = nbfree; - fs->e2fs_gd[c].ext2bgd_nifree = nifree; - fs->e2fs_gd[c].ext2bgd_ndirs = ndirs; + fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree); + fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree); + fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs); sbdirty(); } @@ -207,7 +207,8 @@ pass5() print_bmap(bbmap, fs->e2fs_bsize); } - snprintf(msg, 255, "BLK(S) MISSING IN BIT MAPS #%d", c); + (void)snprintf(msg, sizeof(msg), + "BLK(S) MISSING IN BIT MAPS #%d", c); if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) && dofix(&idesc[1], msg)) { memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize); @@ -219,7 +220,8 @@ pass5() printf("ibmap:\n"); print_bmap(ibmap, fs->e2fs_bsize); } - snprintf(msg, 255, "INODE(S) MISSING IN BIT MAPS #%d", c); + (void)snprintf(msg, sizeof(msg), + "INODE(S) MISSING IN BIT MAPS #%d", c); if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) && dofix(&idesc[1], msg)) { memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize); diff --git a/sbin/fsck_ext2fs/setup.c b/sbin/fsck_ext2fs/setup.c index 9af2f9640a6..e13d8c0055c 100644 --- a/sbin/fsck_ext2fs/setup.c +++ b/sbin/fsck_ext2fs/setup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setup.c,v 1.5 1999/08/17 09:13:14 millert Exp $ */ +/* $OpenBSD: setup.c,v 1.6 2000/04/26 23:26:06 jasoni Exp $ */ /* $NetBSD: setup.c,v 1.1 1997/06/11 11:22:01 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; #if 0 static char rcsid[] = "$NetBSD: setup.c,v 1.1 1997/06/11 11:22:01 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: setup.c,v 1.5 1999/08/17 09:13:14 millert Exp $"; +static char rcsid[] = "$OpenBSD: setup.c,v 1.6 2000/04/26 23:26:06 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -55,6 +55,7 @@ static char rcsid[] = "$OpenBSD: setup.c,v 1.5 1999/08/17 09:13:14 millert Exp $ #include #include #include +#include #include #include @@ -67,12 +68,10 @@ static char rcsid[] = "$OpenBSD: setup.c,v 1.5 1999/08/17 09:13:14 millert Exp $ #include "extern.h" #include "fsutil.h" -struct bufarea asblk; -#define altsblock (*asblk.b_un.b_fs) #define POWEROF2(num) (((num) & ((num) - 1)) == 0) void badsb __P((int, char *)); -/* int calcsb __P((char *, int, struct m_ext2fs *)); */ +int calcsb __P((char *, int, struct m_ext2fs *)); static struct disklabel *getdisklabel __P((char *, int)); static int readsb __P((int)); @@ -80,7 +79,7 @@ int setup(dev) char *dev; { - long cg, size, asked, i, j; + long cg, asked, i; long bmapsize; struct disklabel *lp; off_t sizepb; @@ -119,8 +118,8 @@ setup(dev) lfdir = 0; initbarea(&sblk); initbarea(&asblk); - sblk.b_un.b_buf = malloc(sizeof(struct m_ext2fs)); - asblk.b_un.b_buf = malloc(sizeof(struct m_ext2fs)); + 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"); if ((lp = getdisklabel((char *)NULL, fsreadfd)) != NULL) @@ -183,6 +182,7 @@ setup(dev) if (reply("SET TO DEFAULT") == 1) { sblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_bcount * 0.1; sbdirty(); + dirty(&asblk); } } if (sblock.e2fs.e2fs_bpg != sblock.e2fs.e2fs_fpg) { @@ -191,7 +191,7 @@ setup(dev) return 0; } if (asblk.b_dirty && !bflag) { - memcpy(&altsblock, &sblock, (size_t)SBSIZE); + copyback_sb(&asblk); flush(fswritefd, &asblk); } /* @@ -199,6 +199,8 @@ setup(dev) */ sblock.e2fs_gd = malloc(sblock.e2fs_ngdb * sblock.e2fs_bsize); + if (sblock.e2fs_gd == NULL) + errexit("out of memory\n"); asked = 0; for (i=0; i < sblock.e2fs_ngdb; i++) { if (bread(fsreadfd,(char *) @@ -227,14 +229,20 @@ setup(dev) (unsigned)(maxino + 1)); goto badsblabel; } + typemap = calloc((unsigned)(maxino + 1), sizeof(char)); + if (typemap == NULL) { + printf("cannot alloc %u bytes for typemap\n", + (unsigned)(maxino + 1)); + goto badsblabel; + } lncntp = (int16_t *)calloc((unsigned)(maxino + 1), sizeof(int16_t)); if (lncntp == NULL) { printf("cannot alloc %u bytes for lncntp\n", - (unsigned)(maxino + 1) * sizeof(int16_t)); + (unsigned)((maxino + 1) * sizeof(int16_t))); goto badsblabel; } 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; listmax = numdirs + 10; @@ -244,7 +252,7 @@ setup(dev) sizeof(struct inoinfo *)); if (inpsort == NULL || inphead == NULL) { printf("cannot alloc %u bytes for inphead\n", - (unsigned)numdirs * sizeof(struct inoinfo *)); + (unsigned)(numdirs * sizeof(struct inoinfo *))); goto badsblabel; } bufinit(); @@ -264,10 +272,14 @@ readsb(listerr) { 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); sblk.b_bno = super; sblk.b_size = SBSIZE; + + /* Copy the superblock in memory */ + e2fs_sbload(sblk.b_un.b_fs, &sblock.e2fs); + /* * run a few consistency checks of the super block */ @@ -294,14 +306,6 @@ readsb(listerr) sblock.e2fs_ipb = sblock.e2fs_bsize / sizeof(struct ext2fs_dinode); sblock.e2fs_itpg = sblock.e2fs.e2fs_ipg/sblock.e2fs_ipb; - cgoverhead = 1 /* super block */ + - sblock.e2fs_ngdb + - 1 /* block bitmap */ + - 1 /* inode bitmap */ + - sblock.e2fs_itpg; - - if (debug) /* DDD */ - printf("cg overhead %d blocks \n", cgoverhead); /* * Compute block size that the filesystem is based on, * according to fsbtodb, and adjust superblock block number @@ -310,6 +314,11 @@ readsb(listerr) super *= dev_bsize; dev_bsize = sblock.e2fs_bsize / fsbtodb(&sblock, 1); 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) { havesb = 1; return (1); @@ -320,36 +329,49 @@ readsb(listerr) * of whole super block against an alternate super block. * When an alternate super-block is specified this check is skipped. */ - getblk(&asblk, 1 * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock, - (long)SBSIZE); - if (asblk.b_errs) - return (0); - altsblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_rbcount; - altsblock.e2fs.e2fs_fbcount = sblock.e2fs.e2fs_fbcount; - altsblock.e2fs.e2fs_ficount = sblock.e2fs.e2fs_ficount; - altsblock.e2fs.e2fs_mtime = sblock.e2fs.e2fs_mtime; - altsblock.e2fs.e2fs_wtime = sblock.e2fs.e2fs_wtime; - altsblock.e2fs.e2fs_mnt_count = sblock.e2fs.e2fs_mnt_count; - altsblock.e2fs.e2fs_max_mnt_count = sblock.e2fs.e2fs_max_mnt_count; - altsblock.e2fs.e2fs_state = sblock.e2fs.e2fs_state; - altsblock.e2fs.e2fs_beh = sblock.e2fs.e2fs_beh; - altsblock.e2fs.e2fs_lastfsck = sblock.e2fs.e2fs_lastfsck; - 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)) { + asblk.b_un.b_fs->e2fs_rbcount = sblk.b_un.b_fs->e2fs_rbcount; + asblk.b_un.b_fs->e2fs_fbcount = sblk.b_un.b_fs->e2fs_fbcount; + asblk.b_un.b_fs->e2fs_ficount = sblk.b_un.b_fs->e2fs_ficount; + asblk.b_un.b_fs->e2fs_mtime = sblk.b_un.b_fs->e2fs_mtime; + asblk.b_un.b_fs->e2fs_wtime = sblk.b_un.b_fs->e2fs_wtime; + asblk.b_un.b_fs->e2fs_mnt_count = sblk.b_un.b_fs->e2fs_mnt_count; + asblk.b_un.b_fs->e2fs_max_mnt_count = sblk.b_un.b_fs->e2fs_max_mnt_count; + asblk.b_un.b_fs->e2fs_state = sblk.b_un.b_fs->e2fs_state; + asblk.b_un.b_fs->e2fs_beh = sblk.b_un.b_fs->e2fs_beh; + asblk.b_un.b_fs->e2fs_lastfsck = sblk.b_un.b_fs->e2fs_lastfsck; + asblk.b_un.b_fs->e2fs_fsckintv = sblk.b_un.b_fs->e2fs_fsckintv; + asblk.b_un.b_fs->e2fs_ruid = sblk.b_un.b_fs->e2fs_ruid; + asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid; + asblk.b_un.b_fs->e2fs_block_group_nr = + sblk.b_un.b_fs->e2fs_block_group_nr; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + ((sblock.e2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) || + (sblock.e2fs.e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) { + if (debug) { + printf("compat 0x%08x, incompat 0x%08x, compat_ro " + "0x%08x\n", + sblock.e2fs.e2fs_features_compat, + sblock.e2fs.e2fs_features_incompat, + sblock.e2fs.e2fs_features_rocompat); + } + badsb(listerr,"INCOMPATIBLE FEATURE BITS IN SUPER BLOCK"); + return 0; + } + if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) { if (debug) { - long *nlp, *olp, *endlp; + u_int32_t *nlp, *olp, *endlp; printf("superblock mismatches\n"); - nlp = (long *)&altsblock; - olp = (long *)&sblock; + nlp = (u_int32_t *)asblk.b_un.b_fs; + olp = (u_int32_t *)sblk.b_un.b_fs; endlp = olp + (SBSIZE / sizeof *olp); for ( ; olp < endlp; olp++, nlp++) { if (*olp == *nlp) continue; - printf("offset %d, original %ld, alternate %ld\n", - olp - (long *)&sblock, *olp, *nlp); + printf("offset %ld, original %ld, alternate %ld\n", + (long)(olp - (u_int32_t *)sblk.b_un.b_fs), + (long)fs2h32(*olp), + (long)fs2h32(*nlp)); } } badsb(listerr, @@ -360,6 +382,39 @@ readsb(listerr) 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 badsb(listerr, s) int listerr; @@ -389,7 +444,6 @@ calcsb(dev, devfd, fs) register struct disklabel *lp; register struct partition *pp; register char *cp; - int i; cp = strchr(dev, '\0') - 1; if ((cp == (char *)-1 || (*cp < 'a' || *cp > 'h')) && !isdigit(*cp)) { @@ -401,17 +455,17 @@ calcsb(dev, devfd, fs) pp = &lp->d_partitions[0]; else pp = &lp->d_partitions[*cp - 'a']; - if (pp->p_fstype != FS_BSDFFS) { - pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n", + if (pp->p_fstype != FS_EXT2FS) { + pfatal("%s: NOT LABELED AS A EXT2 FILE SYSTEM (%s)\n", dev, pp->p_fstype < FSMAXTYPES ? fstypenames[pp->p_fstype] : "unknown"); return (0); } memset(fs, 0, sizeof(struct m_ext2fs)); - fs->e2fs_bsize = 1024; /* XXX to look for altenate SP */ - fs->e2fs.e2fs_log_bsize = 0; + fs->e2fs_bsize = pp->p_fsize; + fs->e2fs.e2fs_log_bsize = pp->p_fsize / 1024; 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_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize; fs->e2fs_qbmask = fs->e2fs_bsize - 1; @@ -423,8 +477,6 @@ calcsb(dev, devfd, fs) fs->e2fs_ngdb = howmany(fs->e2fs_ncg, fs->e2fs_bsize / sizeof(struct ext2_gd)); - - return (1); } @@ -443,3 +495,20 @@ getdisklabel(s, fd) } return (&lab); } + +daddr_t +cgoverhead(c) + int c; +{ + int overh; + overh = 1 /* block bitmap */ + + 1 /* inode bitmap */ + + sblock.e2fs_itpg; + if (sblock.e2fs.e2fs_rev > E2FS_REV0 && + sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) { + if (cg_has_sb(c) == 0) + return overh; + } + overh += 1 + sblock.e2fs_ngdb; + return overh; +} diff --git a/sbin/fsck_ext2fs/utilities.c b/sbin/fsck_ext2fs/utilities.c index d83136ce00d..5f4739a3ef4 100644 --- a/sbin/fsck_ext2fs/utilities.c +++ b/sbin/fsck_ext2fs/utilities.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utilities.c,v 1.4 1997/06/25 18:40:43 kstailey Exp $ */ +/* $OpenBSD: utilities.c,v 1.5 2000/04/26 23:26:07 jasoni Exp $ */ /* $NetBSD: utilities.c,v 1.1 1997/06/11 11:22:02 bouyer Exp $ */ /* @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #if 0 static char rcsid[] = "$NetBSD: utilities.c,v 1.1 1997/06/11 11:22:02 bouyer Exp $"; #else -static char rcsid[] = "$OpenBSD: utilities.c,v 1.4 1997/06/25 18:40:43 kstailey Exp $"; +static char rcsid[] = "$OpenBSD: utilities.c,v 1.5 2000/04/26 23:26:07 jasoni Exp $"; #endif #endif #endif /* not lint */ @@ -71,7 +71,7 @@ int ftypeok(dp) struct ext2fs_dinode *dp; { - switch (dp->e2di_mode & IFMT) { + switch (fs2h16(dp->e2di_mode) & IFMT) { case IFDIR: case IFREG: @@ -132,7 +132,8 @@ bufinit() long bufcnt, i; char *bufp; - pbp = pdirbp = NULL; + diskreads = totalreads = 0; + pbp = pdirbp = (struct bufarea *)0; bufhead.b_next = bufhead.b_prev = &bufhead; bufcnt = MAXBUFSPACE / sblock.e2fs_bsize; if (bufcnt < MINBUFS) @@ -174,6 +175,7 @@ getdatablk(blkno, size) if (bp == &bufhead) errexit("deadlocked buffer pool\n"); getblk(bp, blkno, size); + diskreads++; /* fall through */ foundit: totalreads++; @@ -210,7 +212,7 @@ flush(fd, bp) int fd; register struct bufarea *bp; { - register int i, j; + register int i; if (!bp->b_dirty) return; @@ -257,10 +259,13 @@ ckfini(markclean) } flush(fswritefd, &sblk); if (havesb && sblk.b_bno != SBOFF / dev_bsize && - !preen && reply("UPDATE STANDARD SUPERBLOCK")) { + !preen && reply("UPDATE STANDARD SUPERBLOCKS")) { sblk.b_bno = SBOFF / dev_bsize; sbdirty(); flush(fswritefd, &sblk); + copyback_sb(&asblk); + asblk.b_dirty = 1; + flush(fswritefd, &asblk); } for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { cnt++; @@ -271,7 +276,7 @@ ckfini(markclean) } if (bufhead.b_size != cnt) errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt); - pbp = pdirbp = NULL; + pbp = pdirbp = (struct bufarea *)0; if (markclean && (sblock.e2fs.e2fs_state & E2FS_ISCLEAN) == 0) { /* * Mark the file system as clean, and sync the superblock. -- 2.20.1