git: 90532db778dc - stable/13 - Cleanups to fsck_ffs(8).

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Wed, 07 Jun 2023 23:15:39 UTC
The branch stable/13 has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=90532db778dc2bca557d5be43c5b9813ba44d80a

commit 90532db778dc2bca557d5be43c5b9813ba44d80a
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2023-05-29 21:54:52 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2023-06-07 22:54:13 +0000

    Cleanups to fsck_ffs(8).
    
    Sponsored-by: The FreeBSD Foundation
    
    (cherry picked from commit 5267120645fa52eac771c9bd8e28d68620a3bb89)
---
 sbin/fsck_ffs/dir.c   |  3 +++
 sbin/fsck_ffs/inode.c | 17 +++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index 7ea471bcb30a..3ff6c467ee08 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -725,6 +725,7 @@ changeino(ino_t dir, const char *name, ino_t newnum, int depth)
 	ginode(dir, &ip);
 	if (((error = ckinode(ip.i_dp, &idesc)) & ALTERED) && newnum != 0) {
 		DIP_SET(ip.i_dp, di_dirdepth, depth);
+		inodirty(&ip);
 		getinoinfo(dir)->i_depth = depth;
 	}
 	free(idesc.id_name);
@@ -879,6 +880,7 @@ expanddir(struct inode *ip, char *name)
 			DIP_SET(dp, di_ib[0], indirblk);
 			DIP_SET(dp, di_blocks,
 			    DIP(dp, di_blocks) + btodb(sblock.fs_bsize));
+			inodirty(ip);
 		}
 		IBLK_SET(nbp, lastlbn - UFS_NDADDR, newblk);
 		dirty(nbp);
@@ -969,6 +971,7 @@ allocdir(ino_t parent, ino_t request, int mode)
 	} else {
 		inp->i_depth = parentinp->i_depth + 1; 
 		DIP_SET(dp, di_dirdepth, inp->i_depth);
+		inodirty(&ip);
 	}
 	inoinfo(ino)->ino_type = DT_DIR;
 	inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 7dca95129ed1..c56d938cce41 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -90,6 +90,10 @@ ckinode(union dinode *dp, struct inodesc *idesc)
 		dino.dp1 = dp->dp1;
 	else
 		dino.dp2 = dp->dp2;
+	if (DIP(&dino, di_size) < 0) {
+		pfatal("NEGATIVE INODE SIZE %jd\n", DIP(&dino, di_size));
+		return (STOP);
+	}
 	ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize);
 	for (i = 0; i < UFS_NDADDR; i++) {
 		idesc->id_lbn++;
@@ -116,6 +120,7 @@ ckinode(union dinode *dp, struct inodesc *idesc)
 					inodirty(&ip);
 					irelse(&ip);
 				}
+				return (STOP);
 			}
 			continue;
 		}
@@ -498,6 +503,11 @@ irelse(struct inode *ip)
 	/* Check for failed inode read */
 	if (ip->i_bp == NULL)
 		return;
+	if (debug && sblock.fs_magic == FS_UFS2_MAGIC &&
+	    ffs_verify_dinode_ckhash(&sblock, (struct ufs2_dinode *)ip->i_dp)) {
+		pwarn("irelse: releasing inode with bad check-hash");
+		prtinode(ip);
+	}
 	if (ip->i_bp->b_refcnt <= 0)
 		pfatal("irelse: releasing unreferenced ino %ju\n",
 		    (uintmax_t) ip->i_number);
@@ -1419,21 +1429,20 @@ retry:
 	cgdirty(cgbp);
 	ginode(ino, &ip);
 	dp = ip.i_dp;
+	memset(dp, 0, ((sblock.fs_magic == FS_UFS1_MAGIC) ?
+	    sizeof(struct ufs1_dinode) : sizeof(struct ufs2_dinode)));
 	DIP_SET(dp, di_db[0], allocblk(ino_to_cg(&sblock, ino), (long)1,
 	    std_checkblkavail));
 	if (DIP(dp, di_db[0]) == 0) {
 		inoinfo(ino)->ino_state = USTATE;
+		inodirty(&ip);
 		irelse(&ip);
 		return (0);
 	}
 	DIP_SET(dp, di_mode, type);
-	DIP_SET(dp, di_flags, 0);
 	DIP_SET(dp, di_atime, time(NULL));
 	DIP_SET(dp, di_ctime, DIP(dp, di_atime));
 	DIP_SET(dp, di_mtime, DIP(dp, di_ctime));
-	DIP_SET(dp, di_mtimensec, 0);
-	DIP_SET(dp, di_ctimensec, 0);
-	DIP_SET(dp, di_atimensec, 0);
 	DIP_SET(dp, di_size, sblock.fs_fsize);
 	DIP_SET(dp, di_blocks, btodb(sblock.fs_fsize));
 	n_files++;