aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libufs/Makefile5
-rw-r--r--lib/libufs/getinode.3131
-rw-r--r--lib/libufs/inode.c30
-rw-r--r--lib/libufs/libufs.h9
-rw-r--r--sbin/clri/clri.c11
-rw-r--r--sbin/ffsinfo/ffsinfo.c103
-rw-r--r--sbin/fsck_ffs/dir.c13
-rw-r--r--sbin/fsck_ffs/fsck.h2
-rw-r--r--sbin/fsck_ffs/gjournal.c32
-rw-r--r--sbin/fsck_ffs/inode.c21
-rw-r--r--sbin/fsck_ffs/main.c22
-rw-r--r--sbin/fsck_ffs/pass5.c5
-rw-r--r--sbin/fsirand/fsirand.c33
-rw-r--r--sbin/growfs/growfs.c44
-rw-r--r--sbin/newfs/mkfs.c17
-rw-r--r--sbin/tunefs/tunefs.c161
-rw-r--r--sys/ufs/ffs/ffs_extern.h2
-rw-r--r--sys/ufs/ffs/ffs_inode.c10
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c4
-rw-r--r--sys/ufs/ffs/ffs_softdep.c16
-rw-r--r--sys/ufs/ffs/ffs_subr.c42
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c20
-rw-r--r--tools/diag/prtblknos/main.c10
23 files changed, 448 insertions, 295 deletions
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index 16487bebc957..2685f7318ac1 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -3,12 +3,12 @@
PACKAGE=lib${LIB}
LIB= ufs
SHLIBDIR?= /lib
-SHLIB_MAJOR= 6
+SHLIB_MAJOR= 7
SRCS= block.c cgroup.c crc32.c inode.c sblock.c type.c ffs_subr.c ffs_tables.c
INCS= libufs.h
-MAN= bread.3 cgread.3 libufs.3 sbread.3 ufs_disk_close.3
+MAN= bread.3 cgread.3 getinode.3 libufs.3 sbread.3 ufs_disk_close.3
MLINKS+= bread.3 bwrite.3
MLINKS+= bread.3 berase.3
MLINKS+= cgread.3 cgread1.3
@@ -16,6 +16,7 @@ MLINKS+= cgread.3 cgget.3
MLINKS+= cgread.3 cgwrite.3
MLINKS+= cgread.3 cgwrite1.3
MLINKS+= cgread.3 cgput.3
+MLINKS+= getinode.3 putinode.3
MLINKS+= sbread.3 sbwrite.3
MLINKS+= sbread.3 sbget.3
MLINKS+= sbread.3 sbput.3
diff --git a/lib/libufs/getinode.3 b/lib/libufs/getinode.3
new file mode 100644
index 000000000000..6aa5388cbd6d
--- /dev/null
+++ b/lib/libufs/getinode.3
@@ -0,0 +1,131 @@
+.\" Author: Marshall Kirk McKusick <mckusick@freebsd.org>
+.\" Date: January 19, 2018
+.\" Description:
+.\" Manual page for libufs functions:
+.\" getinode(3)
+.\" putinode(3)
+.\"
+.\" This file is in the public domain.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 10, 2018
+.Dt GETINODE 3
+.Os
+.Sh NAME
+.Nm getinode , putinode
+.Nd fetch and store inodes on a UFS file system
+.Sh LIBRARY
+.Lb libufs
+.Sh SYNOPSIS
+.In ufs/ufs/dinode.h
+.In ufs/ffs/fs.h
+.In libufs.h
+.Ft int
+.Fn getinode "struct uufsd *disk" "union dinodep *dp" "ino_t inumber"
+.Ft int
+.Fn putinode "struct uufsd *disk"
+.Sh DESCRIPTION
+The
+.Fn getinode
+and
+.Fn putinode
+functions provide an inode fetch and store API for
+.Xr libufs 3
+consumers.
+They operate on a userland UFS disk structure.
+The
+.Fn getinode
+function fetches the specified inode from the filesystem.
+The
+.Fn putinode
+function stores the most recently fetched inode to the filesystem.
+.Pp
+The
+.Va dinodep
+union is defined as:
+.Bd -literal -offset indent
+union dinodep {
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+};
+.Ed
+.Pp
+Sample code to clear write permissions for inode number
+.Fa inumber
+stored on the filesystem described by
+.Fa diskp .
+.Bd -literal -offset indent
+#include <sys/stat.h>
+#include <err.h>
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#include <libufs.h>
+
+void
+clearwrite(struct uufsd *diskp, ino_t inumber)
+{
+ union dinodep dp;
+
+ if (getinode(diskp, &dp, inumber) == -1)
+ err(1, "getinode: %s", diskp->d_error);
+ switch (diskp->d_ufs) {
+ case 1: /* UFS 1 filesystem */
+ dp.dp1->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ break;
+ case 2: /* UFS 2 filesystem */
+ dp.dp2->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ break;
+ default:
+ errx(1, "unknown filesystem type");
+ }
+ if (putinode(diskp) == -1)
+ err(1, "putinode: %s", diskp->d_error);
+}
+.Ed
+.Sh RETURN VALUES
+The
+.Fn getinode
+and
+.Fn putinode
+functions return 0 on success, or \-1 in case of any error.
+A string describing the error is stored in
+.Fa diskp->d_error .
+The global
+.Fa errno
+often provides additional information.
+.Sh ERRORS
+The function
+.Fn getinode
+may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr pread 2 .
+It can also fail if the inode number is out of the range of inodes
+in the filesystem.
+.Pp
+The function
+.Fn putinode
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr ufs_disk_write 3
+or
+.Xr pwrite 2 .
+.Pp
+Additionally both functions may follow the
+.Xr libufs 3
+error methodologies in case of a device error.
+.Sh SEE ALSO
+.Xr pread 2 ,
+.Xr pwrite 2 ,
+.Xr libufs 3 ,
+.Xr ufs_disk_write 3
+.Sh HISTORY
+These functions first appeared as part of
+.Xr libufs 3
+in
+.Fx 13.0 .
+.Sh AUTHORS
+.An Marshall Kirk McKusick Aq Mt mckusick@freebsd.org
diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c
index 83a6cf0e36c7..11e263f08ad5 100644
--- a/lib/libufs/inode.c
+++ b/lib/libufs/inode.c
@@ -49,18 +49,16 @@ __FBSDID("$FreeBSD$");
#include <libufs.h>
int
-getino(struct uufsd *disk, void **dino, ino_t inode, int *mode)
+getinode(struct uufsd *disk, union dinodep *dp, ino_t inum)
{
ino_t min, max;
caddr_t inoblock;
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
struct fs *fs;
ERROR(disk, NULL);
fs = &disk->d_fs;
- if (inode >= (ino_t)fs->fs_ipg * fs->fs_ncg) {
+ if (inum >= (ino_t)fs->fs_ipg * fs->fs_ncg) {
ERROR(disk, "inode number out of range");
return (-1);
}
@@ -76,26 +74,22 @@ getino(struct uufsd *disk, void **dino, ino_t inode, int *mode)
}
disk->d_inoblock = inoblock;
}
- if (inode >= min && inode < max)
+ if (inum >= min && inum < max)
goto gotit;
- bread(disk, fsbtodb(fs, ino_to_fsba(fs, inode)), inoblock,
+ bread(disk, fsbtodb(fs, ino_to_fsba(fs, inum)), inoblock,
fs->fs_bsize);
- disk->d_inomin = min = inode - (inode % INOPB(fs));
+ disk->d_inomin = min = inum - (inum % INOPB(fs));
disk->d_inomax = max = min + INOPB(fs);
gotit: switch (disk->d_ufs) {
case 1:
- dp1 = &((struct ufs1_dinode *)inoblock)[inode - min];
- if (mode != NULL)
- *mode = dp1->di_mode & IFMT;
- if (dino != NULL)
- *dino = dp1;
+ disk->d_dp.dp1 = &((struct ufs1_dinode *)inoblock)[inum - min];
+ if (dp != NULL)
+ *dp = disk->d_dp;
return (0);
case 2:
- dp2 = &((struct ufs2_dinode *)inoblock)[inode - min];
- if (mode != NULL)
- *mode = dp2->di_mode & IFMT;
- if (dino != NULL)
- *dino = dp2;
+ disk->d_dp.dp2 = &((struct ufs2_dinode *)inoblock)[inum - min];
+ if (dp != NULL)
+ *dp = disk->d_dp;
return (0);
default:
break;
@@ -105,7 +99,7 @@ gotit: switch (disk->d_ufs) {
}
int
-putino(struct uufsd *disk)
+putinode(struct uufsd *disk)
{
struct fs *fs;
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index 4598a9999ce2..dbd378949877 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -35,6 +35,10 @@
/*
* libufs structures.
*/
+union dinodep {
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+};
/*
* userland ufs disk.
@@ -49,6 +53,7 @@ struct uufsd {
caddr_t d_inoblock; /* inode block */
uint32_t d_inomin; /* low inode (not ino_t for ABI compat) */
uint32_t d_inomax; /* high inode (not ino_t for ABI compat) */
+ union dinodep d_dp; /* pointer to currently active inode */
union {
struct fs d_fs; /* filesystem information */
char d_sb[MAXBSIZE];
@@ -135,8 +140,8 @@ int cgwrite1(struct uufsd *, int);
/*
* inode.c
*/
-int getino(struct uufsd *, void **, ino_t, int *);
-int putino(struct uufsd *);
+int getinode(struct uufsd *, union dinodep *, ino_t);
+int putinode(struct uufsd *);
/*
* sblock.c
diff --git a/sbin/clri/clri.c b/sbin/clri/clri.c
index 0c0f8f0947a3..7f9a4f09bfe0 100644
--- a/sbin/clri/clri.c
+++ b/sbin/clri/clri.c
@@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <unistd.h>
-union dinodep {
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
-};
-
static void
usage(void)
{
@@ -104,8 +99,8 @@ main(int argc, char *argv[])
}
(void)printf("clearing %d\n", inonum);
- if (getino(&disk, (void **)&dp, inonum, NULL) == -1) {
- printf("getino: %s\n", disk.d_error);
+ if (getinode(&disk, &dp, inonum) == -1) {
+ printf("getinode: %s\n", disk.d_error);
exitval = 1;
continue;
}
@@ -119,7 +114,7 @@ main(int argc, char *argv[])
memset(dp.dp2, 0, sizeof(*dp.dp2));
dp.dp2->di_gen = generation;
}
- putino(&disk);
+ putinode(&disk);
(void)fsync(disk.d_fd);
}
(void)ufs_disk_close(&disk);
diff --git a/sbin/ffsinfo/ffsinfo.c b/sbin/ffsinfo/ffsinfo.c
index 5e08d35e5d91..9bd3210986a9 100644
--- a/sbin/ffsinfo/ffsinfo.c
+++ b/sbin/ffsinfo/ffsinfo.c
@@ -262,7 +262,7 @@ main(int argc, char **argv)
dbg_csp = fscs;
/* ... and dump it */
- for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) {
+ for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) {
snprintf(dbg_line, sizeof(dbg_line),
"%d. csum in fscs", dbg_csc);
DBG_DUMP_CSUM(&sblock,
@@ -342,8 +342,8 @@ void
dump_whole_ufs1_inode(ino_t inode, int level)
{
DBG_FUNC("dump_whole_ufs1_inode")
- struct ufs1_dinode *ino;
- int rb, mode;
+ union dinodep dp;
+ int rb;
unsigned int ind2ctr, ind3ctr;
ufs1_daddr_t *ind2ptr, *ind3ptr;
char comment[80];
@@ -353,10 +353,10 @@ dump_whole_ufs1_inode(ino_t inode, int level)
/*
* Read the inode from disk/cache.
*/
- if (getino(&disk, (void **)&ino, inode, &mode) == -1)
- err(1, "getino: %s", disk.d_error);
+ if (getinode(&disk, &dp, inode) == -1)
+ err(1, "getinode: %s", disk.d_error);
- if(ino->di_nlink==0) {
+ if (dp.dp1->di_nlink == 0) {
DBG_LEAVE;
return; /* inode not in use */
}
@@ -368,7 +368,7 @@ dump_whole_ufs1_inode(ino_t inode, int level)
if (level & 0x100) {
DBG_DUMP_INO(&sblock,
comment,
- ino);
+ dp.dp1);
}
if (!(level & 0x200)) {
@@ -379,13 +379,13 @@ dump_whole_ufs1_inode(ino_t inode, int level)
/*
* Ok, now prepare for dumping all direct and indirect pointers.
*/
- rb = howmany(ino->di_size, sblock.fs_bsize) - UFS_NDADDR;
- if(rb>0) {
+ rb = howmany(dp.dp1->di_size, sblock.fs_bsize) - UFS_NDADDR;
+ if (rb > 0) {
/*
* Dump single indirect block.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[0]), (void *)&i1blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[0]),
+ (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0",
@@ -394,14 +394,14 @@ dump_whole_ufs1_inode(ino_t inode, int level)
comment,
i1blk,
(size_t)rb);
- rb-=howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t));
+ rb -= howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t));
}
- if(rb>0) {
+ if (rb > 0) {
/*
* Dump double indirect blocks.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[1]), (void *)&i2blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[1]),
+ (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1",
@@ -410,12 +410,12 @@ dump_whole_ufs1_inode(ino_t inode, int level)
comment,
i2blk,
howmany(rb, howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t))));
- for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
- sizeof(ufs1_daddr_t))) && (rb>0)); ind2ctr++) {
- ind2ptr=&((ufs1_daddr_t *)(void *)&i2blk)[ind2ctr];
+ for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize,
+ sizeof(ufs1_daddr_t))) && (rb > 0)); ind2ctr++) {
+ ind2ptr = &((ufs1_daddr_t *)(void *)&i2blk)[ind2ctr];
- if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, *ind2ptr),
+ (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment),
@@ -425,15 +425,15 @@ dump_whole_ufs1_inode(ino_t inode, int level)
comment,
i1blk,
(size_t)rb);
- rb-=howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t));
+ rb -= howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t));
}
}
- if(rb>0) {
+ if (rb > 0) {
/*
* Dump triple indirect blocks.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[2]), (void *)&i3blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[2]),
+ (void *)&i3blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2",
@@ -445,12 +445,12 @@ dump_whole_ufs1_inode(ino_t inode, int level)
howmany(rb,
SQUARE(howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)))));
#undef SQUARE
- for(ind3ctr=0; ((ind3ctr<howmany(sblock.fs_bsize,
- sizeof(ufs1_daddr_t)))&&(rb>0)); ind3ctr++) {
- ind3ptr=&((ufs1_daddr_t *)(void *)&i3blk)[ind3ctr];
+ for (ind3ctr = 0; ((ind3ctr < howmany(sblock.fs_bsize,
+ sizeof(ufs1_daddr_t))) && (rb > 0)); ind3ctr++) {
+ ind3ptr = &((ufs1_daddr_t *)(void *)&i3blk)[ind3ctr];
- if (bread(&disk, fsbtodb(&sblock, *ind3ptr), (void *)&i2blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, *ind3ptr),
+ (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment),
@@ -461,8 +461,8 @@ dump_whole_ufs1_inode(ino_t inode, int level)
i2blk,
howmany(rb,
howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t))));
- for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
- sizeof(ufs1_daddr_t)))&&(rb>0)); ind2ctr++) {
+ for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize,
+ sizeof(ufs1_daddr_t))) && (rb > 0)); ind2ctr++) {
ind2ptr=&((ufs1_daddr_t *)(void *)&i2blk)
[ind2ctr];
if (bread(&disk, fsbtodb(&sblock, *ind2ptr),
@@ -477,7 +477,7 @@ dump_whole_ufs1_inode(ino_t inode, int level)
comment,
i1blk,
(size_t)rb);
- rb-=howmany(sblock.fs_bsize,
+ rb -= howmany(sblock.fs_bsize,
sizeof(ufs1_daddr_t));
}
}
@@ -496,8 +496,8 @@ void
dump_whole_ufs2_inode(ino_t inode, int level)
{
DBG_FUNC("dump_whole_ufs2_inode")
- struct ufs2_dinode *ino;
- int rb, mode;
+ union dinodep dp;
+ int rb;
unsigned int ind2ctr, ind3ctr;
ufs2_daddr_t *ind2ptr, *ind3ptr;
char comment[80];
@@ -507,10 +507,10 @@ dump_whole_ufs2_inode(ino_t inode, int level)
/*
* Read the inode from disk/cache.
*/
- if (getino(&disk, (void **)&ino, inode, &mode) == -1)
- err(1, "getino: %s", disk.d_error);
+ if (getinode(&disk, &dp, inode) == -1)
+ err(1, "getinode: %s", disk.d_error);
- if (ino->di_nlink == 0) {
+ if (dp.dp2->di_nlink == 0) {
DBG_LEAVE;
return; /* inode not in use */
}
@@ -520,7 +520,7 @@ dump_whole_ufs2_inode(ino_t inode, int level)
*/
snprintf(comment, sizeof(comment), "Inode 0x%08jx", (uintmax_t)inode);
if (level & 0x100) {
- DBG_DUMP_INO(&sblock, comment, ino);
+ DBG_DUMP_INO(&sblock, comment, dp.dp2);
}
if (!(level & 0x200)) {
@@ -531,13 +531,13 @@ dump_whole_ufs2_inode(ino_t inode, int level)
/*
* Ok, now prepare for dumping all direct and indirect pointers.
*/
- rb = howmany(ino->di_size, sblock.fs_bsize) - UFS_NDADDR;
+ rb = howmany(dp.dp2->di_size, sblock.fs_bsize) - UFS_NDADDR;
if (rb > 0) {
/*
* Dump single indirect block.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[0]), (void *)&i1blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[0]),
+ (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0",
@@ -549,8 +549,8 @@ dump_whole_ufs2_inode(ino_t inode, int level)
/*
* Dump double indirect blocks.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[1]), (void *)&i2blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[1]),
+ (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1",
@@ -563,8 +563,8 @@ dump_whole_ufs2_inode(ino_t inode, int level)
sizeof(ufs2_daddr_t))) && (rb>0)); ind2ctr++) {
ind2ptr = &((ufs2_daddr_t *)(void *)&i2blk)[ind2ctr];
- if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, *ind2ptr),
+ (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment),
@@ -578,8 +578,8 @@ dump_whole_ufs2_inode(ino_t inode, int level)
/*
* Dump triple indirect blocks.
*/
- if (bread(&disk, fsbtodb(&sblock, ino->di_ib[2]), (void *)&i3blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[2]),
+ (void *)&i3blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2",
@@ -595,8 +595,8 @@ dump_whole_ufs2_inode(ino_t inode, int level)
sizeof(ufs2_daddr_t))) && (rb > 0)); ind3ctr++) {
ind3ptr = &((ufs2_daddr_t *)(void *)&i3blk)[ind3ctr];
- if (bread(&disk, fsbtodb(&sblock, *ind3ptr), (void *)&i2blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, *ind3ptr),
+ (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment),
@@ -610,8 +610,9 @@ dump_whole_ufs2_inode(ino_t inode, int level)
for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize,
sizeof(ufs2_daddr_t))) && (rb > 0)); ind2ctr++) {
ind2ptr = &((ufs2_daddr_t *)(void *)&i2blk) [ind2ctr];
- if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk,
- (size_t)sblock.fs_bsize) == -1) {
+ if (bread(&disk, fsbtodb(&sblock, *ind2ptr),
+ (void *)&i1blk, (size_t)sblock.fs_bsize)
+ == -1) {
err(1, "bread: %s", disk.d_error);
}
snprintf(comment, sizeof(comment),
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index a590ee74227b..e923714c3c72 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -254,14 +254,14 @@ fileerror(ino_t cwd, ino_t ino, const char *errmesg)
char pathbuf[MAXPATHLEN + 1];
pwarn("%s ", errmesg);
- pinode(ino);
- printf("\n");
- getpathname(pathbuf, cwd, ino);
if (ino < UFS_ROOTINO || ino > maxino) {
- pfatal("NAME=%s\n", pathbuf);
+ pfatal("out-of-range inode number %ju", (uintmax_t)ino);
return;
}
dp = ginode(ino);
+ prtinode(ino, dp);
+ printf("\n");
+ getpathname(pathbuf, cwd, ino);
if (ftypeok(dp))
pfatal("%s=%s\n",
(DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE",
@@ -309,7 +309,7 @@ adjust(struct inodesc *idesc, int lcnt)
if (lcnt != 0) {
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
((DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"));
- pinode(idesc->id_number);
+ prtinode(idesc->id_number, dp);
printf(" COUNT %d SHOULD BE %d",
DIP(dp, di_nlink), DIP(dp, di_nlink) - lcnt);
if (preen || usedsoftdep) {
@@ -390,7 +390,8 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
dp = ginode(orphan);
lostdir = (DIP(dp, di_mode) & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
- pinode(orphan);
+ prtinode(orphan, dp);
+ printf("\n");
if (preen && DIP(dp, di_size) == 0)
return (0);
if (cursnapshot != 0) {
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index cfac25bdfe3d..ffe41be6cf3b 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -463,8 +463,8 @@ void pass4(void);
int pass4check(struct inodesc *);
void pass5(void);
void pfatal(const char *fmt, ...) __printflike(1, 2);
-void pinode(ino_t ino);
void propagate(void);
+void prtinode(ino_t ino, union dinode *dp);
void pwarn(const char *fmt, ...) __printflike(1, 2);
int readsb(int listerr);
int reply(const char *question);
diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c
index 79f670c00567..17361f78a058 100644
--- a/sbin/fsck_ffs/gjournal.c
+++ b/sbin/fsck_ffs/gjournal.c
@@ -392,13 +392,12 @@ clear_inode(struct ufs2_dinode *dino)
void
gjournal_check(const char *filesys)
{
- struct ufs2_dinode *dino;
- void *p;
+ union dinodep dp;
struct cgchain *cgc;
struct cg *cgp;
uint8_t *inosused;
ino_t cino, ino;
- int cg, mode;
+ int cg;
devnam = filesys;
opendisk();
@@ -444,19 +443,20 @@ gjournal_check(const char *filesys)
/* Unallocated? Skip it. */
if (isclr(inosused, cino))
continue;
- if (getino(diskp, &p, ino, &mode) == -1)
- err(1, "getino(cg=%d ino=%ju)",
- cg, (uintmax_t)ino);
- dino = p;
+ if (getinode(diskp, &dp, ino) == -1)
+ err(1, "getinode (cg=%d ino=%ju) %s",
+ cg, (uintmax_t)ino, diskp->d_error);
/* Not a regular file nor directory? Skip it. */
- if (!S_ISREG(dino->di_mode) && !S_ISDIR(dino->di_mode))
+ if (!S_ISREG(dp.dp2->di_mode) &&
+ !S_ISDIR(dp.dp2->di_mode))
continue;
/* Has reference(s)? Skip it. */
- if (dino->di_nlink > 0)
+ if (dp.dp2->di_nlink > 0)
continue;
- //printf("Clearing inode=%d (size=%jd)\n", ino, (intmax_t)dino->di_size);
+ /* printf("Clearing inode=%d (size=%jd)\n", ino,
+ (intmax_t)dp.dp2->di_size); */
/* Free inode's blocks. */
- clear_inode(dino);
+ clear_inode(dp.dp2);
/* Deallocate it. */
clrbit(inosused, cino);
/* Update position of last used inode. */
@@ -469,17 +469,17 @@ gjournal_check(const char *filesys)
cgp->cg_unrefs--;
fs->fs_unrefs--;
/* If this is directory, update related statistics. */
- if (S_ISDIR(dino->di_mode)) {
+ if (S_ISDIR(dp.dp2->di_mode)) {
cgp->cg_cs.cs_ndir--;
fs->fs_cs(fs, cg).cs_ndir--;
fs->fs_cstotal.cs_ndir--;
}
/* Zero-fill the inode. */
- *dino = ufs2_zino;
+ *dp.dp2 = ufs2_zino;
/* Write the inode back. */
- if (putino(diskp) == -1)
- err(1, "putino(cg=%d ino=%ju)",
- cg, (uintmax_t)ino);
+ if (putinode(diskp) == -1)
+ err(1, "putinode (cg=%d ino=%ju) %s",
+ cg, (uintmax_t)ino, diskp->d_error);
if (cgp->cg_unrefs == 0) {
//printf("No more unreferenced inodes in cg=%d.\n", cg);
break;
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 7cce44953a69..3f1cab8b3bd5 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <pwd.h>
#include <string.h>
#include <time.h>
+#include <libufs.h>
#include "fsck.h"
@@ -342,7 +343,11 @@ getnextinode(ino_t inumber, int rebuildcg)
nextinop = inobuf.b_un.b_buf;
}
dp = (union dinode *)nextinop;
- if (rebuildcg && nextinop == inobuf.b_un.b_buf) {
+ if (sblock.fs_magic == FS_UFS1_MAGIC)
+ nextinop += sizeof(struct ufs1_dinode);
+ else
+ nextinop += sizeof(struct ufs2_dinode);
+ if (rebuildcg && (char *)dp == inobuf.b_un.b_buf) {
/*
* Try to determine if we have reached the end of the
* allocated inodes.
@@ -355,7 +360,7 @@ getnextinode(ino_t inumber, int rebuildcg)
UFS_NIADDR * sizeof(ufs2_daddr_t)) ||
dp->dp2.di_mode || dp->dp2.di_size)
return (NULL);
- goto inodegood;
+ return (dp);
}
if (!ftypeok(dp))
return (NULL);
@@ -389,11 +394,6 @@ getnextinode(ino_t inumber, int rebuildcg)
if (DIP(dp, di_ib[j]) != 0)
return (NULL);
}
-inodegood:
- if (sblock.fs_magic == FS_UFS1_MAGIC)
- nextinop += sizeof(struct ufs1_dinode);
- else
- nextinop += sizeof(struct ufs2_dinode);
return (dp);
}
@@ -534,7 +534,8 @@ clri(struct inodesc *idesc, const char *type, int flag)
if (flag == 1) {
pwarn("%s %s", type,
(DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE");
- pinode(idesc->id_number);
+ prtinode(idesc->id_number, dp);
+ printf("\n");
}
if (preen || reply("CLEAR") == 1) {
if (preen)
@@ -600,9 +601,8 @@ clearentry(struct inodesc *idesc)
}
void
-pinode(ino_t ino)
+prtinode(ino_t ino, union dinode *dp)
{
- union dinode *dp;
char *p;
struct passwd *pw;
time_t t;
@@ -610,7 +610,6 @@ pinode(ino_t ino)
printf(" I=%lu ", (u_long)ino);
if (ino < UFS_ROOTINO || ino > maxino)
return;
- dp = ginode(ino);
printf(" OWNER=");
if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL)
printf("%s ", pw->pw_name);
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index e5118619475b..ce4d0a89a36a 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -458,30 +458,40 @@ checkfilesys(char *filesys)
if (preen == 0 && yflag == 0 && sblock.fs_magic != FS_UFS1_MAGIC &&
fswritefd != -1 && getosreldate() >= P_OSREL_CK_CYLGRP) {
if ((sblock.fs_metackhash & CK_CYLGRP) == 0 &&
- reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0)
+ reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_CYLGRP;
+ sblock.fs_metackhash |= CK_CYLGRP;
+ }
if ((sblock.fs_metackhash & CK_SUPERBLOCK) == 0 &&
getosreldate() >= P_OSREL_CK_SUPERBLOCK &&
reply("ADD SUPERBLOCK CHECK-HASH PROTECTION") != 0) {
+ ckhashadd |= CK_SUPERBLOCK;
sblock.fs_metackhash |= CK_SUPERBLOCK;
- sbdirty();
}
#ifdef notyet
if ((sblock.fs_metackhash & CK_INODE) == 0 &&
getosreldate() >= P_OSREL_CK_INODE &&
- reply("ADD INODE CHECK-HASH PROTECTION") != 0)
+ reply("ADD INODE CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_INODE;
+ sblock.fs_metackhash |= CK_INODE;
+ }
if ((sblock.fs_metackhash & CK_INDIR) == 0 &&
getosreldate() >= P_OSREL_CK_INDIR &&
- reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0)
+ reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_INDIR;
+ sblock.fs_metackhash |= CK_INDIR;
+ }
if ((sblock.fs_metackhash & CK_DIR) == 0 &&
getosreldate() >= P_OSREL_CK_DIR &&
- reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0)
+ reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_DIR;
+ sblock.fs_metackhash |= CK_DIR;
+ }
#endif /* notyet */
- if (ckhashadd != 0)
+ if (ckhashadd != 0) {
sblock.fs_flags |= FS_METACKHASH;
+ sbdirty();
+ }
}
/*
* Cleared if any questions answered no. Used to decide if
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 71e3eda74c1b..436d184c327b 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -74,11 +74,8 @@ pass5(void)
memset(newcg, 0, (size_t)fs->fs_cgsize);
newcg->cg_niblk = fs->fs_ipg;
/* check to see if we are to add a cylinder group check hash */
- if ((ckhashadd & CK_CYLGRP) != 0) {
- fs->fs_metackhash |= CK_CYLGRP;
+ if ((ckhashadd & CK_CYLGRP) != 0)
rewritecg = 1;
- sbdirty();
- }
if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen)
diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c
index bb0f27a59301..f5e26571f903 100644
--- a/sbin/fsirand/fsirand.c
+++ b/sbin/fsirand/fsirand.c
@@ -175,7 +175,7 @@ fsirand(char *device)
}
/* For each cylinder group, randomize inodes and update backup sblock */
- for (cg = 0, inumber = 0; cg < (int)sblock->fs_ncg; cg++) {
+ for (cg = 0, inumber = UFS_ROOTINO; cg < (int)sblock->fs_ncg; cg++) {
/* Read in inodes, then print or randomize generation nums */
dblk = fsbtodb(sblock, ino_to_fsba(sblock, inumber));
if (lseek(devfd, (off_t)dblk * bsize, SEEK_SET) < 0) {
@@ -187,21 +187,22 @@ fsirand(char *device)
return (1);
}
- for (n = 0; n < (int)sblock->fs_ipg; n++, inumber++) {
- if (sblock->fs_magic == FS_UFS1_MAGIC)
- dp1 = &((struct ufs1_dinode *)inodebuf)[n];
- else
- dp2 = &((struct ufs2_dinode *)inodebuf)[n];
- if (inumber >= UFS_ROOTINO) {
- if (printonly)
- (void)printf("ino %ju gen %08x\n",
- (uintmax_t)inumber,
- sblock->fs_magic == FS_UFS1_MAGIC ?
- dp1->di_gen : dp2->di_gen);
- else if (sblock->fs_magic == FS_UFS1_MAGIC)
- dp1->di_gen = random();
- else
- dp2->di_gen = random();
+ dp1 = (struct ufs1_dinode *)(void *)inodebuf;
+ dp2 = (struct ufs2_dinode *)(void *)inodebuf;
+ for (n = cg > 0 ? 0 : UFS_ROOTINO;
+ n < (int)sblock->fs_ipg;
+ n++, inumber++) {
+ if (printonly) {
+ (void)printf("ino %ju gen %08x\n",
+ (uintmax_t)inumber,
+ sblock->fs_magic == FS_UFS1_MAGIC ?
+ dp1->di_gen : dp2->di_gen);
+ } else if (sblock->fs_magic == FS_UFS1_MAGIC) {
+ dp1->di_gen = arc4random();
+ dp1++;
+ } else {
+ dp2->di_gen = arc4random();
+ dp2++;
}
}
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 61f90de7ea68..b75f377841ef 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -301,16 +301,21 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
{
DBG_FUNC("initcg")
static caddr_t iobuf;
+ static long iobufsize;
long blkno, start;
ino_t ino;
ufs2_daddr_t i, cbase, dmax;
struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
struct csum *cs;
uint j, d, dupper, dlower;
- if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize * 3)) == NULL)
- errx(37, "panic: cannot allocate I/O buffer");
-
+ if (iobuf == NULL) {
+ iobufsize = 2 * sblock.fs_bsize;
+ if ((iobuf = malloc(iobufsize)) == NULL)
+ errx(37, "panic: cannot allocate I/O buffer");
+ memset(iobuf, '\0', iobufsize);
+ }
/*
* Determine block bounds for cylinder group.
* Allow space for super block summary information in first
@@ -375,12 +380,29 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
acg.cg_cs.cs_nifree--;
}
/*
+ * Initialize the initial inode blocks.
+ */
+ dp1 = (struct ufs1_dinode *)(void *)iobuf;
+ dp2 = (struct ufs2_dinode *)(void *)iobuf;
+ for (i = 0; i < acg.cg_initediblk; i++) {
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ dp1->di_gen = arc4random();
+ dp1++;
+ } else {
+ dp2->di_gen = arc4random();
+ dp2++;
+ }
+ }
+ wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), iobufsize, iobuf,
+ fso, Nflag);
+ /*
* For the old file system, we have to initialize all the inodes.
*/
- if (sblock.fs_magic == FS_UFS1_MAGIC) {
- bzero(iobuf, sblock.fs_bsize);
- for (i = 0; i < sblock.fs_ipg / INOPF(&sblock);
- i += sblock.fs_frag) {
+ if (sblock.fs_magic == FS_UFS1_MAGIC &&
+ sblock.fs_ipg > 2 * INOPB(&sblock)) {
+ for (i = 2 * sblock.fs_frag;
+ i < sblock.fs_ipg / INOPF(&sblock);
+ i += sblock.fs_frag) {
dp1 = (struct ufs1_dinode *)(void *)iobuf;
for (j = 0; j < INOPB(&sblock); j++) {
dp1->di_gen = arc4random();
@@ -463,12 +485,8 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
*cs = acg.cg_cs;
cgckhash(&acg);
- memcpy(iobuf, &acg, sblock.fs_cgsize);
- memset(iobuf + sblock.fs_cgsize, '\0',
- sblock.fs_bsize * 3 - sblock.fs_cgsize);
-
- wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
- sblock.fs_bsize * 3, iobuf, fso, Nflag);
+ wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, &acg,
+ fso, Nflag);
DBG_DUMP_CG(&sblock, "new cg", &acg);
DBG_LEAVE;
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index 74a0f9511a85..2bea89cf2bc9 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -1029,7 +1029,7 @@ goth:
void
iput(union dinode *ip, ino_t ino)
{
- ufs2_daddr_t d;
+ union dinodep dp;
bread(&disk, part_ofs + fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg,
sblock.fs_cgsize);
@@ -1043,20 +1043,15 @@ iput(union dinode *ip, ino_t ino)
err(1, "iput: cgput: %s", disk.d_error);
sblock.fs_cstotal.cs_nifree--;
fscs[0].cs_nifree--;
- if (ino >= (unsigned long)sblock.fs_ipg * sblock.fs_ncg) {
- printf("fsinit: inode value out of range (%ju).\n",
- (uintmax_t)ino);
+ if (getinode(&disk, &dp, ino) == -1) {
+ printf("iput: %s\n", disk.d_error);
exit(32);
}
- d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino));
- bread(&disk, part_ofs + d, (char *)iobuf, sblock.fs_bsize);
if (sblock.fs_magic == FS_UFS1_MAGIC)
- ((struct ufs1_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] =
- ip->dp1;
+ *dp.dp1 = ip->dp1;
else
- ((struct ufs2_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] =
- ip->dp2;
- wtfs(d, sblock.fs_bsize, (char *)iobuf);
+ *dp.dp2 = ip->dp2;
+ putinode(&disk);
}
/*
diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c
index ef27b60f6bef..6a6b7f767ede 100644
--- a/sbin/tunefs/tunefs.c
+++ b/sbin/tunefs/tunefs.c
@@ -679,41 +679,36 @@ dir_search(ufs2_daddr_t blk, int bytes)
static ino_t
journal_findfile(void)
{
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
+ union dinodep dp;
ino_t ino;
- int mode;
- void *ip;
int i;
- if (getino(&disk, &ip, UFS_ROOTINO, &mode) != 0) {
- warn("Failed to get root inode");
+ if (getinode(&disk, &dp, UFS_ROOTINO) != 0) {
+ warn("Failed to get root inode: %s", disk.d_error);
return (-1);
}
- dp2 = ip;
- dp1 = ip;
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- if ((off_t)dp1->di_size >= lblktosize(&sblock, UFS_NDADDR)) {
+ if ((off_t)dp.dp1->di_size >= lblktosize(&sblock, UFS_NDADDR)) {
warnx("UFS_ROOTINO extends beyond direct blocks.");
return (-1);
}
for (i = 0; i < UFS_NDADDR; i++) {
- if (dp1->di_db[i] == 0)
+ if (dp.dp1->di_db[i] == 0)
break;
- if ((ino = dir_search(dp1->di_db[i],
- sblksize(&sblock, (off_t)dp1->di_size, i))) != 0)
+ if ((ino = dir_search(dp.dp1->di_db[i],
+ sblksize(&sblock, (off_t)dp.dp1->di_size, i))) != 0)
return (ino);
}
} else {
- if ((off_t)dp2->di_size >= lblktosize(&sblock, UFS_NDADDR)) {
+ if ((off_t)dp.dp2->di_size >= lblktosize(&sblock, UFS_NDADDR)) {
warnx("UFS_ROOTINO extends beyond direct blocks.");
return (-1);
}
for (i = 0; i < UFS_NDADDR; i++) {
- if (dp2->di_db[i] == 0)
+ if (dp.dp2->di_db[i] == 0)
break;
- if ((ino = dir_search(dp2->di_db[i],
- sblksize(&sblock, (off_t)dp2->di_size, i))) != 0)
+ if ((ino = dir_search(dp.dp2->di_db[i],
+ sblksize(&sblock, (off_t)dp.dp2->di_size, i))) != 0)
return (ino);
}
}
@@ -795,23 +790,18 @@ dir_extend(ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino)
static int
journal_insertfile(ino_t ino)
{
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
- void *ip;
+ union dinodep dp;
ufs2_daddr_t nblk;
ufs2_daddr_t blk;
ufs_lbn_t lbn;
int size;
- int mode;
int off;
- if (getino(&disk, &ip, UFS_ROOTINO, &mode) != 0) {
- warn("Failed to get root inode");
+ if (getinode(&disk, &dp, UFS_ROOTINO) != 0) {
+ warn("Failed to get root inode: %s", disk.d_error);
sbdirty();
return (-1);
}
- dp2 = ip;
- dp1 = ip;
blk = 0;
size = 0;
nblk = journal_balloc();
@@ -824,15 +814,15 @@ journal_insertfile(ino_t ino)
* have to free them and extend the block.
*/
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- lbn = lblkno(&sblock, dp1->di_size);
- off = blkoff(&sblock, dp1->di_size);
- blk = dp1->di_db[lbn];
- size = sblksize(&sblock, (off_t)dp1->di_size, lbn);
+ lbn = lblkno(&sblock, dp.dp1->di_size);
+ off = blkoff(&sblock, dp.dp1->di_size);
+ blk = dp.dp1->di_db[lbn];
+ size = sblksize(&sblock, (off_t)dp.dp1->di_size, lbn);
} else {
- lbn = lblkno(&sblock, dp2->di_size);
- off = blkoff(&sblock, dp2->di_size);
- blk = dp2->di_db[lbn];
- size = sblksize(&sblock, (off_t)dp2->di_size, lbn);
+ lbn = lblkno(&sblock, dp.dp2->di_size);
+ off = blkoff(&sblock, dp.dp2->di_size);
+ blk = dp.dp2->di_db[lbn];
+ size = sblksize(&sblock, (off_t)dp.dp2->di_size, lbn);
}
if (off != 0) {
if (dir_extend(blk, nblk, off, ino) == -1)
@@ -843,16 +833,16 @@ journal_insertfile(ino_t ino)
return (-1);
}
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
- dp1->di_db[lbn] = nblk;
- dp1->di_size = lblktosize(&sblock, lbn+1);
+ dp.dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
+ dp.dp1->di_db[lbn] = nblk;
+ dp.dp1->di_size = lblktosize(&sblock, lbn+1);
} else {
- dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
- dp2->di_db[lbn] = nblk;
- dp2->di_size = lblktosize(&sblock, lbn+1);
+ dp.dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE;
+ dp.dp2->di_db[lbn] = nblk;
+ dp.dp2->di_size = lblktosize(&sblock, lbn+1);
}
- if (putino(&disk) < 0) {
- warn("Failed to write root inode");
+ if (putinode(&disk) < 0) {
+ warn("Failed to write root inode: %s", disk.d_error);
return (-1);
}
if (cgwrite(&disk) < 0) {
@@ -916,11 +906,8 @@ indir_fill(ufs2_daddr_t blk, int level, int *resid)
static void
journal_clear(void)
{
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
+ union dinodep dp;
ino_t ino;
- int mode;
- void *ip;
ino = journal_findfile();
if (ino == (ino_t)-1 || ino == 0) {
@@ -928,18 +915,16 @@ journal_clear(void)
return;
}
printf("Clearing journal flags from inode %ju\n", (uintmax_t)ino);
- if (getino(&disk, &ip, ino, &mode) != 0) {
- warn("Failed to get journal inode");
+ if (getinode(&disk, &dp, ino) != 0) {
+ warn("Failed to get journal inode: %s", disk.d_error);
return;
}
- dp2 = ip;
- dp1 = ip;
if (sblock.fs_magic == FS_UFS1_MAGIC)
- dp1->di_flags = 0;
+ dp.dp1->di_flags = 0;
else
- dp2->di_flags = 0;
- if (putino(&disk) < 0) {
- warn("Failed to write journal inode");
+ dp.dp2->di_flags = 0;
+ if (putinode(&disk) < 0) {
+ warn("Failed to write journal inode: %s", disk.d_error);
return;
}
}
@@ -947,15 +932,12 @@ journal_clear(void)
static int
journal_alloc(int64_t size)
{
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
+ union dinodep dp;
ufs2_daddr_t blk;
- void *ip;
struct cg *cgp;
int resid;
ino_t ino;
int blks;
- int mode;
time_t utime;
int i;
@@ -1007,8 +989,8 @@ journal_alloc(int64_t size)
break;
printf("Using inode %ju in cg %d for %jd byte journal\n",
(uintmax_t)ino, cgp->cg_cgx, size);
- if (getino(&disk, &ip, ino, &mode) != 0) {
- warn("Failed to get allocated inode");
+ if (getinode(&disk, &dp, ino) != 0) {
+ warn("Failed to get allocated inode: %s", disk.d_error);
sbdirty();
goto out;
}
@@ -1017,39 +999,39 @@ journal_alloc(int64_t size)
* blocks and size uninitialized. This causes legacy
* fsck implementations to clear the inode.
*/
- dp2 = ip;
- dp1 = ip;
time(&utime);
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- bzero(dp1, sizeof(*dp1));
- dp1->di_size = size;
- dp1->di_mode = IFREG | IREAD;
- dp1->di_nlink = 1;
- dp1->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
- dp1->di_atime = utime;
- dp1->di_mtime = utime;
- dp1->di_ctime = utime;
+ bzero(dp.dp1, sizeof(*dp.dp1));
+ dp.dp1->di_size = size;
+ dp.dp1->di_mode = IFREG | IREAD;
+ dp.dp1->di_nlink = 1;
+ dp.dp1->di_flags =
+ SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
+ dp.dp1->di_atime = utime;
+ dp.dp1->di_mtime = utime;
+ dp.dp1->di_ctime = utime;
} else {
- bzero(dp2, sizeof(*dp2));
- dp2->di_size = size;
- dp2->di_mode = IFREG | IREAD;
- dp2->di_nlink = 1;
- dp2->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
- dp2->di_atime = utime;
- dp2->di_mtime = utime;
- dp2->di_ctime = utime;
- dp2->di_birthtime = utime;
+ bzero(dp.dp2, sizeof(*dp.dp2));
+ dp.dp2->di_size = size;
+ dp.dp2->di_mode = IFREG | IREAD;
+ dp.dp2->di_nlink = 1;
+ dp.dp2->di_flags =
+ SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP;
+ dp.dp2->di_atime = utime;
+ dp.dp2->di_mtime = utime;
+ dp.dp2->di_ctime = utime;
+ dp.dp2->di_birthtime = utime;
}
for (i = 0; i < UFS_NDADDR && resid; i++, resid--) {
blk = journal_balloc();
if (blk <= 0)
goto out;
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- dp1->di_db[i] = blk;
- dp1->di_blocks++;
+ dp.dp1->di_db[i] = blk;
+ dp.dp1->di_blocks++;
} else {
- dp2->di_db[i] = blk;
- dp2->di_blocks++;
+ dp.dp2->di_db[i] = blk;
+ dp.dp2->di_blocks++;
}
}
for (i = 0; i < UFS_NIADDR && resid; i++) {
@@ -1062,19 +1044,20 @@ journal_alloc(int64_t size)
goto out;
}
if (sblock.fs_magic == FS_UFS1_MAGIC) {
- dp1->di_ib[i] = blk;
- dp1->di_blocks += blks;
+ dp.dp1->di_ib[i] = blk;
+ dp.dp1->di_blocks += blks;
} else {
- dp2->di_ib[i] = blk;
- dp2->di_blocks += blks;
+ dp.dp2->di_ib[i] = blk;
+ dp.dp2->di_blocks += blks;
}
}
if (sblock.fs_magic == FS_UFS1_MAGIC)
- dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize;
+ dp.dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize;
else
- dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize;
- if (putino(&disk) < 0) {
- warn("Failed to write inode");
+ dp.dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize;
+ if (putinode(&disk) < 0) {
+ warn("Failed to write allocated inode: %s",
+ disk.d_error);
sbdirty();
return (-1);
}
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 6b8e708f7371..c2f6c91bcc4b 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -82,7 +82,7 @@ int ffs_getcg(struct fs *, struct vnode *, u_int, struct buf **,
struct cg **);
int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
-void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
+int ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
int ffs_own_mount(const struct mount *mp);
int ffs_reallocblks(struct vop_reallocblks_args *);
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index a1be71511434..d146d14980c3 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -148,12 +148,18 @@ loop:
if (I_IS_UFS1(ip)) {
*((struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
- /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
+ /*
+ * XXX: FIX? The entropy here is desirable,
+ * but the harvesting may be expensive
+ */
random_harvest_queue(&(ip->i_din1), sizeof(ip->i_din1), RANDOM_FS_ATIME);
} else {
*((struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
- /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
+ /*
+ * XXX: FIX? The entropy here is desirable,
+ * but the harvesting may be expensive
+ */
random_harvest_queue(&(ip->i_din2), sizeof(ip->i_din2), RANDOM_FS_ATIME);
}
if (waitfor)
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 4453c59517df..09b1d4982c49 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -1333,12 +1333,12 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode)
*/
dip = (struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, cancelip->i_number);
- if (clearmode || cancelip->i_effnlink == 0)
- dip->di_mode = 0;
dip->di_size = 0;
dip->di_blocks = 0;
dip->di_flags &= ~SF_SNAPSHOT;
bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs2_daddr_t));
+ if (clearmode || cancelip->i_effnlink == 0)
+ dip->di_mode = 0;
bdwrite(bp);
/*
* Now go through and expunge all the blocks in the file
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index dcc72b2fdfd3..3fe9e205f858 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -6698,12 +6698,13 @@ softdep_journal_freeblocks(ip, cred, length, flags)
if (bp->b_bufsize == fs->fs_bsize)
bp->b_flags |= B_CLUSTEROK;
softdep_update_inodeblock(ip, bp, 0);
- if (ump->um_fstype == UFS1)
+ if (ump->um_fstype == UFS1) {
*((struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
- else
+ } else {
*((struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
+ }
ACQUIRE_LOCK(ump);
(void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
if ((inodedep->id_state & IOSTARTED) != 0)
@@ -9640,6 +9641,7 @@ static void
clear_unlinked_inodedep(inodedep)
struct inodedep *inodedep;
{
+ struct ufs2_dinode *dip;
struct ufsmount *ump;
struct inodedep *idp;
struct inodedep *idn;
@@ -9743,12 +9745,14 @@ clear_unlinked_inodedep(inodedep)
ffs_oldfscompat_write((struct fs *)bp->b_data, ump);
softdep_setup_sbupdate(ump, (struct fs *)bp->b_data,
bp);
- } else if (fs->fs_magic == FS_UFS1_MAGIC)
+ } else if (fs->fs_magic == FS_UFS1_MAGIC) {
((struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, pino))->di_freelink = nino;
- else
- ((struct ufs2_dinode *)bp->b_data +
- ino_to_fsbo(fs, pino))->di_freelink = nino;
+ } else {
+ dip = (struct ufs2_dinode *)bp->b_data +
+ ino_to_fsbo(fs, pino);
+ dip->di_freelink = nino;
+ }
/*
* If the bwrite fails we have no recourse to recover. The
* filesystem is corrupted already.
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index de70a3f84283..541d44c887db 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -108,31 +108,35 @@ ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
* Load up the contents of an inode and copy the appropriate pieces
* to the incore copy.
*/
-void
+int
ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
{
+ struct ufs1_dinode *dip1;
+ struct ufs2_dinode *dip2;
if (I_IS_UFS1(ip)) {
- *ip->i_din1 =
+ dip1 = ip->i_din1;
+ *dip1 =
*((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
- ip->i_mode = ip->i_din1->di_mode;
- ip->i_nlink = ip->i_din1->di_nlink;
- ip->i_size = ip->i_din1->di_size;
- ip->i_flags = ip->i_din1->di_flags;
- ip->i_gen = ip->i_din1->di_gen;
- ip->i_uid = ip->i_din1->di_uid;
- ip->i_gid = ip->i_din1->di_gid;
- } else {
- *ip->i_din2 =
- *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
- ip->i_mode = ip->i_din2->di_mode;
- ip->i_nlink = ip->i_din2->di_nlink;
- ip->i_size = ip->i_din2->di_size;
- ip->i_flags = ip->i_din2->di_flags;
- ip->i_gen = ip->i_din2->di_gen;
- ip->i_uid = ip->i_din2->di_uid;
- ip->i_gid = ip->i_din2->di_gid;
+ ip->i_mode = dip1->di_mode;
+ ip->i_nlink = dip1->di_nlink;
+ ip->i_size = dip1->di_size;
+ ip->i_flags = dip1->di_flags;
+ ip->i_gen = dip1->di_gen;
+ ip->i_uid = dip1->di_uid;
+ ip->i_gid = dip1->di_gid;
+ return (0);
}
+ dip2 = ip->i_din2;
+ *dip2 = *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
+ ip->i_mode = dip2->di_mode;
+ ip->i_nlink = dip2->di_nlink;
+ ip->i_size = dip2->di_size;
+ ip->i_flags = dip2->di_flags;
+ ip->i_gen = dip2->di_gen;
+ ip->i_uid = dip2->di_uid;
+ ip->i_gid = dip2->di_gid;
+ return (0);
}
#endif /* KERNEL */
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index b69dd20da113..7ecaae231f07 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -740,16 +740,19 @@ loop:
bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int)fs->fs_bsize, NOCRED, &bp);
if (error) {
- VOP_UNLOCK(vp, 0);
- vrele(vp);
+ vput(vp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
+ return (error);
+ }
+ if ((error = ffs_load_inode(bp, ip, fs, ip->i_number)) != 0) {
+ brelse(bp);
+ vput(vp);
MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
return (error);
}
- ffs_load_inode(bp, ip, fs, ip->i_number);
ip->i_effnlink = ip->i_nlink;
brelse(bp);
- VOP_UNLOCK(vp, 0);
- vrele(vp);
+ vput(vp);
}
return (0);
}
@@ -1729,7 +1732,12 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
ip->i_din1 = uma_zalloc(uma_ufs1, M_WAITOK);
else
ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
- ffs_load_inode(bp, ip, fs, ino);
+ if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
+ bqrelse(bp);
+ vput(vp);
+ *vpp = NULL;
+ return (error);
+ }
if (DOINGSOFTDEP(vp))
softdep_load_inodeblock(ip);
else
diff --git a/tools/diag/prtblknos/main.c b/tools/diag/prtblknos/main.c
index 51d5b135a5ea..c3abb2babad1 100644
--- a/tools/diag/prtblknos/main.c
+++ b/tools/diag/prtblknos/main.c
@@ -47,7 +47,7 @@ main(argc, argv)
char *argv[];
{
struct uufsd disk;
- union dinode *dp;
+ union dinodep dp;
struct fs *fs;
struct stat sb;
struct statfs sfb;
@@ -98,11 +98,11 @@ main(argc, argv)
(void)printf("%s (inode #%jd): ", filename,
(intmax_t)inonum);
- if ((error = getino(&disk, (void **)&dp, inonum, NULL)) < 0)
- warn("Read of inode %jd on %s failed",
- (intmax_t)inonum, fsname);
+ if ((error = getinode(&disk, &dp, inonum)) < 0)
+ warn("Read of inode %jd on %s failed: %s",
+ (intmax_t)inonum, fsname, disk.d_error);
- prtblknos(&disk, dp);
+ prtblknos(&disk, (union dinode *)dp.dp1);
}
exit(0);
}