Support for ext2fs rev. 1
authorjasoni <jasoni@openbsd.org>
Wed, 26 Apr 2000 23:25:33 +0000 (23:25 +0000)
committerjasoni <jasoni@openbsd.org>
Wed, 26 Apr 2000 23:25:33 +0000 (23:25 +0000)
bin/df/ext2fs_df.c
sbin/fsck_ext2fs/dir.c
sbin/fsck_ext2fs/fsck.h
sbin/fsck_ext2fs/inode.c
sbin/fsck_ext2fs/main.c
sbin/fsck_ext2fs/pass1.c
sbin/fsck_ext2fs/pass2.c
sbin/fsck_ext2fs/pass5.c
sbin/fsck_ext2fs/setup.c
sbin/fsck_ext2fs/utilities.c

index 48a30d4..6631485 100644 (file)
@@ -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 */
index 1a146eb..934a004 100644 (file)
@@ -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);
index fd8f5a7..63a3b45 100644 (file)
@@ -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 */
index 48c0c3f..2d50031 100644 (file)
@@ -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);
                }
index 3ddd9b3..5806a97 100644 (file)
@@ -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 <string.h>
 #include <ctype.h>
 #include <stdio.h>
+#include <time.h>
 #include <unistd.h>
 
 #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;
index e753290..b949d49 100644 (file)
@@ -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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
 #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:
index 5a930f8..82adaef 100644 (file)
@@ -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)
index 586c8c6..e6d2f0a 100644 (file)
@@ -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);
index 9af2f96..e13d8c0 100644 (file)
@@ -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 <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
+#include <sys/file.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -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;
+}
index d83136c..5f4739a 100644 (file)
@@ -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.