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