summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2007-04-10 16:08:18 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2007-04-10 16:08:18 +0000
commit2c8e080377c510894f310612f6d8a99efc8efc74 (patch)
tree5be96bc88ef4d998dd50980aae354bc1eec4fdd9 /sbin
parent037bcc8f2068c6e0961b3b5dd7f6fd375dfc0c02 (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.c94
-rw-r--r--sbin/fsck_ffs/extern.h12
-rw-r--r--sbin/fsck_ffs/fsck.h58
-rw-r--r--sbin/fsck_ffs/inode.c176
-rw-r--r--sbin/fsck_ffs/main.c18
-rw-r--r--sbin/fsck_ffs/pass1.c120
-rw-r--r--sbin/fsck_ffs/pass1b.c6
-rw-r--r--sbin/fsck_ffs/pass2.c40
-rw-r--r--sbin/fsck_ffs/pass4.c70
-rw-r--r--sbin/fsck_ffs/pass5.c75
-rw-r--r--sbin/fsck_ffs/setup.c134
-rw-r--r--sbin/fsck_ffs/utilities.c35
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);
}