svn commit: r359789 - head/sbin/fsck_ffs
Kirk McKusick
mckusick at FreeBSD.org
Fri Apr 10 23:49:35 UTC 2020
Author: mckusick
Date: Fri Apr 10 23:49:34 2020
New Revision: 359789
URL: https://svnweb.freebsd.org/changeset/base/359789
Log:
Add an inode check-hash verification when running the journalled
soft update recovery code with the debugging (-d) option.
As inode check-hash was first introduced to UFS in FreeBSD 13,
there is no need to MFC this commit.
Reported by: Chuck Silvers
Sponsored by: Netflix
Modified:
head/sbin/fsck_ffs/suj.c
Modified: head/sbin/fsck_ffs/suj.c
==============================================================================
--- head/sbin/fsck_ffs/suj.c Fri Apr 10 23:13:29 2020 (r359788)
+++ head/sbin/fsck_ffs/suj.c Fri Apr 10 23:49:34 2020 (r359789)
@@ -109,6 +109,7 @@ struct ino_blk {
LIST_ENTRY(ino_blk) ib_next;
uint8_t *ib_buf;
int ib_dirty;
+ ino_t ib_startinginum;
ufs2_daddr_t ib_blk;
};
LIST_HEAD(iblkhd, ino_blk);
@@ -157,6 +158,7 @@ static void ino_adjust(struct suj_ino *);
static void ino_build(struct suj_ino *);
static int blk_isfree(ufs2_daddr_t);
static void initsuj(void);
+static void ino_dirty(ino_t);
static void *
errmalloc(size_t n)
@@ -394,6 +396,7 @@ ino_read(ino_t ino)
struct iblkhd *hd;
struct suj_cg *sc;
ufs2_daddr_t blk;
+ union dinode *dp;
int off;
blk = ino_to_fsba(fs, ino);
@@ -412,6 +415,7 @@ ino_read(ino_t ino)
bzero(iblk, sizeof(*iblk));
iblk->ib_buf = errmalloc(fs->fs_bsize);
iblk->ib_blk = blk;
+ iblk->ib_startinginum = rounddown(ino, INOPB(fs));
LIST_INSERT_HEAD(hd, iblk, ib_next);
if (bread(&disk, fsbtodb(fs, blk), iblk->ib_buf, fs->fs_bsize) == -1)
err_suj("Failed to read inode block %jd\n", blk);
@@ -420,8 +424,18 @@ found:
off = ino_to_fsbo(fs, ino);
if (fs->fs_magic == FS_UFS1_MAGIC)
return (union dinode *)&((struct ufs1_dinode *)iblk->ib_buf)[off];
- else
- return (union dinode *)&((struct ufs2_dinode *)iblk->ib_buf)[off];
+ dp = (union dinode *)&((struct ufs2_dinode *)iblk->ib_buf)[off];
+ if (debug &&
+ ffs_verify_dinode_ckhash(fs, (struct ufs2_dinode *)dp) != 0) {
+ pwarn("ino_read: INODE CHECK-HASH FAILED");
+ prtinode(ino, dp);
+ if (preen || reply("FIX") != 0) {
+ if (preen)
+ printf(" (FIXED)\n");
+ ino_dirty(ino);
+ }
+ }
+ return (dp);
}
static void
@@ -464,9 +478,25 @@ ino_dirty(ino_t ino)
static void
iblk_write(struct ino_blk *iblk)
{
+ struct ufs2_dinode *dp;
+ int i;
if (iblk->ib_dirty == 0)
return;
+ if (debug && fs->fs_magic == FS_UFS2_MAGIC) {
+ dp = (struct ufs2_dinode *)iblk->ib_buf;
+ for (i = 0; i < INOPB(fs); dp++, i++) {
+ if (ffs_verify_dinode_ckhash(fs, dp) == 0)
+ continue;
+ pwarn("iblk_write: INODE CHECK-HASH FAILED");
+ prtinode(iblk->ib_startinginum + i, (union dinode *)dp);
+ if (preen || reply("FIX") != 0) {
+ if (preen)
+ printf(" (FIXED)\n");
+ ino_dirty(iblk->ib_startinginum + i);
+ }
+ }
+ }
if (bwrite(&disk, fsbtodb(fs, iblk->ib_blk), iblk->ib_buf,
fs->fs_bsize) == -1)
err_suj("Failed to write inode block %jd\n", iblk->ib_blk);
More information about the svn-src-all
mailing list