git: 3c2dc524c333 - main - Do not panic in case of corrupted directory

From: Fedor Uporov <fsu_at_FreeBSD.org>
Date: Sat, 18 Mar 2023 06:16:51 UTC
The branch main has been updated by fsu:

URL: https://cgit.FreeBSD.org/src/commit/?id=3c2dc524c333747a8c5deb3f0f88b29a8e36dff4

commit 3c2dc524c333747a8c5deb3f0f88b29a8e36dff4
Author:     Fedor Uporov <fsu@FreeBSD.org>
AuthorDate: 2023-03-18 06:11:27 +0000
Commit:     Fedor Uporov <fsu@FreeBSD.org>
CommitDate: 2023-03-18 06:16:24 +0000

    Do not panic in case of corrupted directory
    
    The panic() will be called under ext2_dirbad()
    function in case of rw mount. It cause user confusion,
    like in BZ 265951.
    
    PR:                     265951
    Reviewed by:            pfg, mckusick
    MFC after:              2 week
    Differential revision:  https://reviews.freebsd.org/D38503
---
 sys/fs/ext2fs/ext2_lookup.c | 14 +++++---------
 sys/fs/ext2fs/ext2_vnops.c  |  9 +++++++++
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c
index 93a2d172e01f..4859d51f8429 100644
--- a/sys/fs/ext2fs/ext2_lookup.c
+++ b/sys/fs/ext2fs/ext2_lookup.c
@@ -539,8 +539,8 @@ found:
 	if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen) >
 	    dp->i_size) {
 		ext2_dirbad(dp, i_offset, "i_size too small");
-		dp->i_size = entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen);
-		dp->i_flag |= IN_CHANGE | IN_UPDATE;
+		brelse(bp);
+		return (EIO);
 	}
 	brelse(bp);
 
@@ -802,13 +802,9 @@ ext2_dirbad(struct inode *ip, doff_t offset, char *how)
 	struct mount *mp;
 
 	mp = ITOV(ip)->v_mount;
-	if ((mp->mnt_flag & MNT_RDONLY) == 0)
-		panic("ext2_dirbad: %s: bad dir ino %ju at offset %ld: %s\n",
-		    mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number,
-		    (long)offset, how);
-	else
-		SDT_PROBE4(ext2fs, , trace, ext2_dirbad_error,
-		    mp->mnt_stat.f_mntonname, ip->i_number, offset, how);
+
+	SDT_PROBE4(ext2fs, , trace, ext2_dirbad_error,
+	    mp->mnt_stat.f_mntonname, ip->i_number, offset, how);
 }
 
 /*
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index a7da8249ab4d..8ec12f9a7f8f 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -1088,6 +1088,15 @@ abortit:
 				if (namlen != 2 ||
 				    dirbuf->dotdot_name[0] != '.' ||
 				    dirbuf->dotdot_name[1] != '.') {
+					/*
+					 * The filesystem is in corrupted state,
+					 * need to run fsck to fix mangled dir
+					 * entry. From other side this error
+					 * need to be ignored because it is
+					 * too difficult to revert directories
+					 * to state before rename from this
+					 * point.
+					 */
 					ext2_dirbad(xp, (doff_t)12,
 					    "rename: mangled dir");
 				} else {