summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r--sbin/fsck_ffs/dir.c86
-rw-r--r--sbin/fsck_ffs/fsck.h95
-rw-r--r--sbin/fsck_ffs/fsutil.c28
-rw-r--r--sbin/fsck_ffs/inode.c189
-rw-r--r--sbin/fsck_ffs/main.c20
-rw-r--r--sbin/fsck_ffs/pass1.c125
-rw-r--r--sbin/fsck_ffs/pass1b.c4
-rw-r--r--sbin/fsck_ffs/pass2.c38
-rw-r--r--sbin/fsck_ffs/pass4.c6
-rw-r--r--sbin/fsck_ffs/pass5.c149
-rw-r--r--sbin/fsck_ffs/setup.c111
11 files changed, 477 insertions, 374 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index 9a3eee4..7ab051d 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -69,10 +69,10 @@ struct odirtemplate odirhead = {
static int chgino(struct inodesc *);
static int dircheck(struct inodesc *, struct direct *);
-static int expanddir(struct dinode *dp, char *name);
+static int expanddir(union dinode *dp, char *name);
static void freedir(ino_t ino, ino_t parent);
static struct direct *fsck_readdir(struct inodesc *);
-static struct bufarea *getdirblk(ufs_daddr_t blkno, long size);
+static struct bufarea *getdirblk(ufs2_daddr_t blkno, long size);
static int lftempname(char *bufp, ino_t ino);
static int mkentry(struct inodesc *);
@@ -255,7 +255,7 @@ direrror(ino_t ino, char *errmesg)
void
fileerror(ino_t cwd, ino_t ino, char *errmesg)
{
- struct dinode *dp;
+ union dinode *dp;
char pathbuf[MAXPATHLEN + 1];
pwarn("%s ", errmesg);
@@ -269,7 +269,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);
}
@@ -277,11 +278,11 @@ fileerror(ino_t cwd, ino_t ino, char *errmesg)
void
adjust(struct inodesc *idesc, int lcnt)
{
- struct dinode *dp;
+ union dinode *dp;
int saveresolved;
dp = ginode(idesc->id_number);
- if (dp->di_nlink == lcnt) {
+ if (DIP(dp, di_nlink) == lcnt) {
/*
* If we have not hit any unresolved problems, are running
* in preen mode, and are on a filesystem using soft updates,
@@ -312,10 +313,10 @@ adjust(struct inodesc *idesc, int lcnt)
}
if (lcnt != 0) {
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);
+ DIP(dp, di_nlink), DIP(dp, di_nlink) - lcnt);
if (preen || usedsoftdep) {
if (lcnt < 0) {
printf("\n");
@@ -326,7 +327,7 @@ adjust(struct inodesc *idesc, int lcnt)
}
if (preen || reply("ADJUST") == 1) {
if (bkgrdflag == 0) {
- dp->di_nlink -= lcnt;
+ DIP(dp, di_nlink) -= lcnt;
inodirty();
} else {
cmd.value = idesc->id_number;
@@ -383,7 +384,7 @@ chgino(struct inodesc *idesc)
int
linkup(ino_t orphan, ino_t parentdir, char *name)
{
- struct dinode *dp;
+ union dinode *dp;
int lostdir;
ino_t oldlfdir;
struct inodesc idesc;
@@ -391,10 +392,10 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
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 && dp->di_size == 0)
+ if (preen && DIP(dp, di_size) == 0)
return (0);
if (cursnapshot != 0) {
pfatal("FILE LINKUP IN SNAPSHOT");
@@ -438,7 +439,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
}
}
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);
@@ -475,7 +476,7 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
parentdir != (ino_t)-1)
(void)makeentry(orphan, lfdir, "..");
dp = ginode(lfdir);
- dp->di_nlink++;
+ DIP(dp, di_nlink)++;
inodirty();
inoinfo(lfdir)->ino_linkcnt++;
pwarn("DIR I=%lu CONNECTED. ", (u_long)orphan);
@@ -520,7 +521,7 @@ changeino(ino_t dir, char *name, ino_t newnum)
int
makeentry(ino_t parent, ino_t ino, char *name)
{
- struct dinode *dp;
+ union dinode *dp;
struct inodesc idesc;
char pathbuf[MAXPATHLEN + 1];
@@ -535,8 +536,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(dp, di_size) = roundup(DIP(dp, di_size), DIRBLKSIZ);
inodirty();
}
if ((ckinode(dp, &idesc) & ALTERED) != 0)
@@ -552,23 +553,24 @@ makeentry(ino_t parent, ino_t ino, char *name)
* Attempt to expand the size of a directory
*/
static int
-expanddir(struct dinode *dp, char *name)
+expanddir(union dinode *dp, char *name)
{
- ufs_daddr_t lastbn, newblk;
+ ufs2_daddr_t lastbn, newblk;
struct bufarea *bp;
char *cp, firstblk[DIRBLKSIZ];
- lastbn = lblkno(&sblock, dp->di_size);
- if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)
+ lastbn = lblkno(&sblock, DIP(dp, di_size));
+ 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(dp, di_db[lastbn + 1]) = DIP(dp, di_db[lastbn]);
+ DIP(dp, di_db[lastbn]) = newblk;
+ DIP(dp, di_size) += sblock.fs_bsize;
+ 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;
memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
@@ -581,8 +583,8 @@ expanddir(struct dinode *dp, char *name)
cp += DIRBLKSIZ)
memmove(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;
memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir);
@@ -595,10 +597,10 @@ expanddir(struct 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(dp, di_db[lastbn]) = DIP(dp, di_db[lastbn + 1]);
+ DIP(dp, di_db[lastbn + 1]) = 0;
+ DIP(dp, di_size) -= sblock.fs_bsize;
+ 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, int mode)
{
ino_t ino;
char *cp;
- struct dinode *dp;
+ union dinode *dp;
struct bufarea *bp;
struct inoinfo *inp;
struct dirtemplate *dirp;
@@ -621,7 +623,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);
@@ -632,10 +634,10 @@ allocdir(ino_t parent, ino_t request, int mode)
cp += DIRBLKSIZ)
memmove(cp, &emptydir, sizeof emptydir);
dirty(bp);
- dp->di_nlink = 2;
+ DIP(dp, di_nlink) = 2;
inodirty();
if (ino == ROOTINO) {
- inoinfo(ino)->ino_linkcnt = dp->di_nlink;
+ inoinfo(ino)->ino_linkcnt = DIP(dp, di_nlink);
cacheino(dp, ino);
return(ino);
}
@@ -650,11 +652,11 @@ allocdir(ino_t parent, ino_t request, int mode)
inp->i_dotdot = parent;
inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
if (inoinfo(ino)->ino_state == DSTATE) {
- inoinfo(ino)->ino_linkcnt = dp->di_nlink;
+ inoinfo(ino)->ino_linkcnt = DIP(dp, di_nlink);
inoinfo(parent)->ino_linkcnt++;
}
dp = ginode(parent);
- dp->di_nlink++;
+ DIP(dp, di_nlink)++;
inodirty();
return (ino);
}
@@ -665,11 +667,11 @@ allocdir(ino_t parent, ino_t request, int mode)
static void
freedir(ino_t ino, ino_t parent)
{
- struct dinode *dp;
+ union dinode *dp;
if (ino != parent) {
dp = ginode(parent);
- dp->di_nlink--;
+ DIP(dp, di_nlink)--;
inodirty();
}
freeino(ino);
@@ -704,7 +706,7 @@ lftempname(char *bufp, ino_t ino)
* Insure that it is held until another is requested.
*/
static struct bufarea *
-getdirblk(ufs_daddr_t blkno, long size)
+getdirblk(ufs2_daddr_t blkno, long size)
{
if (pdirbp != 0)
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 2df0cd8..efe7fb5 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -1,4 +1,16 @@
/*
+ * 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) 1982, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
* Copyright (c) 1980, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -43,6 +55,14 @@
#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)
+
/*
* Each inode on the filesystem is described by the following structure.
* The linkcnt is initially set to the value in the inode. Each time it
@@ -79,19 +99,24 @@ struct inostatlist {
struct bufarea {
struct bufarea *b_next; /* free list queue */
struct bufarea *b_prev; /* free list queue */
- ufs_daddr_t b_bno;
+ ufs2_daddr_t b_bno;
int b_size;
int b_errs;
int b_flags;
union {
char *b_buf; /* buffer space */
- ufs_daddr_t *b_indir; /* indirect block */
+ ufs1_daddr_t *b_indir1; /* UFS1 indirect block */
+ ufs2_daddr_t *b_indir2; /* UFS2 indirect block */
struct fs *b_fs; /* super block */
struct cg *b_cg; /* cylinder group */
- struct dinode *b_dinode; /* inode block */
+ struct ufs1_dinode *b_dinode1; /* UFS1 inode block */
+ struct ufs2_dinode *b_dinode2; /* UFS2 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 B_INUSE 1
@@ -110,7 +135,7 @@ struct bufarea *pbp; /* current inode block */
} while (0)
#define initbarea(bp) do { \
(bp)->b_dirty = 0; \
- (bp)->b_bno = (ufs_daddr_t)-1; \
+ (bp)->b_bno = (ufs2_daddr_t)-1; \
(bp)->b_flags = 0; \
} while (0)
@@ -127,12 +152,12 @@ struct inodesc {
int (*id_func)(); /* function to be applied to blocks of inode */
ino_t id_number; /* inode number described */
ino_t id_parent; /* for DATA nodes, their parent */
- int id_lbn; /* logical block number of current block */
- ufs_daddr_t id_blkno; /* current block number being examined */
+ ufs_lbn_t id_lbn; /* logical block number of current block */
+ ufs2_daddr_t id_blkno; /* current block number being examined */
int id_numfrags; /* number of frags contained in block */
- quad_t id_filesize; /* for DATA nodes, the size of the directory */
+ off_t id_filesize; /* for DATA nodes, the size of the directory */
+ ufs2_daddr_t id_entryno;/* for DATA nodes, current entry number */
int id_loc; /* for DATA nodes, current location in dir */
- int id_entryno; /* for DATA nodes, current entry number */
struct direct *id_dirp; /* for DATA nodes, ptr to current entry */
char *id_name; /* for DATA nodes, name to find or enter */
char id_type; /* type of descriptor, DATA or ADDR */
@@ -165,7 +190,7 @@ struct inodesc {
*/
struct dups {
struct dups *next;
- ufs_daddr_t dup;
+ ufs2_daddr_t dup;
};
struct dups *duplist; /* head of dup list */
struct dups *muldup; /* end of unique duplicate dup block numbers */
@@ -189,7 +214,7 @@ struct inoinfo {
ino_t i_dotdot; /* inode number of `..' */
size_t i_isize; /* size of inode */
u_int i_numblks; /* size of block array in bytes */
- ufs_daddr_t i_blks[1]; /* actually longer */
+ ufs2_daddr_t i_blks[1]; /* actually longer */
} **inphead, **inpsort;
long numdirs, dirhash, listmax, inplast;
long countdirs; /* number of directories we actually found */
@@ -223,7 +248,7 @@ int fsmodified; /* 1 => write done to filesystem */
int fsreadfd; /* file descriptor for reading filesystem */
int fswritefd; /* file descriptor for writing filesystem */
-ufs_daddr_t maxfsblock; /* number of blocks in the filesystem */
+ufs2_daddr_t maxfsblock; /* number of blocks in the filesystem */
char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in filesystem */
@@ -231,13 +256,19 @@ ino_t lfdir; /* lost & found directory inode number */
char *lfname; /* lost & found directory name */
int lfmode; /* lost & found directory creation mode */
-ufs_daddr_t n_blks; /* number of blocks in use */
-ufs_daddr_t n_files; /* number of files in use */
+ufs2_daddr_t n_blks; /* number of blocks in use */
+ino_t n_files; /* number of files in use */
int got_siginfo; /* received a SIGINFO */
-#define clearinode(dp) (*(dp) = zino)
-struct 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)
@@ -255,44 +286,44 @@ struct fstab;
void adjust(struct inodesc *, int lcnt);
-ufs_daddr_t allocblk(long frags);
+ufs2_daddr_t allocblk(long frags);
ino_t allocdir(ino_t parent, ino_t request, int mode);
ino_t allocino(ino_t request, int type);
-void blkerror(ino_t ino, char *type, ufs_daddr_t blk);
+void blkerror(ino_t ino, char *type, ufs2_daddr_t blk);
char *blockcheck(char *name);
-int bread(int fd, char *buf, ufs_daddr_t blk, long size);
+int bread(int fd, char *buf, ufs2_daddr_t blk, long size);
void bufinit(void);
-void bwrite(int fd, char *buf, ufs_daddr_t blk, long size);
-void cacheino(struct dinode *dp, ino_t inumber);
+void bwrite(int fd, char *buf, ufs2_daddr_t blk, long size);
+void cacheino(union dinode *dp, ino_t inumber);
void catch(int);
void catchquit(int);
int changeino(ino_t dir, char *name, ino_t newnum);
-int chkrange(ufs_daddr_t blk, int cnt);
+int chkrange(ufs2_daddr_t blk, int cnt);
void ckfini(int markclean);
-int ckinode(struct dinode *dp, struct inodesc *);
+int ckinode(union dinode *dp, struct inodesc *);
void clri(struct inodesc *, char *type, int flag);
int clearentry(struct inodesc *);
void direrror(ino_t ino, char *errmesg);
int dirscan(struct inodesc *);
int dofix(struct inodesc *, char *msg);
-void ffs_clrblock(struct fs *, u_char *, ufs_daddr_t);
+void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
void ffs_fragacct(struct fs *, int, int32_t [], int);
-int ffs_isblock(struct fs *, u_char *, ufs_daddr_t);
-void ffs_setblock(struct fs *, u_char *, ufs_daddr_t);
+int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
+void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t);
void fileerror(ino_t cwd, ino_t ino, char *errmesg);
int findino(struct inodesc *);
int findname(struct inodesc *);
void flush(int fd, struct bufarea *bp);
-void freeblk(ufs_daddr_t blkno, long frags);
+void freeblk(ufs2_daddr_t blkno, long frags);
void freeino(ino_t ino);
void freeinodebuf(void);
-int ftypeok(struct dinode *dp);
-void getblk(struct bufarea *bp, ufs_daddr_t blk, long size);
-struct bufarea *getdatablk(ufs_daddr_t blkno, long size);
+int ftypeok(union dinode *dp);
+void getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
+struct bufarea *getdatablk(ufs2_daddr_t blkno, long size);
struct inoinfo *getinoinfo(ino_t inumber);
-struct dinode *getnextinode(ino_t inumber);
+union dinode *getnextinode(ino_t inumber);
void getpathname(char *namebuf, ino_t curdir, ino_t ino);
-struct dinode *ginode(ino_t inumber);
+union dinode *ginode(ino_t inumber);
void infohandler(int sig);
void inocleanup(void);
void inodirty(void);
@@ -314,7 +345,7 @@ void propagate(void);
void pwarn(const char *fmt, ...) __printflike(1, 2);
int readsb(int listerr);
int reply(char *question);
-void rwerror(char *mesg, ufs_daddr_t blk);
+void rwerror(char *mesg, ufs2_daddr_t blk);
void sblock_init(void);
void setinodebuf(ino_t);
int setup(char *dev);
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index bf6c7fe..18e5eed 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -42,6 +42,7 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <sys/disklabel.h>
#include <sys/stat.h>
#include <sys/disklabel.h>
@@ -63,9 +64,9 @@ static const char rcsid[] =
long diskreads, totalreads; /* Disk cache statistics */
int
-ftypeok(struct dinode *dp)
+ftypeok(union dinode *dp)
{
- switch (dp->di_mode & IFMT) {
+ switch (DIP(dp, di_mode) & IFMT) {
case IFDIR:
case IFREG:
@@ -78,7 +79,7 @@ ftypeok(struct dinode *dp)
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);
}
}
@@ -181,7 +182,7 @@ bufinit(void)
* Manage a cache of directory blocks.
*/
struct bufarea *
-getdatablk(ufs_daddr_t blkno, long size)
+getdatablk(ufs2_daddr_t blkno, long size)
{
struct bufarea *bp;
@@ -207,9 +208,9 @@ foundit:
}
void
-getblk(struct bufarea *bp, ufs_daddr_t blk, long size)
+getblk(struct bufarea *bp, ufs2_daddr_t blk, long size)
{
- ufs_daddr_t dblk;
+ ufs2_daddr_t dblk;
totalreads++;
dblk = fsbtodb(&sblock, blk);
@@ -251,7 +252,7 @@ flush(int fd, struct bufarea *bp)
}
void
-rwerror(char *mesg, ufs_daddr_t blk)
+rwerror(char *mesg, ufs2_daddr_t blk)
{
if (bkgrdcheck)
@@ -293,9 +294,10 @@ ckfini(int markclean)
return;
}
flush(fswritefd, &sblk);
- if (havesb && sblk.b_bno != SBOFF / dev_bsize && cursnapshot == 0 &&
+ if (havesb && cursnapshot == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
+ sblk.b_bno != fsbtodb(&sblock, sblock.fs_sblockloc) &&
!preen && reply("UPDATE STANDARD SUPERBLOCK")) {
- sblk.b_bno = SBOFF / dev_bsize;
+ sblk.b_bno = fsbtodb(&sblock, sblock.fs_sblockloc);
sbdirty();
flush(fswritefd, &sblk);
}
@@ -336,7 +338,7 @@ ckfini(int markclean)
}
int
-bread(int fd, char *buf, ufs_daddr_t blk, long size)
+bread(int fd, char *buf, ufs2_daddr_t blk, long size)
{
char *cp;
int i, errs;
@@ -373,7 +375,7 @@ bread(int fd, char *buf, ufs_daddr_t blk, long size)
}
void
-bwrite(int fd, char *buf, ufs_daddr_t blk, long size)
+bwrite(int fd, char *buf, ufs2_daddr_t blk, long size)
{
int i;
char *cp;
@@ -406,7 +408,7 @@ bwrite(int fd, char *buf, ufs_daddr_t blk, long size)
/*
* allocate a data block with the specified number of fragments
*/
-ufs_daddr_t
+ufs2_daddr_t
allocblk(long frags)
{
int i, j, k, cg, baseblk;
@@ -450,7 +452,7 @@ allocblk(long frags)
* Free a previously allocated block
*/
void
-freeblk(ufs_daddr_t blkno, long frags)
+freeblk(ufs2_daddr_t blkno, long frags)
{
struct inodesc idesc;
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 0050ae1..636daa6 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -40,6 +40,7 @@ static const char rcsid[] =
#endif /* not lint */
#include <sys/param.h>
+#include <sys/stdint.h>
#include <sys/time.h>
#include <sys/sysctl.h>
@@ -55,16 +56,15 @@ static const char rcsid[] =
static ino_t startinum;
-static int iblock(struct inodesc *, long ilevel, quad_t isize);
+static int iblock(struct inodesc *, long ilevel, off_t isize);
int
-ckinode(struct dinode *dp, struct inodesc *idesc)
+ckinode(union dinode *dp, struct inodesc *idesc)
{
- ufs_daddr_t *ap;
- int ret;
- long n, ndb, offset;
- struct dinode dino;
- quad_t remsize, sizepb;
+ off_t remsize, sizepb;
+ int i, offset, ret;
+ union dinode dino;
+ ufs2_daddr_t ndb;
mode_t mode;
char pathbuf[MAXPATHLEN + 1];
@@ -72,21 +72,25 @@ ckinode(struct dinode *dp, struct inodesc *idesc)
idesc->id_fix = DONTKNOW;
idesc->id_lbn = -1;
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 < (unsigned)sblock.fs_maxsymlinklen))
+ DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen))
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 (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++) {
idesc->id_lbn++;
- if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
+ 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, idesc->id_number,
@@ -95,8 +99,7 @@ ckinode(struct 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(dp, di_size) = i * sblock.fs_bsize;
printf(
"YOU MUST RERUN FSCK AFTERWARDS\n");
rerun = 1;
@@ -106,7 +109,7 @@ ckinode(struct dinode *dp, struct inodesc *idesc)
}
continue;
}
- idesc->id_blkno = *ap;
+ idesc->id_blkno = DIP(&dino, di_db[i]);
if (idesc->id_type != DATA)
ret = (*idesc->id_func)(idesc);
else
@@ -115,13 +118,13 @@ ckinode(struct 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++) {
+ for (i = 0; i < NIADDR; i++) {
sizepb *= NINDIR(&sblock);
- if (*ap) {
- idesc->id_blkno = *ap;
- ret = iblock(idesc, n, remsize);
+ 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 {
@@ -134,7 +137,7 @@ ckinode(struct dinode *dp, struct inodesc *idesc)
pathbuf);
if (reply("ADJUST LENGTH") == 1) {
dp = ginode(idesc->id_number);
- dp->di_size -= remsize;
+ DIP(dp, di_size) -= remsize;
remsize = 0;
printf(
"YOU MUST RERUN FSCK AFTERWARDS\n");
@@ -150,16 +153,14 @@ ckinode(struct dinode *dp, struct inodesc *idesc)
}
static int
-iblock(struct inodesc *idesc, long ilevel, quad_t isize)
+iblock(struct inodesc *idesc, long ilevel, off_t isize)
{
- ufs_daddr_t *ap;
- ufs_daddr_t *aplim;
struct bufarea *bp;
int i, n, (*func)(), nif;
- quad_t sizepb;
+ off_t sizepb;
char buf[BUFSIZ];
char pathbuf[MAXPATHLEN + 1];
- struct dinode *dp;
+ union dinode *dp;
if (idesc->id_type != DATA) {
func = idesc->id_func;
@@ -173,31 +174,30 @@ iblock(struct inodesc *idesc, long ilevel, quad_t isize)
ilevel--;
for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
sizepb *= NINDIR(&sblock);
- nif = howmany(isize , sizepb);
- if (nif > NINDIR(&sblock))
+ if (howmany(isize, sizepb) > NINDIR(&sblock))
nif = NINDIR(&sblock);
+ 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)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
(u_long)idesc->id_number);
if (preen) {
pfatal("%s", buf);
} else if (dofix(idesc, buf)) {
- *ap = 0;
+ IBLK(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++) {
+ for (i = 0; i < nif; i++) {
if (ilevel == 0)
idesc->id_lbn++;
- if (*ap) {
- idesc->id_blkno = *ap;
+ if (IBLK(bp, i)) {
+ idesc->id_blkno = IBLK(bp, i);
if (ilevel == 0)
n = (*func)(idesc);
else
@@ -215,7 +215,7 @@ iblock(struct inodesc *idesc, long ilevel, quad_t isize)
pathbuf);
if (reply("ADJUST LENGTH") == 1) {
dp = ginode(idesc->id_number);
- dp->di_size -= isize;
+ DIP(dp, di_size) -= isize;
isize = 0;
printf(
"YOU MUST RERUN FSCK AFTERWARDS\n");
@@ -237,7 +237,7 @@ iblock(struct inodesc *idesc, long ilevel, quad_t isize)
* Return 0 if in range, 1 if out of range.
*/
int
-chkrange(ufs_daddr_t blk, int cnt)
+chkrange(ufs2_daddr_t blk, int cnt)
{
int c;
@@ -280,10 +280,10 @@ chkrange(ufs_daddr_t blk, int cnt)
/*
* General purpose interface for reading inodes.
*/
-struct dinode *
+union dinode *
ginode(ino_t inumber)
{
- ufs_daddr_t iblk;
+ ufs2_daddr_t iblk;
if (inumber < ROOTINO || inumber > maxino)
errx(EEXIT, "bad inode number %d to ginode", inumber);
@@ -295,7 +295,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)]);
}
/*
@@ -304,14 +307,15 @@ ginode(ino_t inumber)
*/
static ino_t nextino, lastinum, lastvalidinum;
static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-static struct dinode *inodebuf;
+static caddr_t inodebuf;
-struct dinode *
+union dinode *
getnextinode(ino_t inumber)
{
long size;
- ufs_daddr_t dblk;
- static struct dinode *dp;
+ ufs2_daddr_t dblk;
+ union dinode *dp;
+ static caddr_t nextinop;
if (inumber != nextino++ || inumber > lastvalidinum)
errx(EEXIT, "bad inode number %d to nextinode", inumber);
@@ -329,10 +333,15 @@ getnextinode(ino_t inumber)
* If bread returns an error, it will already have zeroed
* out the buffer, so we do not need to do so here.
*/
- (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
@@ -349,17 +358,19 @@ setinodebuf(ino_t inum)
if (inodebuf != NULL)
return;
inobufsize = blkroundup(&sblock, INOBUFSIZE);
- fullcnt = inobufsize / sizeof(struct dinode);
+ fullcnt = inobufsize / ((sblock.fs_magic == FS_UFS1_MAGIC) ?
+ sizeof(struct ufs1_dinode) : sizeof(struct ufs2_dinode));
readpercg = sblock.fs_ipg / fullcnt;
partialcnt = sblock.fs_ipg % fullcnt;
- partialsize = partialcnt * sizeof(struct dinode);
+ partialsize = partialcnt * ((sblock.fs_magic == FS_UFS1_MAGIC) ?
+ sizeof(struct ufs1_dinode) : sizeof(struct ufs2_dinode));
if (partialcnt != 0) {
readpercg++;
} else {
partialcnt = fullcnt;
partialsize = inobufsize;
}
- if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
+ if ((inodebuf = malloc((unsigned)inobufsize)) == NULL)
errx(EEXIT, "cannot allocate space for inode buffer");
}
@@ -380,17 +391,17 @@ freeinodebuf(void)
* Enter inodes into the cache.
*/
void
-cacheino(struct dinode *dp, ino_t inumber)
+cacheino(union dinode *dp, ino_t inumber)
{
- struct inoinfo *inp;
- struct inoinfo **inpp;
- int blks;
+ struct inoinfo *inp, **inpp;
+ int i, blks;
- blks = howmany(dp->di_size, sblock.fs_bsize);
- if (blks > NDADDR)
+ if (howmany(DIP(dp, di_size), sblock.fs_bsize) > NDADDR)
blks = NDADDR + NIADDR;
+ else
+ blks = howmany(DIP(dp, di_size), sblock.fs_bsize);
inp = (struct inoinfo *)
- malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
+ malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t));
if (inp == NULL)
errx(EEXIT, "cannot increase directory list");
inpp = &inphead[inumber % dirhash];
@@ -399,9 +410,13 @@ cacheino(struct dinode *dp, ino_t inumber)
inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
inp->i_dotdot = (ino_t)0;
inp->i_number = inumber;
- inp->i_isize = dp->di_size;
- inp->i_numblks = blks * sizeof(ufs_daddr_t);
- memmove(&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) {
listmax += 100;
inpsort = (struct inoinfo **)realloc((char *)inpsort,
@@ -456,12 +471,12 @@ inodirty(void)
void
clri(struct inodesc *idesc, char *type, int flag)
{
- struct 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) {
@@ -475,7 +490,7 @@ clri(struct inodesc *idesc, char *type, int flag)
inodirty();
} else {
cmd.value = idesc->id_number;
- cmd.size = -dp->di_nlink;
+ cmd.size = -DIP(dp, di_nlink);
if (debug)
printf("adjrefcnt ino %ld amt %ld\n",
(long)cmd.value, cmd.size);
@@ -530,7 +545,7 @@ clearentry(struct inodesc *idesc)
void
pinode(ino_t ino)
{
- struct dinode *dp;
+ union dinode *dp;
char *p;
struct passwd *pw;
time_t t;
@@ -540,24 +555,24 @@ pinode(ino_t ino)
return;
dp = ginode(ino);
printf(" OWNER=");
- if ((pw = getpwuid((int)dp->di_uid)) != 0)
+ if ((pw = getpwuid((int)DIP(dp, di_uid))) != 0)
printf("%s ", pw->pw_name);
else
- 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=%qu ", dp->di_size);
- t = dp->di_mtime;
+ printf("SIZE=%qu ", DIP(dp, di_size));
+ t = DIP(dp, di_mtime);
p = ctime(&t);
printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
}
void
-blkerror(ino_t ino, char *type, ufs_daddr_t blk)
+blkerror(ino_t ino, char *type, ufs2_daddr_t blk)
{
- pfatal("%ld %s I=%lu", (long)blk, type, (u_long)ino);
+ pfatal("%lld %s I=%lu", (intmax_t)blk, type, (u_long)ino);
printf("\n");
switch (inoinfo(ino)->ino_state) {
@@ -586,7 +601,7 @@ ino_t
allocino(ino_t request, int type)
{
ino_t ino;
- struct dinode *dp;
+ union dinode *dp;
struct cg *cgp = &cgrp;
int cg;
@@ -619,18 +634,20 @@ allocino(ino_t request, int type)
}
cgdirty();
dp = ginode(ino);
- dp->di_db[0] = allocblk((long)1);
- if (dp->di_db[0] == 0) {
+ DIP(dp, di_db[0]) = allocblk((long)1);
+ if (DIP(dp, di_db[0]) == 0) {
inoinfo(ino)->ino_state = USTATE;
return (0);
}
- dp->di_mode = type;
- dp->di_flags = 0;
- dp->di_atime = time(NULL);
- dp->di_mtime = dp->di_ctime = dp->di_atime;
- dp->di_mtimensec = dp->di_ctimensec = dp->di_atimensec = 0;
- dp->di_size = sblock.fs_fsize;
- dp->di_blocks = btodb(sblock.fs_fsize);
+ DIP(dp, di_mode) = type;
+ DIP(dp, di_flags) = 0;
+ DIP(dp, di_atime) = time(NULL);
+ DIP(dp, di_mtime) = DIP(dp, di_ctime) = DIP(dp, di_atime);
+ DIP(dp, di_mtimensec) = 0;
+ DIP(dp, di_ctimensec) = 0;
+ DIP(dp, di_atimensec) = 0;
+ DIP(dp, di_size) = sblock.fs_fsize;
+ DIP(dp, di_blocks) = btodb(sblock.fs_fsize);
n_files++;
inodirty();
inoinfo(ino)->ino_type = IFTODT(type);
@@ -644,7 +661,7 @@ void
freeino(ino_t ino)
{
struct inodesc idesc;
- struct 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 73364a7..c69e9d3 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
+#include <sys/disklabel.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/ufsmount.h>
@@ -95,6 +96,9 @@ main(int argc, char *argv[])
case 'c':
skipclean = 0;
cvtlevel = argtoi('c', "conversion level", optarg, 10);
+ if (cvtlevel < 3)
+ errx(EEXIT, "cannot do level %d conversion",
+ cvtlevel);
break;
case 'd':
@@ -180,14 +184,14 @@ argtoi(int flag, char *req, char *str, int base)
static int
checkfilesys(char *filesys)
{
- ufs_daddr_t n_ffree, n_bfree;
+ ufs2_daddr_t n_ffree, n_bfree;
struct ufs_args args;
struct dups *dp;
struct statfs *mntp;
struct zlncnt *zlnp;
- ufs_daddr_t blks;
- ufs_daddr_t files;
+ ufs2_daddr_t blks;
int cylno, size;
+ ino_t files;
cdevname = filesys;
if (debug && preen)
@@ -367,10 +371,9 @@ checkfilesys(char *filesys)
pwarn("Reclaimed: %ld directories, %ld files, %d fragments\n",
countdirs, (long)files - countdirs, blks);
}
- pwarn("%ld files, %ld used, %ld free ",
- (long)n_files, (long)n_blks, (long)(n_ffree +
- sblock.fs_frag * n_bfree));
- printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
+ pwarn("%ld files, %ld used, %qu free ",
+ (long)n_files, (long)n_blks, n_ffree + sblock.fs_frag * n_bfree);
+ printf("(%qu frags, %qu blocks, %.1f%% fragmentation)\n",
n_ffree, n_bfree, n_ffree * 100.0 / sblock.fs_dsize);
if (debug) {
if (files < 0)
@@ -404,7 +407,8 @@ checkfilesys(char *filesys)
*/
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
bwrite(fswritefd, (char *)&sblock,
- fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
+ fsbtodb(&sblock, cgsblock(&sblock, cylno)),
+ SBLOCKSIZE);
}
if (rerun)
resolved = 0;
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index cfb8af8..10f03eb 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -52,8 +52,8 @@ static const char rcsid[] =
#include "fsck.h"
-static ufs_daddr_t badblk;
-static ufs_daddr_t dupblk;
+static ufs2_daddr_t badblk;
+static ufs2_daddr_t dupblk;
static ino_t lastino; /* last inode in use */
static void checkinode(ino_t inumber, struct inodesc *);
@@ -61,11 +61,12 @@ static void checkinode(ino_t inumber, struct inodesc *);
void
pass1(void)
{
- u_int8_t *cp;
- ino_t inumber;
- int c, i, cgd, inosused;
struct inostat *info;
struct inodesc idesc;
+ ino_t inumber, inosused;
+ ufs2_daddr_t i, cgd;
+ u_int8_t *cp;
+ int c;
/*
* Set filesystem reserved blocks in used block map.
@@ -93,7 +94,11 @@ pass1(void)
for (c = 0; c < sblock.fs_ncg; c++) {
inumber = c * sblock.fs_ipg;
setinodebuf(inumber);
- inosused = sblock.fs_ipg;
+ getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
+ if (sblock.fs_magic == FS_UFS2_MAGIC)
+ inosused = cgrp.cg_initediblk;
+ else
+ inosused = sblock.fs_ipg;
if (got_siginfo) {
printf("%s: phase 1: cyl group %d of %d (%d%%)\n",
cdevname, c, sblock.fs_ncg,
@@ -108,10 +113,9 @@ pass1(void)
* read only those inodes in from disk.
*/
if (preen && usedsoftdep) {
- getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
if (!cg_chkmagic(&cgrp))
pfatal("CG %d: BAD MAGIC NUMBER\n", c);
- cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY];
+ cp = &cg_inosused(&cgrp)[(inosused - 1) / NBBY];
for ( ; inosused > 0; inosused -= NBBY, cp--) {
if (*cp == 0)
continue;
@@ -157,9 +161,10 @@ pass1(void)
* to the size necessary to describe the inodes that we
* really found.
*/
- inosused = lastino - (c * sblock.fs_ipg);
- if (inosused < 0)
+ if (lastino < (c * sblock.fs_ipg))
inosused = 0;
+ else
+ inosused = lastino - (c * sblock.fs_ipg);
inostathead[c].il_numalloced = inosused;
if (inosused == 0) {
free(inostathead[c].il_stat);
@@ -180,21 +185,29 @@ pass1(void)
static void
checkinode(ino_t inumber, struct inodesc *idesc)
{
- struct dinode *dp;
+ union dinode *dp;
struct zlncnt *zlnp;
- u_int64_t kernmaxfilesize;
- ufs_daddr_t ndb, j;
+ off_t kernmaxfilesize;
+ ufs2_daddr_t ndb;
mode_t mode;
char *symbuf;
+ int j;
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(ufs_daddr_t)) ||
- memcmp(dp->di_ib, zino.di_ib,
- NIADDR * sizeof(ufs_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=%lu",
(u_long)inumber);
if (reply("CLEAR") == 1) {
@@ -208,36 +221,37 @@ checkinode(ino_t inumber, struct inodesc *idesc)
}
lastino = inumber;
/* This should match the file size limit in ffs_mountfs(). */
- kernmaxfilesize = (u_int64_t)0x40000000 * sblock.fs_bsize - 1;
- if (dp->di_size > kernmaxfilesize ||
- dp->di_size > sblock.fs_maxfilesize ||
- (mode == IFDIR && dp->di_size > MAXDIRSIZE)) {
+ kernmaxfilesize = (off_t)0x40000000 * sblock.fs_bsize - 1;
+ if (DIP(dp, di_size) > kernmaxfilesize ||
+ DIP(dp, di_size) > sblock.fs_maxfilesize ||
+ (mode == IFDIR && DIP(dp, di_size) > MAXDIRSIZE)) {
if (debug)
- printf("bad size %qu:", dp->di_size);
+ printf("bad size %qu:", 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(dp, di_size) = sblock.fs_fsize;
+ DIP(dp, di_mode) = IFREG|0600;
inodirty();
}
if ((mode == IFBLK || mode == IFCHR || mode == IFIFO ||
- mode == IFSOCK) && dp->di_size != 0) {
+ mode == IFSOCK) && DIP(dp, di_size) != 0) {
if (debug)
- printf("bad special-file size %qu:", dp->di_size);
+ printf("bad special-file size %qu:", DIP(dp, di_size));
goto unknown;
}
- if ((mode == IFBLK || mode == IFCHR) && (dev_t)dp->di_rdev == NODEV) {
+ if ((mode == IFBLK || mode == IFCHR) &&
+ (dev_t)DIP(dp, di_rdev) == NODEV) {
if (debug)
printf("bad special-file rdev NODEV:");
goto unknown;
}
- ndb = howmany(dp->di_size, sblock.fs_bsize);
+ ndb = howmany(DIP(dp, di_size), sblock.fs_bsize);
if (ndb < 0) {
if (debug)
- printf("bad size %qu ndb %d:",
- dp->di_size, ndb);
+ printf("bad size %qu ndb %qu:",
+ DIP(dp, di_size), ndb);
goto unknown;
}
if (mode == IFBLK || mode == IFCHR)
@@ -247,8 +261,13 @@ checkinode(ino_t inumber, struct inodesc *idesc)
* Fake ndb value so direct/indirect block checks below
* will detect any garbage after symlink string.
*/
- if (dp->di_size < (u_int64_t)sblock.fs_maxsymlinklen) {
- ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
+ if (DIP(dp, di_size) < (off_t)sblock.fs_maxsymlinklen) {
+ 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--)
@@ -258,26 +277,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: %ld\n",
- (long)dp->di_db[j]);
+ printf("bad direct addr[%d]: %qu\n", j,
+ (ufs2_daddr_t)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: %ld\n",
- (long)dp->di_ib[j]);
+ printf("bad indirect addr: %qu\n",
+ DIP(dp, di_ib[j]));
goto unknown;
}
if (ftypeok(dp) == 0)
goto unknown;
n_files++;
- inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
- if (dp->di_nlink <= 0) {
+ inoinfo(inumber)->ino_linkcnt = DIP(dp, di_nlink);
+ if (DIP(dp, di_nlink) <= 0) {
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
if (zlnp == NULL) {
pfatal("LINK COUNT TABLE OVERFLOW");
@@ -292,7 +311,7 @@ checkinode(ino_t inumber, struct inodesc *idesc)
}
}
if (mode == IFDIR) {
- if (dp->di_size == 0)
+ if (DIP(dp, di_size) == 0)
inoinfo(inumber)->ino_state = DCLEAR;
else
inoinfo(inumber)->ino_state = DSTATE;
@@ -303,30 +322,30 @@ checkinode(ino_t inumber, struct inodesc *idesc)
inoinfo(inumber)->ino_type = IFTODT(mode);
badblk = dupblk = 0;
idesc->id_number = inumber;
- if (dp->di_flags & SF_SNAPSHOT)
+ if (DIP(dp, di_flags) & SF_SNAPSHOT)
idesc->id_type = SNAP;
else
idesc->id_type = ADDR;
(void)ckinode(dp, idesc);
idesc->id_entryno *= btodb(sblock.fs_fsize);
- if (dp->di_blocks != idesc->id_entryno) {
- pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
- (u_long)inumber, (long)dp->di_blocks,
- (long)idesc->id_entryno);
+ if (DIP(dp, di_blocks) != idesc->id_entryno) {
+ pwarn("INCORRECT BLOCK COUNT I=%lu (%qu should be %qu)",
+ (u_long)inumber, DIP(dp, di_blocks),
+ idesc->id_entryno);
if (preen)
printf(" (CORRECTED)\n");
else if (reply("CORRECT") == 0)
return;
if (bkgrdflag == 0) {
dp = ginode(inumber);
- dp->di_blocks = idesc->id_entryno;
+ DIP(dp, di_blocks) = idesc->id_entryno;
inodirty();
} else {
cmd.value = idesc->id_number;
- cmd.size = idesc->id_entryno - dp->di_blocks;
+ cmd.size = idesc->id_entryno - DIP(dp, di_blocks);
if (debug)
- printf("adjblkcnt ino %ld amount %ld\n",
- (long)cmd.value, cmd.size);
+ printf("adjblkcnt ino %qu amount %ld\n",
+ cmd.value, cmd.size);
if (sysctl(adjblkcnt, MIBSIZE, 0, 0,
&cmd, sizeof cmd) == -1)
rwerror("ADJUST INODE BLOCK COUNT", cmd.value);
@@ -349,7 +368,7 @@ pass1check(struct inodesc *idesc)
{
int res = KEEPON;
int anyout, nfrags;
- ufs_daddr_t blkno = idesc->id_blkno;
+ ufs2_daddr_t blkno = idesc->id_blkno;
struct dups *dlp;
struct dups *new;
diff --git a/sbin/fsck_ffs/pass1b.c b/sbin/fsck_ffs/pass1b.c
index dbb401b..b30a2b1 100644
--- a/sbin/fsck_ffs/pass1b.c
+++ b/sbin/fsck_ffs/pass1b.c
@@ -55,7 +55,7 @@ void
pass1b(void)
{
int c, i;
- struct dinode *dp;
+ union dinode *dp;
struct inodesc idesc;
ino_t inumber;
@@ -90,7 +90,7 @@ pass1bcheck(struct inodesc *idesc)
{
struct dups *dlp;
int nfrags, res = KEEPON;
- ufs_daddr_t blkno = idesc->id_blkno;
+ ufs2_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1))
diff --git a/sbin/fsck_ffs/pass2.c b/sbin/fsck_ffs/pass2.c
index 2347f76..34fda76 100644
--- a/sbin/fsck_ffs/pass2.c
+++ b/sbin/fsck_ffs/pass2.c
@@ -58,11 +58,12 @@ static int pass2check(struct inodesc *);
void
pass2(void)
{
- struct dinode *dp;
+ union dinode *dp;
struct inoinfo **inpp, *inp;
struct inoinfo **inpend;
struct inodesc curino;
- struct dinode dino;
+ union dinode dino;
+ int i;
char pathbuf[MAXPATHLEN + 1];
switch (inoinfo(ROOTINO)->ino_state) {
@@ -105,8 +106,8 @@ pass2(void)
exit(EEXIT);
}
dp = ginode(ROOTINO);
- dp->di_mode &= ~IFMT;
- dp->di_mode |= IFDIR;
+ DIP(dp, di_mode) &= ~IFMT;
+ DIP(dp, di_mode) |= IFDIR;
inodirty();
break;
@@ -130,7 +131,6 @@ pass2(void)
memset(&curino, 0, sizeof(struct inodesc));
curino.id_type = DATA;
curino.id_func = pass2check;
- dp = &dino;
inpend = &inpsort[inplast];
for (inpp = inpsort; inpp < inpend; inpp++) {
if (got_siginfo) {
@@ -147,9 +147,8 @@ pass2(void)
inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ);
if (reply("FIX") == 1) {
dp = ginode(inp->i_number);
- dp->di_size = inp->i_isize;
+ DIP(dp, di_size) = inp->i_isize;
inodirty();
- dp = &dino;
}
} else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) {
getpathname(pathbuf, inp->i_number, inp->i_number);
@@ -166,15 +165,22 @@ pass2(void)
inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
if (preen || reply("ADJUST") == 1) {
dp = ginode(inp->i_number);
- dp->di_size = roundup(inp->i_isize, DIRBLKSIZ);
+ DIP(dp, di_size) =
+ roundup(inp->i_isize, DIRBLKSIZ);
inodirty();
- dp = &dino;
}
}
- memset(&dino, 0, sizeof(struct dinode));
- dino.di_mode = IFDIR;
- dp->di_size = inp->i_isize;
- memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
+ dp = &dino;
+ memset(dp, 0, sizeof(struct ufs2_dinode));
+ DIP(dp, di_mode) = IFDIR;
+ DIP(dp, di_size) = inp->i_isize;
+ for (i = 0;
+ i < (inp->i_numblks<NDADDR ? inp->i_numblks : NDADDR);
+ i++)
+ DIP(dp, di_db[i]) = inp->i_blks[i];
+ if (inp->i_numblks > NDADDR)
+ for (i = 0; i < NIADDR; i++)
+ DIP(dp, di_ib[i]) = inp->i_blks[NDADDR + i];
curino.id_number = inp->i_number;
curino.id_parent = inp->i_parent;
(void)ckinode(dp, &curino);
@@ -223,7 +229,7 @@ pass2check(struct inodesc *idesc)
struct direct *dirp = idesc->id_dirp;
struct inoinfo *inp;
int n, entrysize, ret = 0;
- struct dinode *dp;
+ union dinode *dp;
char *errmsg;
struct direct proto;
char namebuf[MAXPATHLEN + 1];
@@ -392,8 +398,8 @@ again:
break;
dp = ginode(dirp->d_ino);
inoinfo(dirp->d_ino)->ino_state =
- (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
- inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink;
+ (DIP(dp, di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE;
+ inoinfo(dirp->d_ino)->ino_linkcnt = DIP(dp, di_nlink);
goto again;
case DSTATE:
diff --git a/sbin/fsck_ffs/pass4.c b/sbin/fsck_ffs/pass4.c
index 6683ae4..da29804 100644
--- a/sbin/fsck_ffs/pass4.c
+++ b/sbin/fsck_ffs/pass4.c
@@ -54,7 +54,7 @@ pass4(void)
{
ino_t inumber;
struct zlncnt *zlnp;
- struct dinode *dp;
+ union dinode *dp;
struct inodesc idesc;
int i, n, cg;
@@ -100,7 +100,7 @@ pass4(void)
case DCLEAR:
dp = ginode(inumber);
- if (dp->di_size == 0) {
+ if (DIP(dp, di_size) == 0) {
clri(&idesc, "ZERO LENGTH", 1);
break;
}
@@ -125,7 +125,7 @@ pass4check(struct inodesc *idesc)
{
struct dups *dlp;
int nfrags, res = KEEPON;
- ufs_daddr_t blkno = idesc->id_blkno;
+ ufs2_daddr_t blkno = idesc->id_blkno;
for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
if (chkrange(blkno, 1)) {
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index f2ab2a8..707872b 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -55,18 +55,17 @@ static void check_maps(u_char *, u_char *, int, int, char *, int *, int, int);
void
pass5(void)
{
- int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
+ int c, i, j, blk, frags, basesize, mapsize;
int inomapsize, blkmapsize;
struct fs *fs = &sblock;
struct cg *cg = &cgrp;
- ufs_daddr_t dbase, dmax, d;
- int i, j, excessdirs, rewritecg = 0;
+ ufs2_daddr_t d, dbase, dmax;
+ int excessdirs, rewritecg = 0;
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;
inoinfo(WINO)->ino_state = USTATE;
memset(newcg, 0, (size_t)fs->fs_cgsize);
@@ -110,63 +109,46 @@ pass5(void)
}
}
}
- switch ((int)fs->fs_postblformat) {
-
- case FS_42POSTBLFMT:
- basesize = (char *)(&ocg->cg_btot[0]) -
- (char *)(&ocg->cg_firstfield);
- sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]);
- mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
- (u_char *)&ocg->cg_iused[0];
- blkmapsize = howmany(fs->fs_fpg, NBBY);
- inomapsize = &ocg->cg_free[0] - (u_char *)&ocg->cg_iused[0];
- ocg->cg_magic = CG_MAGIC;
- savednrpos = fs->fs_nrpos;
- fs->fs_nrpos = 8;
- 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(u_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);
- blkmapsize = newcg->cg_nextfreeoff - newcg->cg_freeoff;
- if (fs->fs_contigsumsize > 0) {
- newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
- sizeof(u_int32_t);
- newcg->cg_clustersumoff =
- roundup(newcg->cg_clustersumoff, sizeof(u_int32_t));
- newcg->cg_clusteroff = newcg->cg_clustersumoff +
- (fs->fs_contigsumsize + 1) * sizeof(u_int32_t);
- newcg->cg_nextfreeoff = newcg->cg_clusteroff +
- howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
- }
- newcg->cg_magic = CG_MAGIC;
- basesize = &newcg->cg_space[0] -
- (u_char *)(&newcg->cg_firstfield);
- sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
- mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
- break;
-
- default:
- inomapsize = blkmapsize = sumsize = 0; /* keep lint happy */
- errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
- fs->fs_postblformat);
+ basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
+ if (sblock.fs_magic == FS_UFS2_MAGIC) {
+ newcg->cg_iusedoff = basesize;
+ } else {
+ /*
+ * We reserve the space for the old rotation summary
+ * tables for the benefit of old kernels, but do not
+ * maintain them in modern kernels. In time, they can
+ * go away.
+ */
+ newcg->cg_old_btotoff = basesize;
+ newcg->cg_old_boff = newcg->cg_old_btotoff +
+ fs->fs_old_cpg * sizeof(int32_t);
+ newcg->cg_iusedoff = newcg->cg_old_boff +
+ fs->fs_old_cpg * fs->fs_old_nrpos * sizeof(u_int16_t);
+ memset(&newcg->cg_space[0], 0, newcg->cg_iusedoff - basesize);
+ }
+ inomapsize = howmany(fs->fs_ipg, NBBY);
+ newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize;
+ blkmapsize = howmany(fs->fs_fpg, NBBY);
+ newcg->cg_nextfreeoff = newcg->cg_freeoff + blkmapsize;
+ if (fs->fs_contigsumsize > 0) {
+ newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
+ sizeof(u_int32_t);
+ newcg->cg_clustersumoff =
+ roundup(newcg->cg_clustersumoff, sizeof(u_int32_t));
+ newcg->cg_clusteroff = newcg->cg_clustersumoff +
+ (fs->fs_contigsumsize + 1) * sizeof(u_int32_t);
+ newcg->cg_nextfreeoff = newcg->cg_clusteroff +
+ howmany(fragstoblks(fs, fs->fs_fpg), NBBY);
}
+ newcg->cg_magic = CG_MAGIC;
+ mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
memset(&idesc[0], 0, sizeof idesc);
for (i = 0; i < 3; i++)
idesc[i].id_type = ADDR;
- memset(&cstotal, 0, sizeof(struct csum));
- j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
- for (i = fs->fs_size; i < j; i++)
- setbmap(i);
+ memset(&cstotal, 0, sizeof(struct csum_total));
+ dmax = blknum(fs, fs->fs_size + fs->fs_frag - 1);
+ for (d = fs->fs_size; d < dmax; d++)
+ setbmap(d);
for (c = 0; c < fs->fs_ncg; c++) {
if (got_siginfo) {
printf("%s: phase 5: cyl group %d of %d (%d%%)\n",
@@ -177,17 +159,23 @@ pass5(void)
getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
if (!cg_chkmagic(cg))
pfatal("CG %d: BAD MAGIC NUMBER\n", c);
+ newcg->cg_time = cg->cg_time;
+ newcg->cg_old_time = cg->cg_old_time;
+ newcg->cg_cgx = c;
dbase = cgbase(fs, c);
dmax = dbase + fs->fs_fpg;
if (dmax > fs->fs_size)
dmax = fs->fs_size;
- newcg->cg_time = cg->cg_time;
- newcg->cg_cgx = c;
- if (c == fs->fs_ncg - 1 && fs->fs_ncyl % fs->fs_cpg > 0)
- newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
- else
- newcg->cg_ncyl = fs->fs_cpg;
newcg->cg_ndblk = dmax - dbase;
+ if (fs->fs_magic == FS_UFS1_MAGIC) {
+ if (c == fs->fs_ncg - 1)
+ newcg->cg_old_ncyl = howmany(newcg->cg_ndblk,
+ fs->fs_fpg / fs->fs_old_cpg);
+ else
+ newcg->cg_old_ncyl = fs->fs_old_cpg;
+ newcg->cg_old_niblk = fs->fs_ipg;
+ newcg->cg_niblk = 0;
+ }
if (fs->fs_contigsumsize > 0)
newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
newcg->cg_cs.cs_ndir = 0;
@@ -206,11 +194,16 @@ pass5(void)
newcg->cg_irotor = cg->cg_irotor;
else
newcg->cg_irotor = 0;
+ if (fs->fs_magic == FS_UFS1_MAGIC) {
+ newcg->cg_initediblk = 0;
+ } else {
+ if ((unsigned)cg->cg_initediblk > fs->fs_ipg)
+ newcg->cg_initediblk = fs->fs_ipg;
+ else
+ newcg->cg_initediblk = cg->cg_initediblk;
+ }
memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
- memset(&cg_blktot(newcg)[0], 0,
- (size_t)(sumsize + mapsize));
- if (fs->fs_postblformat == FS_42POSTBLFMT)
- ocg->cg_magic = CG_MAGIC;
+ memset(cg_inosused(newcg), 0, (size_t)(mapsize));
j = fs->fs_ipg * c;
for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
switch (inoinfo(j)->ino_state) {
@@ -254,9 +247,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);
@@ -312,13 +302,9 @@ pass5(void)
continue;
}
if (cursnapshot == 0 &&
- (memcmp(newcg, cg, basesize) != 0 ||
- memcmp(&cg_blktot(newcg)[0],
- &cg_blktot(cg)[0], sumsize) != 0) &&
+ memcmp(newcg, cg, basesize) != 0 &&
dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
memmove(cg, newcg, (size_t)basesize);
- memmove(&cg_blktot(cg)[0],
- &cg_blktot(newcg)[0], (size_t)sumsize);
cgdirty();
}
if (bkgrdflag != 0 || usedsoftdep || debug) {
@@ -346,12 +332,10 @@ pass5(void)
cgdirty();
}
}
- if (fs->fs_postblformat == FS_42POSTBLFMT)
- fs->fs_nrpos = savednrpos;
if (cursnapshot == 0 &&
- memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0
- && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
- memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
+ memcmp(&cstotal, &fs->fs_cstotal, sizeof cstotal) != 0
+ && dofix(&idesc[0], "SUMMARY BLK COUNT(S) WRONG IN SUPERBLK")) {
+ memmove(&fs->fs_cstotal, &cstotal, sizeof cstotal);
fs->fs_ronly = 0;
fs->fs_fmod = 0;
sbdirty();
@@ -398,6 +382,7 @@ check_maps(
aend = n;
continue;
}
+ returntosingle = 1;
if (astart == aend)
(*msg)("ALLOCATED %s %d MARKED FREE\n",
name, astart);
@@ -434,6 +419,7 @@ check_maps(
pwarn("%s %sS %d-%ld MARKED USED\n",
"UNALLOCATED", name, ustart,
ustart + size - 1);
+ returntosingle = 1;
if (bkgrdflag != 0) {
cmd.value = ustart;
cmd.size = size;
@@ -476,6 +462,7 @@ check_maps(
pwarn("UNALLOCATED %sS %d-%ld MARKED USED\n",
name, ustart, ustart + size - 1);
}
+ returntosingle = 1;
if (bkgrdflag != 0) {
cmd.value = ustart;
cmd.size = size;
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 107ded2..243edbe 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -210,7 +210,8 @@ setup(char *dev)
sbdirty();
}
}
- if (sblock.fs_inodefmt < FS_44INODEFMT) {
+ if (sblock.fs_magic == FS_UFS1_MAGIC &&
+ sblock.fs_old_inodefmt < FS_44INODEFMT) {
pwarn("Format of filesystem is too old.\n");
pwarn("Must update to modern format using a version of fsck\n");
pfatal("from before 2002 with the command ``fsck -c 2''\n");
@@ -286,28 +287,43 @@ badsb:
}
/*
+ * Possible superblock locations ordered from most to least likely.
+ */
+static int sblock_try[] = SBLOCKSEARCH;
+
+/*
* Read in the super block and its summary info.
*/
int
readsb(int listerr)
{
- ufs_daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
+ ufs2_daddr_t super;
+ int i;
- 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); }
- if (sblock.fs_cpg < 1)
- { badsb(listerr, "CPG OUT OF RANGE"); return (0); }
- if (sblock.fs_sbsize > SBSIZE)
- { badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); }
+ if (bflag) {
+ super = bflag;
+ if ((bread(fsreadfd, (char *)&sblock, super, (long)SBLOCKSIZE)))
+ return (0);
+ } else {
+ for (i = 0; sblock_try[i] != -1; i++) {
+ super = sblock_try[i] / dev_bsize;
+ if ((bread(fsreadfd, (char *)&sblock, super,
+ (long)SBLOCKSIZE)))
+ return (0);
+ if ((sblock.fs_magic == FS_UFS1_MAGIC ||
+ (sblock.fs_magic == FS_UFS2_MAGIC &&
+ sblock.fs_sblockloc ==
+ numfrags(&sblock, sblock_try[i]))) &&
+ sblock.fs_ncg >= 1 &&
+ sblock.fs_bsize >= SBLOCKSIZE &&
+ sblock.fs_bsize >= sizeof(struct fs))
+ break;
+ }
+ if (sblock_try[i] == -1) {
+ fprintf(stderr, "Cannot find filesystem superblock\n");
+ return (0);
+ }
+ }
/*
* Compute block size that the filesystem is based on,
* according to fsbtodb, and adjust superblock block number
@@ -316,6 +332,7 @@ readsb(int listerr)
super *= dev_bsize;
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
sblk.b_bno = super / dev_bsize;
+ sblk.b_size = SBLOCKSIZE;
if (bflag) {
havesb = 1;
return (1);
@@ -331,8 +348,6 @@ readsb(int listerr)
altsblock.fs_cblkno != sblock.fs_cblkno ||
altsblock.fs_iblkno != sblock.fs_iblkno ||
altsblock.fs_dblkno != sblock.fs_dblkno ||
- altsblock.fs_cgoffset != sblock.fs_cgoffset ||
- altsblock.fs_cgmask != sblock.fs_cgmask ||
altsblock.fs_ncg != sblock.fs_ncg ||
altsblock.fs_bsize != sblock.fs_bsize ||
altsblock.fs_fsize != sblock.fs_fsize ||
@@ -347,7 +362,6 @@ readsb(int listerr)
altsblock.fs_nindir != sblock.fs_nindir ||
altsblock.fs_inopb != sblock.fs_inopb ||
altsblock.fs_cssize != sblock.fs_cssize ||
- altsblock.fs_cpg != sblock.fs_cpg ||
altsblock.fs_ipg != sblock.fs_ipg ||
altsblock.fs_fpg != sblock.fs_fpg ||
altsblock.fs_magic != sblock.fs_magic) {
@@ -355,6 +369,21 @@ readsb(int listerr)
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
return (0);
}
+ /*
+ * If not yet done, update UFS1 superblock with new wider fields.
+ */
+ if (sblock.fs_magic == FS_UFS1_MAGIC &&
+ sblock.fs_maxbsize != sblock.fs_bsize) {
+ sblock.fs_maxbsize = sblock.fs_bsize;
+ sblock.fs_time = sblock.fs_old_time;
+ sblock.fs_size = sblock.fs_old_size;
+ sblock.fs_dsize = sblock.fs_old_dsize;
+ sblock.fs_csaddr = sblock.fs_old_csaddr;
+ sblock.fs_cstotal.cs_ndir = sblock.fs_old_cstotal.cs_ndir;
+ sblock.fs_cstotal.cs_nbfree = sblock.fs_old_cstotal.cs_nbfree;
+ sblock.fs_cstotal.cs_nifree = sblock.fs_old_cstotal.cs_nifree;
+ sblock.fs_cstotal.cs_nffree = sblock.fs_old_cstotal.cs_nffree;
+ }
havesb = 1;
return (1);
}
@@ -380,8 +409,8 @@ sblock_init(void)
lfdir = 0;
initbarea(&sblk);
initbarea(&asblk);
- sblk.b_un.b_buf = malloc(SBSIZE);
- asblk.b_un.b_buf = malloc(SBSIZE);
+ sblk.b_un.b_buf = malloc(SBLOCKSIZE);
+ asblk.b_un.b_buf = malloc(SBLOCKSIZE);
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
errx(EEXIT, "cannot allocate space for superblock");
if ((lp = getdisklabel(NULL, fsreadfd)))
@@ -402,7 +431,7 @@ calcsb(char *dev, int devfd, struct fs *fs)
struct disklabel *lp;
struct partition *pp;
char *cp;
- int i;
+ int i, nspf;
cp = strchr(dev, '\0') - 1;
if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
@@ -430,24 +459,30 @@ calcsb(char *dev, int devfd, struct fs *fs)
memset(fs, 0, sizeof(struct fs));
fs->fs_fsize = pp->p_fsize;
fs->fs_frag = pp->p_frag;
- fs->fs_cpg = pp->p_cpg;
fs->fs_size = pp->p_size;
- fs->fs_ntrak = lp->d_ntracks;
- fs->fs_nsect = lp->d_nsectors;
- fs->fs_spc = lp->d_secpercyl;
- fs->fs_nspf = fs->fs_fsize / lp->d_secsize;
- fs->fs_cgmask = 0xffffffff;
- for (i = fs->fs_ntrak; i > 1; i >>= 1)
- fs->fs_cgmask <<= 1;
- if (!POWEROF2(fs->fs_ntrak))
- fs->fs_cgmask <<= 1;
- fs->fs_cgoffset = roundup(
- howmany(fs->fs_nsect, NSPF(fs)), fs->fs_frag);
- fs->fs_fpg = (fs->fs_cpg * fs->fs_spc) / NSPF(fs);
- fs->fs_ncg = howmany(fs->fs_size / fs->fs_spc, fs->fs_cpg);
- for (fs->fs_fsbtodb = 0, i = NSPF(fs); i > 1; i >>= 1)
+ fs->fs_sblkno = roundup(
+ howmany(lp->d_bbsize + lp->d_sbsize, fs->fs_fsize),
+ fs->fs_frag);
+ nspf = fs->fs_fsize / lp->d_secsize;
+ for (fs->fs_fsbtodb = 0, i = nspf; i > 1; i >>= 1)
fs->fs_fsbtodb++;
dev_bsize = lp->d_secsize;
+ if (fs->fs_magic == FS_UFS2_MAGIC) {
+ fs->fs_fpg = pp->p_cpg;
+ fs->fs_ncg = howmany(fs->fs_size, fs->fs_fpg);
+ } else /* if (fs->fs_magic == FS_UFS1_MAGIC) */ {
+ fs->fs_old_cpg = pp->p_cpg;
+ fs->fs_old_cgmask = 0xffffffff;
+ for (i = lp->d_ntracks; i > 1; i >>= 1)
+ fs->fs_old_cgmask <<= 1;
+ if (!POWEROF2(lp->d_ntracks))
+ fs->fs_old_cgmask <<= 1;
+ fs->fs_old_cgoffset = roundup(howmany(lp->d_nsectors, nspf),
+ fs->fs_frag);
+ fs->fs_fpg = (fs->fs_old_cpg * lp->d_secpercyl) / nspf;
+ fs->fs_ncg = howmany(fs->fs_size / lp->d_secpercyl,
+ fs->fs_old_cpg);
+ }
return (1);
}
OpenPOWER on IntegriCloud