--- sbin/fsck_ffs/dir.c.orig Wed Jan 24 14:24:58 2007 +++ sbin/fsck_ffs/dir.c Fri Feb 2 21:41:21 2007 @@ -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 *er 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 *er 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 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 * 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); @@ -579,8 +581,8 @@ expanddir(struct ufs1_dinode *dp, char * 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); @@ -593,10 +595,10 @@ expanddir(struct ufs1_dinode *dp, char * 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); } @@ -611,7 +613,7 @@ allocdir(ino_t parent, ino_t request, in uid_t uid; gid_t gid; char *cp; - struct ufs1_dinode *dp; + union dinode *dp; struct bufarea *bp; struct dirtemplate *dirp; struct inoinfo *inp; @@ -624,7 +626,7 @@ allocdir(ino_t parent, ino_t request, in 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); @@ -635,10 +637,10 @@ allocdir(ino_t parent, ino_t request, in 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); } @@ -652,17 +654,17 @@ allocdir(ino_t parent, ino_t request, in 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); } @@ -673,11 +675,11 @@ allocdir(ino_t parent, ino_t request, in 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); --- sbin/fsck_ffs/extern.h.orig Tue Aug 26 01:28:15 2003 +++ sbin/fsck_ffs/extern.h Fri Feb 2 21:41:21 2007 @@ -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); --- sbin/fsck_ffs/fsck.h.orig Wed Mar 22 21:24:32 2006 +++ sbin/fsck_ffs/fsck.h Fri Feb 2 21:41:21 2007 @@ -2,6 +2,15 @@ /* $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 */ @@ -197,10 +235,18 @@ int lfmode; /* lost & found directory 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) (*(dp) = zino) -struct ufs1_dinode zino; +#define clearinode(dp) \ + if (sblock.fs_magic == FS_UFS1_MAGIC) { \ + (dp)->dp1 = ufs1_zino; \ + } else { \ + (dp)->dp2 = ufs2_zino; \ + } +struct ufs1_dinode ufs1_zino; +struct ufs2_dinode ufs2_zino; + #define setbmap(blkno) setbit(blockmap, blkno) #define testbmap(blkno) isset(blockmap, blkno) #define clrbmap(blkno) clrbit(blockmap, blkno) @@ -211,7 +257,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); --- sbin/fsck_ffs/inode.c.orig Wed Jan 24 14:24:58 2007 +++ sbin/fsck_ffs/inode.c Sat Feb 3 22:04:16 2007 @@ -60,33 +60,37 @@ static ino_t startinum; static int iblock(struct inodesc *, long, u_int64_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 i 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 i } 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 i 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 i 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 i 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,26 +179,24 @@ iblock(struct inodesc *idesc, long ileve 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", idesc->id_number); 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 @@ -211,7 +212,8 @@ iblock(struct inodesc *idesc, long ileve 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"); @@ -267,7 +269,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; @@ -282,7 +284,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)]); } /* @@ -291,14 +296,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); @@ -312,25 +318,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 { @@ -361,14 +380,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)); @@ -384,9 +404,13 @@ cacheino(struct ufs1_dinode *dp, ino_t i 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, @@ -442,12 +466,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) { @@ -490,7 +514,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; @@ -501,16 +525,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]); } @@ -548,7 +572,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; @@ -583,20 +607,22 @@ 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_mtime, t); + DIP_SET(dp, di_ctime, t); + DIP_SET(dp, di_atime, t); + DIP_SET(dp, di_size, sblock.fs_fsize); + DIP_SET(dp, di_blocks, btodb(sblock.fs_fsize)); n_files++; inodirty(); if (newinofmt) @@ -611,7 +637,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; --- sbin/fsck_ffs/main.c.orig Fri Feb 2 21:35:41 2007 +++ sbin/fsck_ffs/main.c Fri Feb 2 21:41:21 2007 @@ -256,15 +256,15 @@ checkfilesys(char *filesys, char *mntpt, /* * 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 * @@ -291,7 +291,7 @@ checkfilesys(char *filesys, char *mntpt, muldup = NULL; inocleanup(); if (fsmodified) { - (void)time(&sblock.fs_ffs1_time); + sblock.fs_time = (time_t)time(NULL); sbdirty(); } if (cvtlevel && sblk.b_dirty) { --- sbin/fsck_ffs/pass1.c.orig Fri Feb 2 21:35:41 2007 +++ sbin/fsck_ffs/pass1.c Fri Feb 2 21:41:21 2007 @@ -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,19 +120,28 @@ 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; char *symbuf; 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); @@ -137,24 +152,25 @@ checkinode(ino_t inumber, struct inodesc 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) @@ -166,32 +182,39 @@ checkinode(ino_t inumber, struct inodesc * 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--) @@ -201,25 +224,26 @@ checkinode(ino_t inumber, struct inodesc } } 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"); @@ -234,7 +258,7 @@ checkinode(ino_t inumber, struct inodesc } } if (mode == IFDIR) { - if (dp->di_size == 0) + if (DIP(dp, di_size) == 0) statemap[inumber] = DCLEAR; else statemap[inumber] = DSTATE; @@ -242,27 +266,29 @@ checkinode(ino_t inumber, struct inodesc } 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; --- sbin/fsck_ffs/pass1b.c.orig Wed Mar 22 21:24:32 2006 +++ sbin/fsck_ffs/pass1b.c Fri Feb 2 21:41:21 2007 @@ -64,7 +64,7 @@ void pass1b(void) { int c, i; - struct ufs1_dinode *dp; + union dinode *dp; struct inodesc idesc; ino_t inumber; --- sbin/fsck_ffs/pass2.c.orig Wed Mar 22 21:24:32 2006 +++ sbin/fsck_ffs/pass2.c Fri Feb 2 21:41:21 2007 @@ -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_numblksi_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: --- sbin/fsck_ffs/pass4.c.orig Wed Mar 22 21:24:32 2006 +++ sbin/fsck_ffs/pass4.c Fri Feb 2 21:41:21 2007 @@ -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 +95,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; --- sbin/fsck_ffs/pass5.c.orig Mon Feb 19 12:35:31 2007 +++ sbin/fsck_ffs/pass5.c Mon Feb 19 12:39:42 2007 @@ -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 +284,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 +337,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 +381,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(); --- sbin/fsck_ffs/setup.c.orig Thu Feb 22 11:54:49 2007 +++ sbin/fsck_ffs/setup.c Thu Feb 22 11:55:44 2007 @@ -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 (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0) - return (0); + 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); + } + } + 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"); @@ -498,15 +543,13 @@ 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); if (cmpsb(&sblock, &altsblock)) { - if (debug) { + if (1) { long *nlp, *olp, *endlp; printf("superblock mismatches\n"); @@ -524,6 +567,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); } @@ -577,7 +631,7 @@ calcsb(char *dev, int devfd, struct 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; --- sbin/fsck_ffs/utilities.c.orig Thu Feb 22 11:54:49 2007 +++ sbin/fsck_ffs/utilities.c Thu Feb 22 11:55:46 2007 @@ -64,9 +64,9 @@ long diskreads, totalreads; /* Disk cach 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); } Index: sbin/fsdb/fsdb.c =================================================================== RCS file: /cvs/src/sbin/fsdb/fsdb.c,v retrieving revision 1.18 diff -u -p -r1.18 fsdb.c --- sbin/fsdb/fsdb.c 19 Mar 2004 14:16:01 -0000 1.18 +++ sbin/fsdb/fsdb.c 3 Feb 2007 17:40:50 -0000 @@ -80,7 +80,7 @@ static int chnamefunc(struct inodesc *); static int dotime(char *, int32_t *, int32_t *); int returntosingle = 0; -struct ufs1_dinode *curinode; +union dinode *curinode; ino_t curinum; static void @@ -328,7 +328,7 @@ CMDFUNCSTART(back) CMDFUNCSTART(zapi) { ino_t inum; - struct ufs1_dinode *dp; + union dinode *dp; char *cp; GETINUM(1,inum); @@ -356,7 +356,8 @@ CMDFUNCSTART(uplink) { if (!checkactive()) return 1; - printf("inode %d link count now %d\n", curinum, ++curinode->di_nlink); + DIP_SET(curinode, di_nlink, DIP(curinode, di_nlink) + 1); + printf("inode %d link count now %d\n", curinum, DIP(curinode, di_nlink)); inodirty(); return 0; } @@ -365,7 +366,8 @@ CMDFUNCSTART(downlink) { if (!checkactive()) return 1; - printf("inode %d link count now %d\n", curinum, --curinode->di_nlink); + DIP_SET(curinode, di_nlink, DIP(curinode, di_nlink) - 1); + printf("inode %d link count now %d\n", curinum, DIP(curinode, di_nlink)); inodirty(); return 0; } @@ -621,7 +623,7 @@ CMDFUNCSTART(newtype) if (!checkactive()) return 1; - type = curinode->di_mode & IFMT; + type = DIP(curinode, di_mode) & IFMT; for (tp = typenamemap; tp < &typenamemap[sizeof(typemap)/sizeof(*typemap)]; tp++) { @@ -636,8 +638,8 @@ CMDFUNCSTART(newtype) warnx("try one of `file', `dir', `socket', `fifo'"); return 1; } - curinode->di_mode &= ~IFMT; - curinode->di_mode |= type; + DIP_SET(curinode, di_mode, DIP(curinode, di_mode) & ~IFMT); + DIP_SET(curinode, di_mode, DIP(curinode, di_mode) | type); inodirty(); printactive(); return 0; @@ -658,8 +660,8 @@ CMDFUNCSTART(chmode) return 1; } - curinode->di_mode &= ~07777; - curinode->di_mode |= modebits; + DIP_SET(curinode, di_mode, DIP(curinode, di_mode) & ~07777); + DIP_SET(curinode, di_mode, DIP(curinode, di_mode) | modebits); inodirty(); printactive(); return rval; @@ -680,7 +682,7 @@ CMDFUNCSTART(chlen) return 1; } - curinode->di_size = len; + DIP_SET(curinode, di_size, len); inodirty(); printactive(); return rval; @@ -705,7 +707,7 @@ CMDFUNCSTART(chaflags) warnx("flags set beyond 32-bit range of field (%lx)", flags); return(1); } - curinode->di_flags = flags; + DIP_SET(curinode, di_flags, flags); inodirty(); printactive(); return rval; @@ -730,7 +732,7 @@ CMDFUNCSTART(chgen) warnx("gen set beyond 32-bit range of field (%lx)", gen); return(1); } - curinode->di_gen = gen; + DIP_SET(curinode, di_gen, gen); inodirty(); printactive(); return rval; @@ -755,7 +757,7 @@ CMDFUNCSTART(linkcount) return 1; } - curinode->di_nlink = lcnt; + DIP_SET(curinode, di_nlink, lcnt); inodirty(); printactive(); return rval; @@ -782,7 +784,7 @@ CMDFUNCSTART(chowner) } } - curinode->di_uid = uid; + DIP_SET(curinode, di_uid, uid); inodirty(); printactive(); return rval; @@ -808,7 +810,7 @@ CMDFUNCSTART(chgroup) } } - curinode->di_gid = gid; + DIP_SET(curinode, di_gid, gid); inodirty(); printactive(); return rval; @@ -873,8 +875,12 @@ badformat: CMDFUNCSTART(chmtime) { - if (dotime(argv[1], &curinode->di_mtime, &curinode->di_mtimensec)) + int32_t rsec, nsec; + + if (dotime(argv[1], &rsec, &nsec)) return 1; + DIP_SET(curinode, di_mtime, rsec); + DIP_SET(curinode, di_mtimensec, nsec); inodirty(); printactive(); return 0; @@ -882,8 +888,12 @@ CMDFUNCSTART(chmtime) CMDFUNCSTART(chatime) { - if (dotime(argv[1], &curinode->di_atime, &curinode->di_atimensec)) + int32_t rsec, nsec; + + if (dotime(argv[1], &rsec, &nsec)) return 1; + DIP_SET(curinode, di_atime, rsec); + DIP_SET(curinode, di_atimensec, nsec); inodirty(); printactive(); return 0; @@ -891,8 +901,12 @@ CMDFUNCSTART(chatime) CMDFUNCSTART(chctime) { - if (dotime(argv[1], &curinode->di_ctime, &curinode->di_ctimensec)) + int32_t rsec, nsec; + + if (dotime(argv[1], &rsec, &nsec)) return 1; + DIP_SET(curinode, di_ctime, rsec); + DIP_SET(curinode, di_ctimensec, nsec); inodirty(); printactive(); return 0; Index: sbin/fsdb/fsdb.h =================================================================== RCS file: /cvs/src/sbin/fsdb/fsdb.h,v retrieving revision 1.5 diff -u -p -r1.5 fsdb.h --- sbin/fsdb/fsdb.h 25 Aug 2003 23:28:15 -0000 1.5 +++ sbin/fsdb/fsdb.h 3 Feb 2007 17:40:50 -0000 @@ -54,12 +54,12 @@ struct cmdtable { unsigned int maxargc; int (*handler)(int argc, char *argv[]); }; -extern struct ufs1_dinode *curinode; +extern union dinode *curinode; extern ino_t curinum; char **crack(char *, int *); int argcount(struct cmdtable *, int, char *[]); -void printstat(const char *, ino_t, struct ufs1_dinode *); +void printstat(const char *, ino_t, union dinode *); int checkactive(void); int checkactivedir(void); int printactive(void); Index: sbin/fsdb/fsdbutil.c =================================================================== RCS file: /cvs/src/sbin/fsdb/fsdbutil.c,v retrieving revision 1.11 diff -u -p -r1.11 fsdbutil.c --- sbin/fsdb/fsdbutil.c 19 Dec 2005 15:18:01 -0000 1.11 +++ sbin/fsdb/fsdbutil.c 3 Feb 2007 17:40:50 -0000 @@ -94,7 +94,7 @@ argcount(struct cmdtable *cmdp, int argc } void -printstat(const char *cp, ino_t inum, struct ufs1_dinode *dp) +printstat(const char *cp, ino_t inum, union dinode *dp) { struct group *grp; struct passwd *pw; @@ -102,7 +102,7 @@ printstat(const char *cp, ino_t inum, st char *p; printf("%s: ", cp); - switch (dp->di_mode & IFMT) { + switch (DIP(dp, di_mode) & IFMT) { case IFDIR: puts("directory"); break; @@ -111,19 +111,22 @@ printstat(const char *cp, ino_t inum, st break; case IFBLK: printf("block special (%d,%d)", - major(dp->di_rdev), minor(dp->di_rdev)); + (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev))); break; case IFCHR: printf("character special (%d,%d)", - major(dp->di_rdev), minor(dp->di_rdev)); + (int)major(DIP(dp, di_rdev)), (int)minor(DIP(dp, di_rdev))); break; case IFLNK: fputs("symlink",stdout); - if (dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN_UFS1 && - dp->di_blocks == 0) - printf(" to `%.*s'\n", (int) dp->di_size, - (char *)dp->di_shortlink); - else + if (DIP(dp, di_size) > 0 && + DIP(dp, di_size) < sblock.fs_maxsymlinklen && + DIP(dp, di_blocks) == 0) { + char *p = sblock.fs_magic == FS_UFS1_MAGIC ? + (char *)dp->dp1.di_shortlink : + (char *)dp->dp2.di_shortlink; + printf(" to `%.*s'\n", (int)DIP(dp, di_size), p); + } else putchar('\n'); break; case IFSOCK: @@ -134,31 +137,31 @@ printstat(const char *cp, ino_t inum, st break; } - printf("I=%u MODE=%o SIZE=%llu", inum, dp->di_mode, dp->di_size); - t = dp->di_mtime; + printf("I=%u MODE=%o SIZE=%llu", inum, DIP(dp, di_mode), DIP(dp, di_size)); + t = DIP(dp, di_mtime); p = ctime(&t); printf("\n\tMTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], - dp->di_mtimensec); - t = dp->di_ctime; + DIP(dp, di_mtimensec)); + t = DIP(dp, di_ctime); p = ctime(&t); printf("\n\tCTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20], - dp->di_ctimensec); - t = dp->di_atime; + DIP(dp, di_ctimensec)); + t = DIP(dp, di_atime); p = ctime(&t); printf("\n\tATIME=%15.15s %4.4s [%d nsec]\n", &p[4], &p[20], - dp->di_atimensec); + DIP(dp, di_atimensec)); - if ((pw = getpwuid(dp->di_uid))) + if ((pw = getpwuid(DIP(dp, di_uid)))) printf("OWNER=%s ", pw->pw_name); else - printf("OWNUID=%u ", dp->di_uid); - if ((grp = getgrgid(dp->di_gid))) + printf("OWNUID=%u ", DIP(dp, di_uid)); + if ((grp = getgrgid(DIP(dp, di_gid)))) printf("GRP=%s ", grp->gr_name); else - printf("GID=%u ", dp->di_gid); + printf("GID=%u ", DIP(dp, di_gid)); - printf("LINKCNT=%hd FLAGS=%#x BLKCNT=%x GEN=%x\n", dp->di_nlink, - dp->di_flags, dp->di_blocks, dp->di_gen); + printf("LINKCNT=%hd FLAGS=%#x BLKCNT=%x GEN=%x\n", DIP(dp, di_nlink), + DIP(dp, di_flags), (unsigned)DIP(dp, di_blocks), DIP(dp, di_gen)); } int @@ -178,7 +181,7 @@ checkactivedir(void) warnx("no current inode"); return 0; } - if ((curinode->di_mode & IFMT) != IFDIR) { + if ((DIP(curinode, di_mode) & IFMT) != IFDIR) { warnx("inode %d not a directory", curinum); return 0; } @@ -190,7 +193,7 @@ printactive(void) { if (!checkactive()) return 1; - switch (curinode->di_mode & IFMT) { + switch (DIP(curinode, di_mode) & IFMT) { case IFDIR: case IFREG: case IFBLK: @@ -205,7 +208,8 @@ printactive(void) break; default: printf("current inode %d: screwy itype 0%o (mode 0%o)?\n", - curinum, curinode->di_mode & IFMT, curinode->di_mode); + curinum, DIP(curinode, di_mode) & IFMT, + DIP(curinode, di_mode)); break; } return 0;