summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-06-21 06:18:05 +0000
committermckusick <mckusick@FreeBSD.org>2002-06-21 06:18:05 +0000
commit88d85c15ef183c06524d6ca695f62c0c0672b00c (patch)
treef1364dbfb9835934a3879b5904f7ff9a1495744c /sbin/fsck_ffs
parenteacb69b0197a8553d5004aa99532cabad8778e36 (diff)
downloadFreeBSD-src-88d85c15ef183c06524d6ca695f62c0c0672b00c.zip
FreeBSD-src-88d85c15ef183c06524d6ca695f62c0c0672b00c.tar.gz
This commit adds basic support for the UFS2 filesystem. The UFS2
filesystem expands the inode to 256 bytes to make space for 64-bit block pointers. It also adds a file-creation time field, an ability to use jumbo blocks per inode to allow extent like pointer density, and space for extended attributes (up to twice the filesystem block size worth of attributes, e.g., on a 16K filesystem, there is space for 32K of attributes). UFS2 fully supports and runs existing UFS1 filesystems. New filesystems built using newfs can be built in either UFS1 or UFS2 format using the -O option. In this commit UFS1 is the default format, so if you want to build UFS2 format filesystems, you must specify -O 2. This default will be changed to UFS2 when UFS2 proves itself to be stable. In this commit the boot code for reading UFS2 filesystems is not compiled (see /sys/boot/common/ufsread.c) as there is insufficient space in the boot block. Once the size of the boot block is increased, this code can be defined. Things to note: the definition of SBSIZE has changed to SBLOCKSIZE. The header file <ufs/ufs/dinode.h> must be included before <ufs/ffs/fs.h> so as to get the definitions of ufs2_daddr_t and ufs_lbn_t. Still TODO: Verify that the first level bootstraps work for all the architectures. Convert the utility ffsinfo to understand UFS2 and test growfs. Add support for the extended attribute storage. Update soft updates to ensure integrity of extended attribute storage. Switch the current extended attribute interfaces to use the extended attribute storage. Add the extent like functionality (framework is there, but is currently never used). Sponsored by: DARPA & NAI Labs. Reviewed by: Poul-Henning Kamp <phk@freebsd.org>
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