diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2007-04-10 16:08:18 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2007-04-10 16:08:18 +0000 |
commit | 2c8e080377c510894f310612f6d8a99efc8efc74 (patch) | |
tree | 5be96bc88ef4d998dd50980aae354bc1eec4fdd9 /sbin | |
parent | 037bcc8f2068c6e0961b3b5dd7f6fd375dfc0c02 (diff) |
Add support for checking ffs2 filesystems. From pedro@ based on
the ufs2 changes in FreeBSD by Kirk Mckusick.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/fsck_ffs/dir.c | 94 | ||||
-rw-r--r-- | sbin/fsck_ffs/extern.h | 12 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsck.h | 58 | ||||
-rw-r--r-- | sbin/fsck_ffs/inode.c | 176 | ||||
-rw-r--r-- | sbin/fsck_ffs/main.c | 18 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass1.c | 120 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass1b.c | 6 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass2.c | 40 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass4.c | 70 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 75 | ||||
-rw-r--r-- | sbin/fsck_ffs/setup.c | 134 | ||||
-rw-r--r-- | sbin/fsck_ffs/utilities.c | 35 |
12 files changed, 515 insertions, 323 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index 0b2cd296680..9a408abd944 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dir.c,v 1.19 2007/02/08 13:09:53 otto Exp $ */ +/* $OpenBSD: dir.c,v 1.20 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: dir.c,v 1.20 1996/09/27 22:45:11 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; #else -static const char rcsid[] = "$OpenBSD: dir.c,v 1.19 2007/02/08 13:09:53 otto Exp $"; +static const char rcsid[] = "$OpenBSD: dir.c,v 1.20 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -64,7 +64,7 @@ struct odirtemplate odirhead = { 0, DIRBLKSIZ - 12, 2, ".." }; -static int expanddir(struct ufs1_dinode *, char *); +static int expanddir(union dinode *, char *); static void freedir(ino_t, ino_t); static struct direct *fsck_readdir(struct inodesc *); static struct bufarea *getdirblk(daddr_t, long); @@ -272,7 +272,7 @@ direrror(ino_t ino, char *errmesg) void fileerror(ino_t cwd, ino_t ino, char *errmesg) { - struct ufs1_dinode *dp; + union dinode *dp; char pathbuf[MAXPATHLEN + 1]; pwarn("%s ", errmesg); @@ -286,7 +286,8 @@ fileerror(ino_t cwd, ino_t ino, char *errmesg) dp = ginode(ino); if (ftypeok(dp)) pfatal("%s=%s\n", - (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); + (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE", + pathbuf); else pfatal("NAME=%s\n", pathbuf); } @@ -294,18 +295,18 @@ fileerror(ino_t cwd, ino_t ino, char *errmesg) void adjust(struct inodesc *idesc, short lcnt) { - struct ufs1_dinode *dp; + union dinode *dp; dp = ginode(idesc->id_number); - if (dp->di_nlink == lcnt) { + if (DIP(dp, di_nlink) == lcnt) { if (linkup(idesc->id_number, 0) == 0) clri(idesc, "UNREF", 0); } else { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : - ((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE")); + ((DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE")); pinode(idesc->id_number); - printf(" COUNT %d SHOULD BE %d", - dp->di_nlink, dp->di_nlink - lcnt); + printf(" COUNT %d SHOULD BE %d", DIP(dp, di_nlink), + DIP(dp, di_nlink) - lcnt); if (preen || usedsoftdep) { if (lcnt < 0) { printf("\n"); @@ -315,7 +316,7 @@ adjust(struct inodesc *idesc, short lcnt) printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { - dp->di_nlink -= lcnt; + DIP(dp, di_nlink) -= lcnt; inodirty(); } } @@ -383,7 +384,7 @@ chgino(struct inodesc *idesc) int linkup(ino_t orphan, ino_t parentdir) { - struct ufs1_dinode *dp; + union dinode *dp; int lostdir; ino_t oldlfdir; struct inodesc idesc; @@ -391,10 +392,10 @@ linkup(ino_t orphan, ino_t parentdir) memset(&idesc, 0, sizeof(struct inodesc)); dp = ginode(orphan); - lostdir = (dp->di_mode & IFMT) == IFDIR; + lostdir = (DIP(dp, di_mode) & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pinode(orphan); - if ((preen || usedsoftdep) && dp->di_size == 0) + if ((preen || usedsoftdep) && DIP(dp, di_size) == 0) return (0); if (preen) printf(" (RECONNECTED)\n"); @@ -433,7 +434,7 @@ linkup(ino_t orphan, ino_t parentdir) } } dp = ginode(lfdir); - if ((dp->di_mode & IFMT) != IFDIR) { + if ((DIP(dp, di_mode) & IFMT) != IFDIR) { pfatal("lost+found IS NOT A DIRECTORY"); if (reply("REALLOCATE") == 0) return (0); @@ -470,7 +471,7 @@ linkup(ino_t orphan, ino_t parentdir) parentdir != (ino_t)-1) (void)makeentry(orphan, lfdir, ".."); dp = ginode(lfdir); - dp->di_nlink++; + DIP_SET(dp, di_nlink, DIP(dp, di_nlink) + 1); inodirty(); lncntp[lfdir]++; pwarn("DIR I=%u CONNECTED. ", orphan); @@ -518,7 +519,7 @@ changeino(dir, name, newnum) int makeentry(ino_t parent, ino_t ino, char *name) { - struct ufs1_dinode *dp; + union dinode *dp; struct inodesc idesc; char pathbuf[MAXPATHLEN + 1]; @@ -533,8 +534,8 @@ makeentry(ino_t parent, ino_t ino, char *name) idesc.id_fix = DONTKNOW; idesc.id_name = name; dp = ginode(parent); - if (dp->di_size % DIRBLKSIZ) { - dp->di_size = roundup(dp->di_size, DIRBLKSIZ); + if (DIP(dp, di_size) % DIRBLKSIZ) { + DIP_SET(dp, di_size, roundup(DIP(dp, di_size), DIRBLKSIZ)); inodirty(); } if ((ckinode(dp, &idesc) & ALTERED) != 0) @@ -550,27 +551,28 @@ makeentry(ino_t parent, ino_t ino, char *name) * Attempt to expand the size of a directory */ static int -expanddir(struct ufs1_dinode *dp, char *name) +expanddir(union dinode *dp, char *name) { daddr_t lastbn, newblk; struct bufarea *bp; char *cp, firstblk[DIRBLKSIZ]; u_int64_t dis; - dis = lblkno(&sblock, dp->di_size); + dis = lblkno(&sblock, DIP(dp, di_size)); if (dis > (u_int64_t)INT_MAX) return (0); lastbn = dis; - if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) + if (lastbn >= NDADDR - 1 || DIP(dp, di_db[lastbn]) == 0 || + DIP(dp, di_size) == 0) return (0); if ((newblk = allocblk(sblock.fs_frag)) == 0) return (0); - dp->di_db[lastbn + 1] = dp->di_db[lastbn]; - dp->di_db[lastbn] = newblk; - dp->di_size += sblock.fs_bsize; - dp->di_blocks += btodb(sblock.fs_bsize); - bp = getdirblk(dp->di_db[lastbn + 1], - (long)dblksize(&sblock, dp, lastbn + 1)); + DIP_SET(dp, di_db[lastbn + 1], DIP(dp, di_db[lastbn])); + DIP_SET(dp, di_db[lastbn], newblk); + DIP_SET(dp, di_size, DIP(dp, di_size) + sblock.fs_bsize); + DIP_SET(dp, di_blocks, DIP(dp, di_blocks) + btodb(sblock.fs_bsize)); + bp = getdirblk(DIP(dp, di_db[lastbn + 1]), + sblksize(&sblock, DIP(dp, di_size), lastbn + 1)); if (bp->b_errs) goto bad; memcpy(firstblk, bp->b_un.b_buf, DIRBLKSIZ); @@ -583,8 +585,8 @@ expanddir(struct ufs1_dinode *dp, char *name) cp += DIRBLKSIZ) memcpy(cp, &emptydir, sizeof emptydir); dirty(bp); - bp = getdirblk(dp->di_db[lastbn + 1], - (long)dblksize(&sblock, dp, lastbn + 1)); + bp = getdirblk(DIP(dp, di_db[lastbn + 1]), + sblksize(&sblock, DIP(dp, di_size), lastbn + 1)); if (bp->b_errs) goto bad; memcpy(bp->b_un.b_buf, &emptydir, sizeof emptydir); @@ -597,10 +599,10 @@ expanddir(struct ufs1_dinode *dp, char *name) inodirty(); return (1); bad: - dp->di_db[lastbn] = dp->di_db[lastbn + 1]; - dp->di_db[lastbn + 1] = 0; - dp->di_size -= sblock.fs_bsize; - dp->di_blocks -= btodb(sblock.fs_bsize); + DIP_SET(dp, di_db[lastbn], DIP(dp, di_db[lastbn + 1])); + DIP_SET(dp, di_db[lastbn + 1], 0); + DIP_SET(dp, di_size, DIP(dp, di_size) - sblock.fs_bsize); + DIP_SET(dp, di_blocks, DIP(dp, di_blocks) - btodb(sblock.fs_bsize)); freeblk(newblk, sblock.fs_frag); return (0); } @@ -615,7 +617,7 @@ allocdir(ino_t parent, ino_t request, int mode) uid_t uid; gid_t gid; char *cp; - struct ufs1_dinode *dp; + union dinode *dp; struct bufarea *bp; struct dirtemplate *dirp; struct inoinfo *inp; @@ -628,7 +630,7 @@ allocdir(ino_t parent, ino_t request, int mode) dirp->dot_ino = ino; dirp->dotdot_ino = parent; dp = ginode(ino); - bp = getdirblk(dp->di_db[0], sblock.fs_fsize); + bp = getdirblk(DIP(dp, di_db[0]), sblock.fs_fsize); if (bp->b_errs) { freeino(ino); return (0); @@ -639,10 +641,10 @@ allocdir(ino_t parent, ino_t request, int mode) cp += DIRBLKSIZ) memcpy(cp, &emptydir, sizeof emptydir); dirty(bp); - dp->di_nlink = 2; + DIP_SET(dp, di_nlink, 2); inodirty(); if (ino == ROOTINO) { - lncntp[ino] = dp->di_nlink; + lncntp[ino] = DIP(dp, di_nlink); cacheino(dp, ino); return(ino); } @@ -656,17 +658,17 @@ allocdir(ino_t parent, ino_t request, int mode) inp->i_dotdot = parent; statemap[ino] = statemap[parent]; if (statemap[ino] == DSTATE) { - lncntp[ino] = dp->di_nlink; + lncntp[ino] = DIP(dp, di_nlink); lncntp[parent]++; } dp = ginode(parent); - dp->di_nlink++; - uid = dp->di_uid; - gid = dp->di_gid; + DIP_SET(dp, di_nlink, DIP(dp, di_nlink) + 1); + uid = DIP(dp, di_uid); + gid = DIP(dp, di_gid); inodirty(); dp = ginode(ino); - dp->di_uid = uid; - dp->di_gid = gid; + DIP_SET(dp, di_uid, uid); + DIP_SET(dp, di_gid, gid); inodirty(); return (ino); } @@ -677,11 +679,11 @@ allocdir(ino_t parent, ino_t request, int mode) static void freedir(ino_t ino, ino_t parent) { - struct ufs1_dinode *dp; + union dinode *dp; if (ino != parent) { dp = ginode(parent); - dp->di_nlink--; + DIP_SET(dp, di_nlink, DIP(dp, di_nlink) - 1); inodirty(); } freeino(ino); diff --git a/sbin/fsck_ffs/extern.h b/sbin/fsck_ffs/extern.h index e3752b54a01..090edc73910 100644 --- a/sbin/fsck_ffs/extern.h +++ b/sbin/fsck_ffs/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.8 2003/08/25 23:28:15 tedu Exp $ */ +/* $OpenBSD: extern.h,v 1.9 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: extern.h,v 1.6 1996/09/27 22:45:12 christos Exp $ */ /* @@ -32,12 +32,12 @@ void blkerror(ino_t, char *, daddr_t); int bread(int, char *, daddr_t, long); void bufinit(void); void bwrite(int, char *, daddr_t, long); -void cacheino(struct ufs1_dinode *, ino_t); +void cacheino(union dinode *, ino_t); int changeino(ino_t, char *, ino_t); struct fstab; int chkrange(daddr_t, int); void ckfini(int); -int ckinode(struct ufs1_dinode *, struct inodesc *); +int ckinode(union dinode *, struct inodesc *); void clri(struct inodesc *, char *, int); int dircheck(struct inodesc *, struct direct *); void direrror(ino_t, char *); @@ -50,7 +50,7 @@ void flush(int, struct bufarea *); void freeblk(daddr_t, long); void freeino(ino_t); void freeinodebuf(void); -int ftypeok(struct ufs1_dinode *); +int ftypeok(union dinode *); void getpathname(char *, size_t, ino_t, ino_t); void inocleanup(void); void inodirty(void); @@ -67,9 +67,9 @@ void pass5(void); void pinode(ino_t); void propagate(ino_t); int reply(char *); -void resetinodebuf(void); +void setinodebuf(ino_t); int setup(char *); -struct ufs1_dinode * getnextinode(ino_t); +union dinode * getnextinode(ino_t); void catch(int); void catchquit(int); void voidquit(int); diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 6cbd5d9c50e..a5a1e746ed8 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -1,7 +1,16 @@ -/* $OpenBSD: fsck.h,v 1.17 2007/02/08 19:02:23 otto Exp $ */ +/* $OpenBSD: fsck.h,v 1.18 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: fsck.h,v 1.13 1996/10/11 20:15:46 thorpej Exp $ */ /* + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Marshall + * Kirk McKusick and Network Associates Laboratories, the Security + * Research Division of Network Associates, Inc. under DARPA/SPAWAR + * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS + * research program. + * * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -37,6 +46,22 @@ #define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */ #define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */ +union dinode { + struct ufs1_dinode dp1; + struct ufs2_dinode dp2; +}; + +#define DIP(dp, field) \ + ((sblock.fs_magic == FS_UFS1_MAGIC) ? \ + (dp)->dp1.field : (dp)->dp2.field) + +#define DIP_SET(dp, field, val) do { \ + if (sblock.fs_magic == FS_UFS1_MAGIC) \ + (dp)->dp1.field = (val); \ + else \ + (dp)->dp2.field = (val); \ + } while (0) + #ifndef BUFSIZ #define BUFSIZ 1024 #endif @@ -60,14 +85,27 @@ struct bufarea { int b_flags; union { char *b_buf; /* buffer space */ - daddr_t *b_indir; /* indirect block */ + ufs1_daddr_t *b_indir1; /* FFS1 indirect block */ + ufs2_daddr_t *b_indir2; /* FFS2 indirect block */ struct fs *b_fs; /* super block */ struct cg *b_cg; /* cylinder group */ - struct ufs1_dinode *b_dinode; /* inode block */ + struct ufs1_dinode *b_dinode1; /* FFS1 inode block */ + struct ufs2_dinode *b_dinode2; /* FFS2 inode block */ } b_un; char b_dirty; }; +#define IBLK(bp, i) \ + ((sblock.fs_magic == FS_UFS1_MAGIC) ? \ + (bp)->b_un.b_indir1[i] : (bp)->b_un.b_indir2[i]) + +#define IBLK_SET(bp, i, val) do { \ + if (sblock.fs_magic == FS_UFS1_MAGIC) \ + (bp)->b_un.b_indir1[i] = (val); \ + else \ + (bp)->b_un.b_indir2[i] = (val); \ + } while (0) + #define B_INUSE 1 #define MINBUFS 5 /* minimum number of buffers required */ @@ -198,9 +236,17 @@ int lfmode; /* lost & found directory creation mode */ daddr_t n_blks; /* number of blocks in use */ daddr_t n_files; /* number of files in use */ +long *cginosused; /* # of allocated inodes in each cg */ + +#define clearinode(dp) \ + if (sblock.fs_magic == FS_UFS1_MAGIC) { \ + (dp)->dp1 = ufs1_zino; \ + } else { \ + (dp)->dp2 = ufs2_zino; \ + } -#define clearinode(dp) (*(dp) = zino) -struct ufs1_dinode zino; +struct ufs1_dinode ufs1_zino; +struct ufs2_dinode ufs2_zino; #define setbmap(blkno) setbit(blockmap, blkno) #define testbmap(blkno) isset(blockmap, blkno) @@ -212,7 +258,7 @@ struct ufs1_dinode zino; #define ALTERED 0x08 #define FOUND 0x10 -struct ufs1_dinode *ginode(ino_t); +union dinode *ginode(ino_t); struct inoinfo *getinoinfo(ino_t); void getblk(struct bufarea *, daddr_t, long); ino_t allocino(ino_t, int); diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index 328220966f3..500fe3997b0 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inode.c,v 1.28 2007/02/12 16:41:07 otto Exp $ */ +/* $OpenBSD: inode.c,v 1.29 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: inode.c,v 1.23 1996/10/11 20:15:47 thorpej Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; #else -static const char rcsid[] = "$OpenBSD: inode.c,v 1.28 2007/02/12 16:41:07 otto Exp $"; +static const char rcsid[] = "$OpenBSD: inode.c,v 1.29 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -60,33 +60,37 @@ static ino_t startinum; static int iblock(struct inodesc *, long, off_t); int -ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) +ckinode(union dinode *dp, struct inodesc *idesc) { - ufs_daddr_t *ap; - long ret, n, ndb, offset; - struct ufs1_dinode dino; + long ret, ndb, offset; + union dinode dino; off_t sizepb, remsize; mode_t mode; + int i; char pathbuf[MAXPATHLEN + 1]; if (idesc->id_fix != IGNORE) idesc->id_fix = DONTKNOW; idesc->id_entryno = 0; - idesc->id_filesize = dp->di_size; - mode = dp->di_mode & IFMT; + idesc->id_filesize = DIP(dp, di_size); + mode = DIP(dp, di_mode) & IFMT; if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && - (dp->di_size < sblock.fs_maxsymlinklen || - (sblock.fs_maxsymlinklen == 0 && dp->di_blocks == 0)))) + (DIP(dp, di_size) < sblock.fs_maxsymlinklen || + (sblock.fs_maxsymlinklen == 0 && DIP(dp, di_blocks) == 0)))) return (KEEPON); - dino = *dp; - ndb = howmany(dino.di_size, sblock.fs_bsize); - for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { - if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) + if (sblock.fs_magic == FS_UFS1_MAGIC) + dino.dp1 = dp->dp1; + else + dino.dp2 = dp->dp2; + ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize); + for (i = 0; i < NDADDR; i++) { + if (--ndb == 0 && (offset = blkoff(&sblock, + DIP(&dino, di_size))) != 0) idesc->id_numfrags = numfrags(&sblock, fragroundup(&sblock, offset)); else idesc->id_numfrags = sblock.fs_frag; - if (*ap == 0) { + if (DIP(&dino, di_db[i]) == 0) { if (idesc->id_type == DATA && ndb >= 0) { /* An empty block in a directory XXX */ getpathname(pathbuf, sizeof pathbuf, @@ -95,8 +99,8 @@ ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->di_size = (ap - &dino.di_db[0]) * - sblock.fs_bsize; + DIP_SET(dp, di_size, + i * sblock.fs_bsize); printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); rerun = 1; @@ -105,7 +109,7 @@ ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) } continue; } - idesc->id_blkno = *ap; + idesc->id_blkno = DIP(&dino, di_db[i]); if (idesc->id_type == ADDR) ret = (*idesc->id_func)(idesc); else @@ -114,12 +118,12 @@ ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) return (ret); } idesc->id_numfrags = sblock.fs_frag; - remsize = dino.di_size - sblock.fs_bsize * NDADDR; + remsize = DIP(&dino, di_size) - sblock.fs_bsize * NDADDR; sizepb = sblock.fs_bsize; - for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { - if (*ap) { - idesc->id_blkno = *ap; - ret = iblock(idesc, n, remsize); + for (i = 0; i < NIADDR; i++) { + if (DIP(&dino, di_ib[i])) { + idesc->id_blkno = DIP(&dino, di_ib[i]); + ret = iblock(idesc, i + 1, remsize); if (ret & STOP) return (ret); } else { @@ -131,7 +135,8 @@ ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->di_size -= remsize; + DIP_SET(dp, di_size, + DIP(dp, di_size) - remsize); remsize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); @@ -150,14 +155,12 @@ ckinode(struct ufs1_dinode *dp, struct inodesc *idesc) static int iblock(struct inodesc *idesc, long ilevel, off_t isize) { - daddr_t *ap; - daddr_t *aplim; struct bufarea *bp; int i, n, (*func)(struct inodesc *), nif; off_t sizepb; char buf[BUFSIZ]; char pathbuf[MAXPATHLEN + 1]; - struct ufs1_dinode *dp; + union dinode *dp; if (idesc->id_type == ADDR) { func = idesc->id_func; @@ -176,9 +179,8 @@ iblock(struct inodesc *idesc, long ilevel, off_t isize) else nif = howmany(isize, sizepb); if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) { - aplim = &bp->b_un.b_indir[NINDIR(&sblock)]; - for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) { - if (*ap == 0) + for (i = nif; i < NINDIR(&sblock); i++) { + if (IBLK(bp, i) == 0) continue; (void)snprintf(buf, sizeof buf, "PARTIALLY TRUNCATED INODE I=%u", @@ -186,16 +188,15 @@ iblock(struct inodesc *idesc, long ilevel, off_t isize) if (preen) pfatal("%s", buf); else if (dofix(idesc, buf)) { - *ap = 0; + IBLK_SET(bp, i, 0); dirty(bp); } } flush(fswritefd, bp); } - aplim = &bp->b_un.b_indir[nif]; - for (ap = bp->b_un.b_indir; ap < aplim; ap++) { - if (*ap) { - idesc->id_blkno = *ap; + for (i = 0; i < nif; i++) { + if (IBLK(bp, i)) { + idesc->id_blkno = IBLK(bp, i); if (ilevel == 0) n = (*func)(idesc); else @@ -213,7 +214,8 @@ iblock(struct inodesc *idesc, long ilevel, off_t isize) pathbuf); if (reply("ADJUST LENGTH") == 1) { dp = ginode(idesc->id_number); - dp->di_size -= isize; + DIP_SET(dp, di_size, + DIP(dp, di_size) - isize); isize = 0; printf( "YOU MUST RERUN FSCK AFTERWARDS\n"); @@ -277,7 +279,7 @@ chkrange(daddr_t blk, int cnt) /* * General purpose interface for reading inodes. */ -struct ufs1_dinode * +union dinode * ginode(ino_t inumber) { daddr_t iblk; @@ -292,7 +294,10 @@ ginode(ino_t inumber) pbp = getdatablk(iblk, sblock.fs_bsize); startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); } - return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]); + if (sblock.fs_magic == FS_UFS1_MAGIC) + return ((union dinode *) + &pbp->b_un.b_dinode1[inumber % INOPB(&sblock)]); + return ((union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)]); } /* @@ -301,14 +306,15 @@ ginode(ino_t inumber) */ ino_t nextino, lastinum; long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; -struct ufs1_dinode *inodebuf; +static caddr_t inodebuf; -struct ufs1_dinode * +union dinode * getnextinode(ino_t inumber) { long size; daddr_t dblk; - static struct ufs1_dinode *dp; + union dinode *dp; + static caddr_t nextinop; if (inumber != nextino++ || inumber > maxino) errexit("bad inode number %d to nextinode\n", inumber); @@ -322,25 +328,38 @@ getnextinode(ino_t inumber) size = inobufsize; lastinum += fullcnt; } - (void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */ - dp = inodebuf; + (void)bread(fsreadfd, inodebuf, dblk, size); + nextinop = inodebuf; } - return (dp++); + dp = (union dinode *)nextinop; + if (sblock.fs_magic == FS_UFS1_MAGIC) + nextinop += sizeof(struct ufs1_dinode); + else + nextinop += sizeof(struct ufs2_dinode); + return (dp); } void -resetinodebuf(void) +setinodebuf(ino_t inum) { startinum = 0; - nextino = 0; - lastinum = 0; + nextino = inum; + lastinum = inum; readcnt = 0; + if (inodebuf != NULL) + return; inobufsize = blkroundup(&sblock, INOBUFSIZE); - fullcnt = inobufsize / sizeof(struct ufs1_dinode); + if (sblock.fs_magic == FS_UFS1_MAGIC) + fullcnt = inobufsize / sizeof(struct ufs1_dinode); + else + fullcnt = inobufsize / sizeof(struct ufs2_dinode); readpercg = sblock.fs_ipg / fullcnt; partialcnt = sblock.fs_ipg % fullcnt; - partialsize = partialcnt * sizeof(struct ufs1_dinode); + if (sblock.fs_magic == FS_UFS1_MAGIC) + partialsize = partialcnt * sizeof(struct ufs1_dinode); + else + partialsize = partialcnt * sizeof(struct ufs2_dinode); if (partialcnt != 0) { readpercg++; } else { @@ -371,14 +390,15 @@ freeinodebuf(void) * Enter inodes into the cache. */ void -cacheino(struct ufs1_dinode *dp, ino_t inumber) +cacheino(union dinode *dp, ino_t inumber) { struct inoinfo *inp; struct inoinfo **inpp, **newinpsort; unsigned int blks; long newlistmax; + int i; - blks = howmany(dp->di_size, sblock.fs_bsize); + blks = howmany(DIP(dp, di_size), sblock.fs_bsize); if (blks > NDADDR) blks = NDADDR + NIADDR; inp = malloc(sizeof(*inp) + (blks ? blks - 1 : 0) * sizeof(daddr_t)); @@ -394,9 +414,13 @@ cacheino(struct ufs1_dinode *dp, ino_t inumber) inp->i_parent = 0; inp->i_dotdot = 0; inp->i_number = inumber; - inp->i_isize = dp->di_size; - inp->i_numblks = blks * sizeof(daddr_t); - memcpy(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks); + inp->i_isize = DIP(dp, di_size); + inp->i_numblks = blks; + for (i = 0; i < (blks < NDADDR ? blks : NDADDR); i++) + inp->i_blks[i] = DIP(dp, di_db[i]); + if (blks > NDADDR) + for (i = 0; i < NIADDR; i++) + inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); if (inplast == listmax) { newlistmax = listmax + 100; newinpsort = realloc(inpsort, @@ -452,12 +476,12 @@ inodirty(void) void clri(struct inodesc *idesc, char *type, int flag) { - struct ufs1_dinode *dp; + union dinode *dp; dp = ginode(idesc->id_number); if (flag == 1) { pwarn("%s %s", type, - (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"); + (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"); pinode(idesc->id_number); } if (preen || reply("CLEAR") == 1) { @@ -500,7 +524,7 @@ findino(struct inodesc *idesc) void pinode(ino_t ino) { - struct ufs1_dinode *dp; + union dinode *dp; char *p; struct passwd *pw; time_t t; @@ -511,16 +535,16 @@ pinode(ino_t ino) dp = ginode(ino); printf(" OWNER="); #ifndef SMALL - if ((pw = getpwuid(dp->di_uid)) != 0) + if ((pw = getpwuid(DIP(dp, di_uid))) != 0) printf("%s ", pw->pw_name); else #endif - printf("%u ", (unsigned)dp->di_uid); - printf("MODE=%o\n", dp->di_mode); + printf("%u ", (unsigned)DIP(dp, di_uid)); + printf("MODE=%o\n", DIP(dp, di_mode)); if (preen) printf("%s: ", cdevname()); - printf("SIZE=%llu ", (unsigned long long)dp->di_size); - t = dp->di_mtime; + printf("SIZE=%llu ", (unsigned long long)DIP(dp, di_size)); + t = DIP(dp, di_mtime); p = ctime(&t); printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); } @@ -558,7 +582,7 @@ ino_t allocino(ino_t request, int type) { ino_t ino; - struct ufs1_dinode *dp; + union dinode *dp; struct cg *cgp = &cgrp; int cg; time_t t; @@ -593,20 +617,24 @@ allocino(ino_t request, int type) } cgdirty(); dp = ginode(ino); - dp->di_db[0] = allocblk(1); - if (dp->di_db[0] == 0) { + DIP_SET(dp, di_db[0], allocblk(1)); + if (DIP(dp, di_db[0]) == 0) { statemap[ino] = USTATE; return (0); } - dp->di_mode = type; - dp->di_uid = geteuid(); - dp->di_gid = getegid(); - dp->di_flags = 0; + DIP_SET(dp, di_mode, type); + DIP_SET(dp, di_uid, geteuid()); + DIP_SET(dp, di_gid, getegid()); + DIP_SET(dp, di_flags, 0); (void)time(&t); - dp->di_atime = t; - dp->di_mtime = dp->di_ctime = dp->di_atime; - dp->di_size = sblock.fs_fsize; - dp->di_blocks = btodb(sblock.fs_fsize); + DIP_SET(dp, di_atime, t); + DIP_SET(dp, di_atimensec, 0); + DIP_SET(dp, di_mtime, t); + DIP_SET(dp, di_mtimensec, 0); + DIP_SET(dp, di_ctime, t); + DIP_SET(dp, di_ctimensec, 0); + DIP_SET(dp, di_size, sblock.fs_fsize); + DIP_SET(dp, di_blocks, btodb(sblock.fs_fsize)); n_files++; inodirty(); if (newinofmt) @@ -621,7 +649,7 @@ void freeino(ino_t ino) { struct inodesc idesc; - struct ufs1_dinode *dp; + union dinode *dp; memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index e6e1ae8a2af..fe8c02dc678 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.30 2007/03/19 13:27:47 pedro Exp $ */ +/* $OpenBSD: main.c,v 1.31 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: main.c,v 1.22 1996/10/11 20:15:48 thorpej Exp $ */ /* @@ -40,7 +40,7 @@ static const char copyright[] = #if 0 static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; #else -static const char rcsid[] = "$OpenBSD: main.c,v 1.30 2007/03/19 13:27:47 pedro Exp $"; +static const char rcsid[] = "$OpenBSD: main.c,v 1.31 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -265,15 +265,15 @@ checkfilesys(char *filesys, char *mntpt, long auxdata, int child) /* * print out summary statistics */ - n_ffree = sblock.fs_ffs1_cstotal.cs_nffree; - n_bfree = sblock.fs_ffs1_cstotal.cs_nbfree; + n_ffree = sblock.fs_cstotal.cs_nffree; + n_bfree = sblock.fs_cstotal.cs_nbfree; pwarn("%d files, %d used, %d free ", n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree); - printf("(%d frags, %d blocks, %d.%d%% fragmentation)\n", - n_ffree, n_bfree, (n_ffree * 100) / sblock.fs_ffs1_dsize, - ((n_ffree * 1000 + sblock.fs_ffs1_dsize / 2) / sblock.fs_ffs1_dsize) % 10); + printf("(%d frags, %d blocks, %lld.%lld%% fragmentation)\n", + n_ffree, n_bfree, (n_ffree * 100) / sblock.fs_dsize, + ((n_ffree * 1000 + sblock.fs_dsize / 2) / sblock.fs_dsize) % 10); if (debug && - (n_files -= maxino - ROOTINO - sblock.fs_ffs1_cstotal.cs_nifree)) + (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree)) printf("%d files missing\n", n_files); if (debug) { n_blks += sblock.fs_ncg * @@ -300,7 +300,7 @@ checkfilesys(char *filesys, char *mntpt, long auxdata, int child) muldup = NULL; inocleanup(); if (fsmodified) { - (void)time(&sblock.fs_ffs1_time); + sblock.fs_time = (time_t)time(NULL); sbdirty(); } if (cvtlevel && sblk.b_dirty) { diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c index ef4ad926cf5..da281ec08fb 100644 --- a/sbin/fsck_ffs/pass1.c +++ b/sbin/fsck_ffs/pass1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.c,v 1.22 2007/03/19 13:27:47 pedro Exp $ */ +/* $OpenBSD: pass1.c,v 1.23 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: pass1.c,v 1.16 1996/09/27 22:45:15 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; #else -static const char rcsid[] = "$OpenBSD: pass1.c,v 1.22 2007/03/19 13:27:47 pedro Exp $"; +static const char rcsid[] = "$OpenBSD: pass1.c,v 1.23 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -69,7 +69,7 @@ void pass1(void) { struct inodesc idesc; - ino_t inumber; + ino_t inumber, inosused; int c, i, cgd; /* @@ -84,7 +84,7 @@ pass1(void) for (; i < cgd; i++) setbmap(i); } - i = sblock.fs_ffs1_csaddr; + i = sblock.fs_csaddr; cgd = i + howmany(sblock.fs_cssize, sblock.fs_fsize); for (; i < cgd; i++) setbmap(i); @@ -94,13 +94,19 @@ pass1(void) memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass1check; - inumber = 0; n_files = n_blks = 0; - resetinodebuf(); info_inumber = 0; info_fn = pass1_info; for (c = 0; c < sblock.fs_ncg; c++) { - for (i = 0; i < sblock.fs_ipg; i++, inumber++) { + inumber = c * sblock.fs_ipg; + setinodebuf(inumber); + getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); + if (sblock.fs_magic == FS_UFS2_MAGIC) + inosused = cgrp.cg_initediblk; + else + inosused = sblock.fs_ipg; + cginosused[c] = inosused; + for (i = 0; i < inosused; i++, inumber++) { info_inumber = inumber; if (inumber < ROOTINO) continue; @@ -114,7 +120,7 @@ pass1(void) static void checkinode(ino_t inumber, struct inodesc *idesc) { - struct ufs1_dinode *dp; + union dinode *dp; struct zlncnt *zlnp; int ndb, j; mode_t mode; @@ -122,11 +128,20 @@ checkinode(ino_t inumber, struct inodesc *idesc) u_int64_t lndb; dp = getnextinode(inumber); - mode = dp->di_mode & IFMT; + mode = DIP(dp, di_mode) & IFMT; if (mode == 0) { - if (memcmp(dp->di_db, zino.di_db, NDADDR * sizeof(daddr_t)) || - memcmp(dp->di_ib, zino.di_ib, NIADDR * sizeof(daddr_t)) || - dp->di_mode || dp->di_size) { + if ((sblock.fs_magic == FS_UFS1_MAGIC && + (memcmp(dp->dp1.di_db, ufs1_zino.di_db, + NDADDR * sizeof(ufs1_daddr_t)) || + memcmp(dp->dp1.di_ib, ufs1_zino.di_ib, + NIADDR * sizeof(ufs1_daddr_t)) || + dp->dp1.di_mode || dp->dp1.di_size)) || + (sblock.fs_magic == FS_UFS2_MAGIC && + (memcmp(dp->dp2.di_db, ufs2_zino.di_db, + NDADDR * sizeof(ufs2_daddr_t)) || + memcmp(dp->dp2.di_ib, ufs2_zino.di_ib, + NIADDR * sizeof(ufs2_daddr_t)) || + dp->dp2.di_mode || dp->dp2.di_size))) { pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber); if (reply("CLEAR") == 1) { dp = ginode(inumber); @@ -138,24 +153,25 @@ checkinode(ino_t inumber, struct inodesc *idesc) return; } lastino = inumber; - if (/* dp->di_size < 0 || */ - dp->di_size + sblock.fs_bsize - 1 < dp->di_size) { + if (/* DIP(dp, di_size) < 0 || */ + DIP(dp, di_size) + sblock.fs_bsize - 1 < DIP(dp, di_size)) { if (debug) - printf("bad size %llu:", (unsigned long long)dp->di_size); + printf("bad size %llu:", + (unsigned long long)DIP(dp, di_size)); goto unknown; } if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { dp = ginode(inumber); - dp->di_size = sblock.fs_fsize; - dp->di_mode = IFREG|0600; + DIP_SET(dp, di_size, sblock.fs_fsize); + DIP_SET(dp, di_mode, IFREG|0600); inodirty(); } - lndb = howmany(dp->di_size, sblock.fs_bsize); + lndb = howmany(DIP(dp, di_size), sblock.fs_bsize); ndb = lndb > (u_int64_t)INT_MAX ? -1 : (int)lndb; if (ndb < 0) { if (debug) printf("bad size %llu ndb %d:", - (unsigned long long)dp->di_size, ndb); + (unsigned long long)DIP(dp, di_size), ndb); goto unknown; } if (mode == IFBLK || mode == IFCHR) @@ -168,32 +184,39 @@ checkinode(ino_t inumber, struct inodesc *idesc) * new format is the same as the old. We simply ignore the * conversion altogether. - mycroft, 19MAY1994 */ - if (doinglevel2 && - dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN_UFS1 && - dp->di_blocks != 0) { + if (sblock.fs_magic == FS_UFS1_MAGIC && doinglevel2 && + DIP(dp, di_size) > 0 && + DIP(dp, di_size) < MAXSYMLINKLEN_UFS1 && + DIP(dp, di_blocks) != 0) { symbuf = alloca(secsize); if (bread(fsreadfd, symbuf, - fsbtodb(&sblock, dp->di_db[0]), + fsbtodb(&sblock, DIP(dp, di_db[0])), (long)secsize) != 0) errexit("cannot read symlink\n"); if (debug) { - symbuf[dp->di_size] = 0; + symbuf[DIP(dp, di_size)] = 0; printf("convert symlink %d(%s) of size %llu\n", inumber, symbuf, - (unsigned long long)dp->di_size); + (unsigned long long)DIP(dp, di_size)); } dp = ginode(inumber); - memcpy(dp->di_shortlink, symbuf, (long)dp->di_size); - dp->di_blocks = 0; + memcpy(dp->dp1.di_shortlink, symbuf, + (long)DIP(dp, di_size)); + DIP_SET(dp, di_blocks, 0); inodirty(); } /* * Fake ndb value so direct/indirect block checks below * will detect any garbage after symlink string. */ - if (dp->di_size < sblock.fs_maxsymlinklen || - (sblock.fs_maxsymlinklen == 0 && dp->di_blocks == 0)) { - ndb = howmany(dp->di_size, sizeof(daddr_t)); + if (DIP(dp, di_size) < sblock.fs_maxsymlinklen || + (sblock.fs_maxsymlinklen == 0 && DIP(dp, di_blocks) == 0)) { + if (sblock.fs_magic == FS_UFS1_MAGIC) + ndb = howmany(DIP(dp, di_size), + sizeof(ufs1_daddr_t)); + else + ndb = howmany(DIP(dp, di_size), + sizeof(ufs2_daddr_t)); if (ndb > NDADDR) { j = ndb - NDADDR; for (ndb = 1; j > 1; j--) @@ -203,25 +226,26 @@ checkinode(ino_t inumber, struct inodesc *idesc) } } for (j = ndb; j < NDADDR; j++) - if (dp->di_db[j] != 0) { + if (DIP(dp, di_db[j]) != 0) { if (debug) - printf("bad direct addr: %d\n", dp->di_db[j]); + printf("bad direct addr: %ld\n", + (long)DIP(dp, di_db[j])); goto unknown; } for (j = 0, ndb -= NDADDR; ndb > 0; j++) ndb /= NINDIR(&sblock); for (; j < NIADDR; j++) - if (dp->di_ib[j] != 0) { + if (DIP(dp, di_ib[j]) != 0) { if (debug) - printf("bad indirect addr: %d\n", - dp->di_ib[j]); + printf("bad indirect addr: %ld\n", + (long)DIP(dp, di_ib[j])); goto unknown; } if (ftypeok(dp) == 0) goto unknown; n_files++; - lncntp[inumber] = dp->di_nlink; - if (dp->di_nlink <= 0) { + lncntp[inumber] = DIP(dp, di_nlink); + if (DIP(dp, di_nlink) <= 0) { zlnp = malloc(sizeof *zlnp); if (zlnp == NULL) { pfatal("LINK COUNT TABLE OVERFLOW"); @@ -236,7 +260,7 @@ checkinode(ino_t inumber, struct inodesc *idesc) } } if (mode == IFDIR) { - if (dp->di_size == 0) + if (DIP(dp, di_size) == 0) statemap[inumber] = DCLEAR; else statemap[inumber] = DSTATE; @@ -244,27 +268,29 @@ checkinode(ino_t inumber, struct inodesc *idesc) } else statemap[inumber] = FSTATE; typemap[inumber] = IFTODT(mode); - if (doinglevel2 && (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) { + if (sblock.fs_magic == FS_UFS1_MAGIC && doinglevel2 && + (dp->dp1.di_ouid != (u_short)-1 || + dp->dp1.di_ogid != (u_short)-1)) { dp = ginode(inumber); - dp->di_uid = dp->di_ouid; - dp->di_ouid = -1; - dp->di_gid = dp->di_ogid; - dp->di_ogid = -1; + DIP_SET(dp, di_uid, dp->dp1.di_ouid); + dp->dp1.di_ouid = -1; + DIP_SET(dp, di_gid, dp->dp1.di_ogid); + dp->dp1.di_ogid = -1; inodirty(); } badblk = dupblk = 0; idesc->id_number = inumber; (void)ckinode(dp, idesc); idesc->id_entryno *= btodb(sblock.fs_fsize); - if (dp->di_blocks != idesc->id_entryno) { - pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)", - inumber, dp->di_blocks, idesc->id_entryno); + if (DIP(dp, di_blocks) != idesc->id_entryno) { + pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %d)", + inumber, (long)DIP(dp, di_blocks), idesc->id_entryno); if (preen) printf(" (CORRECTED)\n"); else if (reply("CORRECT") == 0) return; dp = ginode(inumber); - dp->di_blocks = idesc->id_entryno; + DIP_SET(dp, di_blocks, idesc->id_entryno); inodirty(); } return; diff --git a/sbin/fsck_ffs/pass1b.c b/sbin/fsck_ffs/pass1b.c index 4224ae2fa2e..fce77a44561 100644 --- a/sbin/fsck_ffs/pass1b.c +++ b/sbin/fsck_ffs/pass1b.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1b.c,v 1.13 2006/03/22 20:24:32 deraadt Exp $ */ +/* $OpenBSD: pass1b.c,v 1.14 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: pass1b.c,v 1.10 1996/09/23 16:18:37 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pass1b.c 8.1 (Berkeley) 6/5/93"; #else -static const char rcsid[] = "$OpenBSD: pass1b.c,v 1.13 2006/03/22 20:24:32 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: pass1b.c,v 1.14 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -64,7 +64,7 @@ void pass1b(void) { int c, i; - struct ufs1_dinode *dp; + union dinode *dp; struct inodesc idesc; ino_t inumber; diff --git a/sbin/fsck_ffs/pass2.c b/sbin/fsck_ffs/pass2.c index 4a235958288..eee093c6e44 100644 --- a/sbin/fsck_ffs/pass2.c +++ b/sbin/fsck_ffs/pass2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass2.c,v 1.25 2006/03/22 20:24:32 deraadt Exp $ */ +/* $OpenBSD: pass2.c,v 1.26 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: pass2.c,v 1.17 1996/09/27 22:45:15 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; #else -static const char rcsid[] = "$OpenBSD: pass2.c,v 1.25 2006/03/22 20:24:32 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: pass2.c,v 1.26 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -79,12 +79,13 @@ pass2_info2(char *buf, size_t buflen) void pass2(void) { - struct ufs1_dinode *dp; + union dinode *dp; struct inoinfo **inpp, *inp, *pinp; struct inoinfo **inpend; struct inodesc curino; - struct ufs1_dinode dino; + union dinode dino; char pathbuf[MAXPATHLEN + 1]; + int i; switch (statemap[ROOTINO]) { @@ -126,8 +127,8 @@ pass2(void) errexit("%s", ""); } dp = ginode(ROOTINO); - dp->di_mode &= ~IFMT; - dp->di_mode |= IFDIR; + DIP_SET(dp, di_mode, DIP(dp, di_mode) & ~IFMT); + DIP_SET(dp, di_mode, DIP(dp, di_mode) | IFDIR); inodirty(); break; @@ -162,7 +163,7 @@ pass2(void) inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ); if (reply("FIX") == 1) { dp = ginode(inp->i_number); - dp->di_size = inp->i_isize; + DIP_SET(dp, di_size, inp->i_isize); inodirty(); } } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) { @@ -181,17 +182,24 @@ pass2(void) inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ); if (preen || reply("ADJUST") == 1) { dp = ginode(inp->i_number); - dp->di_size = inp->i_isize; + DIP_SET(dp, di_size, inp->i_isize); inodirty(); } } - memset(&dino, 0, sizeof(struct ufs1_dinode)); - dino.di_mode = IFDIR; - dino.di_size = inp->i_isize; - memcpy(&dino.di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks); + memset(&dino, 0, sizeof(union dinode)); + dp = &dino; + DIP_SET(dp, di_mode, IFDIR); + DIP_SET(dp, di_size, inp->i_isize); + for (i = 0; + i < (inp->i_numblks<NDADDR ? inp->i_numblks : NDADDR); + i++) + DIP_SET(dp, di_db[i], inp->i_blks[i]); + if (inp->i_numblks > NDADDR) + for (i = 0; i < NIADDR; i++) + DIP_SET(dp, di_ib[i], inp->i_blks[NDADDR + i]); curino.id_number = inp->i_number; curino.id_parent = inp->i_parent; - (void)ckinode(&dino, &curino); + (void)ckinode(dp, &curino); } /* * Now that the parents of all directories have been found, @@ -252,7 +260,7 @@ pass2check(struct inodesc *idesc) struct direct *dirp = idesc->id_dirp; struct inoinfo *inp; int n, entrysize, ret = 0; - struct ufs1_dinode *dp; + union dinode *dp; char *errmsg; struct direct proto; char namebuf[MAXPATHLEN + 1]; @@ -445,8 +453,8 @@ again: break; dp = ginode(dirp->d_ino); statemap[dirp->d_ino] = - (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE; - lncntp[dirp->d_ino] = dp->di_nlink; + (DIP(dp, di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE; + lncntp[dirp->d_ino] = DIP(dp, di_nlink); goto again; case DSTATE: diff --git a/sbin/fsck_ffs/pass4.c b/sbin/fsck_ffs/pass4.c index cadcf9847d0..2092a3da564 100644 --- a/sbin/fsck_ffs/pass4.c +++ b/sbin/fsck_ffs/pass4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass4.c,v 1.15 2006/03/22 20:24:32 deraadt Exp $ */ +/* $OpenBSD: pass4.c,v 1.16 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: pass4.c,v 1.11 1996/09/27 22:45:17 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pass4.c 8.1 (Berkeley) 6/5/93"; #else -static const char rcsid[] = "$OpenBSD: pass4.c,v 1.15 2006/03/22 20:24:32 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: pass4.c,v 1.16 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -64,25 +64,29 @@ pass4(void) { ino_t inumber; struct zlncnt *zlnp; - struct ufs1_dinode *dp; + union dinode *dp; struct inodesc idesc; - int n; + int n, c, i; memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass4check; info_fn = pass4_info; - for (inumber = ROOTINO; inumber <= lastino; inumber++) { - info_inumber = inumber; - idesc.id_number = inumber; - switch (statemap[inumber]) { + for (c = 0; c < sblock.fs_ncg; c++) { + inumber = c * sblock.fs_ipg; + for (i = 0; i < cginosused[c]; i++, inumber++) { + if (inumber < ROOTINO) + continue; + idesc.id_number = inumber; + switch (statemap[inumber]) { - case FSTATE: - case DFOUND: - n = lncntp[inumber]; - if (n) - adjust(&idesc, (short)n); - else { + case FSTATE: + case DFOUND: + n = lncntp[inumber]; + if (n) { + adjust(&idesc, (short)n); + break; + } for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) if (zlnp->zlncnt == inumber) { zlnp->zlncnt = zlnhead->zlncnt; @@ -92,30 +96,30 @@ pass4(void) clri(&idesc, "UNREF", 1); break; } - } - break; + break; - case DSTATE: - clri(&idesc, "UNREF", 1); - break; + case DSTATE: + clri(&idesc, "UNREF", 1); + break; - case DCLEAR: - dp = ginode(inumber); - if (dp->di_size == 0) { - clri(&idesc, "ZERO LENGTH", 1); + case DCLEAR: + dp = ginode(inumber); + if (DIP(dp, di_size) == 0) { + clri(&idesc, "ZERO LENGTH", 1); + break; + } + /* FALLTHROUGH */ + case FCLEAR: + clri(&idesc, "BAD/DUP", 1); break; - } - /* FALLTHROUGH */ - case FCLEAR: - clri(&idesc, "BAD/DUP", 1); - break; - case USTATE: - break; + case USTATE: + break; - default: - errexit("BAD STATE %d FOR INODE I=%d\n", - statemap[inumber], inumber); + default: + errexit("BAD STATE %d FOR INODE I=%d\n", + statemap[inumber], inumber); + } } } info_fn = NULL; diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 21a0c3f90e5..5b8a749c03d 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass5.c,v 1.26 2007/03/19 13:27:47 pedro Exp $ */ +/* $OpenBSD: pass5.c,v 1.27 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: pass5.c,v 1.16 1996/09/27 22:45:18 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94"; #else -static const char rcsid[] = "$OpenBSD: pass5.c,v 1.26 2007/03/19 13:27:47 pedro Exp $"; +static const char rcsid[] = "$OpenBSD: pass5.c,v 1.27 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -75,14 +75,13 @@ pass5(void) daddr_t d; long i, j, k; struct csum *cs; - struct csum cstotal; + struct csum_total cstotal; struct inodesc idesc[3]; char buf[MAXBSIZE]; struct cg *newcg = (struct cg *)buf; struct ocg *ocg = (struct ocg *)buf; memset(newcg, 0, (size_t)fs->fs_cgsize); - newcg->cg_niblk = fs->fs_ipg; if (cvtlevel >= 3) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (preen) @@ -138,14 +137,19 @@ pass5(void) break; case FS_DYNAMICPOSTBLFMT: - newcg->cg_btotoff = - &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); - newcg->cg_boff = - newcg->cg_btotoff + fs->fs_cpg * sizeof(int32_t); - newcg->cg_iusedoff = newcg->cg_boff + - fs->fs_cpg * fs->fs_nrpos * sizeof(int16_t); - newcg->cg_freeoff = - newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); + if (sblock.fs_magic == FS_UFS2_MAGIC) { + newcg->cg_iusedoff = &newcg->cg_space[0] - + (u_char *)(&newcg->cg_firstfield); + } else { + newcg->cg_btotoff = &newcg->cg_space[0] - + (u_char *)(&newcg->cg_firstfield); + newcg->cg_boff = newcg->cg_btotoff + + fs->fs_cpg * sizeof(int32_t); + newcg->cg_iusedoff = newcg->cg_boff + fs->fs_cpg * + fs->fs_nrpos * sizeof(int16_t); + } + newcg->cg_freeoff = newcg->cg_iusedoff + + howmany(fs->fs_ipg, NBBY); inomapsize = newcg->cg_freeoff - newcg->cg_iusedoff; newcg->cg_nextfreeoff = newcg->cg_freeoff + howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); @@ -179,8 +183,8 @@ pass5(void) idesc[i].id_fix = FIX; } memset(&cstotal, 0, sizeof(struct csum)); - j = blknum(fs, fs->fs_ffs1_size + fs->fs_frag - 1); - for (i = fs->fs_ffs1_size; i < j; i++) + j = blknum(fs, fs->fs_size + fs->fs_frag - 1); + for (i = fs->fs_size; i < j; i++) setbmap(i); info_cg = 0; info_maxcg = fs->fs_ncg; @@ -192,8 +196,8 @@ pass5(void) pfatal("CG %d: BAD MAGIC NUMBER\n", c); dbase = cgbase(fs, c); dmax = dbase + fs->fs_fpg; - if (dmax > fs->fs_ffs1_size) - dmax = fs->fs_ffs1_size; + if (dmax > fs->fs_size) + dmax = fs->fs_size; newcg->cg_time = cg->cg_time; newcg->cg_ffs2_time = cg->cg_ffs2_time; newcg->cg_cgx = c; @@ -216,17 +220,30 @@ pass5(void) newcg->cg_frotor = cg->cg_frotor; else newcg->cg_frotor = 0; - if (cg->cg_irotor >= 0 && cg->cg_irotor < newcg->cg_niblk) - newcg->cg_irotor = cg->cg_irotor; - else - newcg->cg_irotor = 0; + newcg->cg_irotor = 0; + if (fs->fs_magic == FS_UFS1_MAGIC) { + newcg->cg_initediblk = 0; + newcg->cg_niblk = cg->cg_niblk; + if (cg->cg_irotor >= 0 && + cg->cg_irotor < newcg->cg_niblk) + newcg->cg_irotor = cg->cg_irotor; + } else { + newcg->cg_ncyl = 0; + if ((unsigned)cg->cg_initediblk > fs->fs_ipg) + newcg->cg_initediblk = fs->fs_ipg; + else + newcg->cg_initediblk = cg->cg_initediblk; + newcg->cg_ffs2_niblk = fs->fs_ipg; + if (cg->cg_irotor >= 0 && + cg->cg_irotor < newcg->cg_ffs2_niblk) + newcg->cg_irotor = cg->cg_irotor; + } memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum); - memset(&cg_blktot(newcg)[0], 0, - (size_t)(sumsize + mapsize)); + memset(cg_inosused(newcg), 0, (size_t)(mapsize)); if (fs->fs_postblformat == FS_42POSTBLFMT) ocg->cg_magic = CG_MAGIC; j = fs->fs_ipg * c; - for (i = 0; i < fs->fs_ipg; j++, i++) { + for (i = 0; i < cginosused[c]; j++, i++) { switch (statemap[j]) { case USTATE: @@ -269,8 +286,6 @@ pass5(void) if (frags == fs->fs_frag) { newcg->cg_cs.cs_nbfree++; j = cbtocylno(fs, i); - cg_blktot(newcg)[j]++; - cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; if (fs->fs_contigsumsize > 0) setbit(cg_clustersfree(newcg), i / fs->fs_frag); @@ -324,13 +339,9 @@ pass5(void) cgdirty(); continue; } - if ((memcmp(newcg, cg, basesize) != 0 || - memcmp(&cg_blktot(newcg)[0], - &cg_blktot(cg)[0], sumsize) != 0) && + if (memcmp(newcg, cg, basesize) && dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { memcpy(cg, newcg, (size_t)basesize); - memcpy(&cg_blktot(cg)[0], - &cg_blktot(newcg)[0], (size_t)sumsize); cgdirty(); } if (usedsoftdep) { @@ -372,9 +383,9 @@ pass5(void) info_fn = NULL; if (fs->fs_postblformat == FS_42POSTBLFMT) fs->fs_nrpos = savednrpos; - if (memcmp(&cstotal, &fs->fs_ffs1_cstotal, sizeof *cs) != 0 + if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { - memcpy(&fs->fs_ffs1_cstotal, &cstotal, sizeof *cs); + memcpy(&fs->fs_cstotal, &cstotal, sizeof *cs); fs->fs_ronly = 0; fs->fs_fmod = 0; sbdirty(); diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 2b17bb7d4ad..9c0b520ef5b 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setup.c,v 1.32 2007/03/19 22:13:36 otto Exp $ */ +/* $OpenBSD: setup.c,v 1.33 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: setup.c,v 1.27 1996/09/27 22:45:19 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; #else -static const char rcsid[] = "$OpenBSD: setup.c,v 1.32 2007/03/19 22:13:36 otto Exp $"; +static const char rcsid[] = "$OpenBSD: setup.c,v 1.33 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -69,6 +69,11 @@ static int cmpsb(struct fs *, struct fs *); long numdirs, listmax, inplast; +/* + * Possible locations for the superblock. + */ +static const int sbtry[] = SBLOCKSEARCH; + int setup(char *dev) { @@ -78,6 +83,7 @@ setup(char *dev) struct stat statb; struct fs proto; int doskipclean; + int32_t maxsymlinklen, nindir, inopb; u_int64_t maxfilesize; havesb = 0; @@ -155,7 +161,7 @@ setup(char *dev) if (!preen) pwarn("** File system is already clean\n"); } - maxfsblock = sblock.fs_ffs1_size; + maxfsblock = sblock.fs_size; maxino = sblock.fs_ncg * sblock.fs_ipg; sizepb = sblock.fs_bsize; maxfilesize = sblock.fs_bsize * NDADDR - 1; @@ -181,18 +187,6 @@ setup(char *dev) sbdirty(); } } - if (sblock.fs_interleave < 1 || - sblock.fs_interleave > sblock.fs_nsect) { - pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK", - sblock.fs_interleave); - sblock.fs_interleave = 1; - if (preen) - printf(" (FIXED)\n"); - if (preen || reply("SET TO DEFAULT") == 1) { - sbdirty(); - dirty(&asblk); - } - } if (sblock.fs_npsect < sblock.fs_nsect || sblock.fs_npsect > sblock.fs_nsect*2) { pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK", @@ -259,10 +253,12 @@ setup(char *dev) dirty(&asblk); } } - if (sblock.fs_maxsymlinklen != MAXSYMLINKLEN_UFS1) { + maxsymlinklen = sblock.fs_magic == FS_UFS1_MAGIC ? + MAXSYMLINKLEN_UFS1 : MAXSYMLINKLEN_UFS2; + if (sblock.fs_maxsymlinklen != maxsymlinklen) { pwarn("INCORRECT MAXSYMLINKLEN=%d IN SUPERBLOCK", sblock.fs_maxsymlinklen); - sblock.fs_maxsymlinklen = MAXSYMLINKLEN_UFS1; + sblock.fs_maxsymlinklen = maxsymlinklen; if (preen) printf(" (FIXED)\n"); if (preen || reply("FIX") == 1) { @@ -346,9 +342,13 @@ setup(char *dev) dirty(&asblk); } } - if (INOPB(&sblock) != sblock.fs_bsize / sizeof(struct ufs1_dinode)) { + if (sblock.fs_magic == FS_UFS2_MAGIC) + inopb = sblock.fs_bsize / sizeof(struct ufs2_dinode); + else + inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode); + if (INOPB(&sblock) != inopb) { pwarn("INCONSISTENT INOPB=%d\n", INOPB(&sblock)); - sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode); + sblock.fs_inopb = inopb; if (preen) printf(" (FIXED)\n"); if (preen || reply("FIX") == 1) { @@ -356,9 +356,13 @@ setup(char *dev) dirty(&asblk); } } - if (NINDIR(&sblock) != sblock.fs_bsize / sizeof(ufs1_daddr_t)) { + if (sblock.fs_magic == FS_UFS2_MAGIC) + nindir = sblock.fs_bsize / sizeof(ufs2_daddr_t); + else + nindir = sblock.fs_bsize / sizeof(ufs1_daddr_t); + if (NINDIR(&sblock) != nindir) { pwarn("INCONSISTENT NINDIR=%d\n", NINDIR(&sblock)); - sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t); + sblock.fs_nindir = nindir; if (preen) printf(" (FIXED)\n"); if (preen || reply("FIX") == 1) { @@ -384,7 +388,7 @@ setup(char *dev) size = sblock.fs_cssize - i < sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize; if (bread(fsreadfd, (char *)sblock.fs_csp + i, - fsbtodb(&sblock, sblock.fs_ffs1_csaddr + j * sblock.fs_frag), + fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); if (reply("CONTINUE") == 0) { @@ -422,7 +426,13 @@ setup(char *dev) (unsigned long)(maxino + 1) * sizeof(int16_t)); goto badsblabel; } - numdirs = sblock.fs_ffs1_cstotal.cs_ndir; + cginosused = calloc((unsigned)sblock.fs_ncg, sizeof(long)); + if (cginosused == NULL) { + printf("cannot alloc %u bytes for cginosused\n", + (unsigned)sblock.fs_ncg); + goto badsblabel; + } + numdirs = MAX(sblock.fs_cstotal.cs_ndir, 128); inplast = 0; listmax = numdirs + 10; inpsort = calloc((unsigned)listmax, sizeof(struct inoinfo *)); @@ -433,7 +443,7 @@ setup(char *dev) goto badsblabel; } bufinit(); - if (sblock.fs_ffs1_flags & FS_DOSOFTDEP) + if (sblock.fs_flags & FS_DOSOFTDEP) usedsoftdep = 1; else usedsoftdep = 0; @@ -444,25 +454,58 @@ badsblabel: return (0); } + /* * Read in the super block and its summary info. */ static int readsb(int listerr) { - daddr_t super = bflag ? bflag : SBOFF / dev_bsize; + ufs2_daddr_t super = 0; + int i; + + if (bflag) { + super = bflag; + + if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0) + return (0); + + if (sblock.fs_magic != FS_UFS1_MAGIC && + sblock.fs_magic != FS_UFS2_MAGIC) { + badsb(listerr, "MAGIC NUMBER WRONG"); + return (0); + } + } else { + for (i = 0; sbtry[i] != -1; i++) { + super = sbtry[i] / dev_bsize; + + if (bread(fsreadfd, (char *)&sblock, super, + (long)SBSIZE) != 0) + return (0); + + if (sblock.fs_magic != FS_UFS1_MAGIC && + sblock.fs_magic != FS_UFS2_MAGIC) + continue; /* Not a superblock */ + + if (sblock.fs_magic == FS_UFS2_MAGIC && + sblock.fs_sblockloc != sbtry[i]) + continue; /* Not a superblock */ + + break; + } + + if (sbtry[i] == -1) { + badsb(listerr, "MAGIC NUMBER WRONG"); + return (0); + } + } - if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0) - return (0); sblk.b_bno = super; sblk.b_size = SBSIZE; + /* * run a few consistency checks of the super block */ - if (sblock.fs_magic != FS_MAGIC) { - badsb(listerr, "MAGIC NUMBER WRONG"); - return (0); - } if (sblock.fs_ncg < 1) { badsb(listerr, "NCG OUT OF RANGE"); return (0); @@ -471,10 +514,12 @@ readsb(int listerr) badsb(listerr, "CPG OUT OF RANGE"); return (0); } - if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || - (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) { - badsb(listerr, "NCYL LESS THAN NCG*CPG"); - return (0); + if (sblock.fs_magic == FS_UFS1_MAGIC) { + if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || + (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) { + badsb(listerr, "NCYL LESS THAN NCG*CPG"); + return (0); + } } if (sblock.fs_sbsize > SBSIZE) { badsb(listerr, "SBSIZE PREPOSTEROUSLY LARGE"); @@ -502,10 +547,8 @@ readsb(int listerr) super *= dev_bsize; dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); sblk.b_bno = super / dev_bsize; - if (bflag) { - havesb = 1; - return (1); - } + if (bflag) + goto out; getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); if (asblk.b_errs) return (0); @@ -528,6 +571,17 @@ readsb(int listerr) "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE"); return (0); } +out: + if (sblock.fs_magic == FS_UFS1_MAGIC) { + sblock.fs_time = sblock.fs_ffs1_time; + sblock.fs_size = sblock.fs_ffs1_size; + sblock.fs_dsize = sblock.fs_ffs1_dsize; + sblock.fs_csaddr = sblock.fs_ffs1_csaddr; + sblock.fs_cstotal.cs_ndir = sblock.fs_ffs1_cstotal.cs_ndir; + sblock.fs_cstotal.cs_nbfree = sblock.fs_ffs1_cstotal.cs_nbfree; + sblock.fs_cstotal.cs_nifree = sblock.fs_ffs1_cstotal.cs_nifree; + sblock.fs_cstotal.cs_nffree = sblock.fs_ffs1_cstotal.cs_nffree; + } havesb = 1; return (1); } @@ -581,7 +635,7 @@ calcsb(char *dev, int devfd, struct fs *fs) fs->fs_cpg = pp->p_cpg; fs->fs_nspf = fs->fs_fsize / lp->d_secsize; /* unit for fs->fs_size is fragments, for pp->p_size it is sectors */ - fs->fs_ffs1_size = pp->p_size / fs->fs_nspf; + fs->fs_size = pp->p_size / fs->fs_nspf; fs->fs_ntrak = lp->d_ntracks; fs->fs_nsect = lp->d_nsectors; fs->fs_spc = lp->d_secpercyl; diff --git a/sbin/fsck_ffs/utilities.c b/sbin/fsck_ffs/utilities.c index 8841eac111a..ea366ea57d6 100644 --- a/sbin/fsck_ffs/utilities.c +++ b/sbin/fsck_ffs/utilities.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utilities.c,v 1.32 2007/03/19 13:27:47 pedro Exp $ */ +/* $OpenBSD: utilities.c,v 1.33 2007/04/10 16:08:17 millert Exp $ */ /* $NetBSD: utilities.c,v 1.18 1996/09/27 22:45:20 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #else -static const char rcsid[] = "$OpenBSD: utilities.c,v 1.32 2007/03/19 13:27:47 pedro Exp $"; +static const char rcsid[] = "$OpenBSD: utilities.c,v 1.33 2007/04/10 16:08:17 millert Exp $"; #endif #endif /* not lint */ @@ -64,9 +64,9 @@ long diskreads, totalreads; /* Disk cache statistics */ static void rwerror(char *, daddr_t); int -ftypeok(struct ufs1_dinode *dp) +ftypeok(union dinode *dp) { - switch (dp->di_mode & IFMT) { + switch (DIP(dp, di_mode) & IFMT) { case IFDIR: case IFREG: case IFBLK: @@ -77,7 +77,7 @@ ftypeok(struct ufs1_dinode *dp) return (1); default: if (debug) - printf("bad file type 0%o\n", dp->di_mode); + printf("bad file type 0%o\n", DIP(dp, di_mode)); return (0); } } @@ -227,7 +227,7 @@ flush(int fd, struct bufarea *bp) return; for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { bwrite(fswritefd, (char *)sblock.fs_csp + i, - fsbtodb(&sblock, sblock.fs_ffs1_csaddr + j * sblock.fs_frag), + fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), sblock.fs_cssize - i < sblock.fs_bsize ? sblock.fs_cssize - i : sblock.fs_bsize); } @@ -250,6 +250,7 @@ ckfini(int markclean) struct bufarea *bp, *nbp; int cnt = 0; sigset_t oset, nset; + int64_t sblockloc; sigemptyset(&nset); sigaddset(&nset, SIGINT); @@ -261,12 +262,24 @@ ckfini(int markclean) sigprocmask(SIG_SETMASK, &oset, NULL); return; } - /* Force update on next mount */ - sblock.fs_ffs1_flags &= ~FS_FLAGS_UPDATED; + if (sblock.fs_magic == FS_UFS1_MAGIC) { + sblockloc = SBLOCK_UFS1; + sblock.fs_ffs1_time = sblock.fs_time; + sblock.fs_ffs1_size = sblock.fs_size; + sblock.fs_ffs1_dsize = sblock.fs_dsize; + sblock.fs_ffs1_csaddr = sblock.fs_csaddr; + sblock.fs_ffs1_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir; + sblock.fs_ffs1_cstotal.cs_nbfree = sblock.fs_cstotal.cs_nbfree; + sblock.fs_ffs1_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree; + sblock.fs_ffs1_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree; + /* Force update on next mount */ + sblock.fs_ffs1_flags &= ~FS_FLAGS_UPDATED; + } else + sblockloc = SBLOCK_UFS2; flush(fswritefd, &sblk); - if (havesb && sblk.b_bno != SBOFF / dev_bsize && - !preen && reply("UPDATE STANDARD SUPERBLOCK")) { - sblk.b_bno = SBOFF / dev_bsize; + if (havesb && sblk.b_bno != sblockloc / dev_bsize && !preen && + reply("UPDATE STANDARD SUPERBLOCK")) { + sblk.b_bno = sblockloc / dev_bsize; sbdirty(); flush(fswritefd, &sblk); } |