The branch main has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=069767091e54a2537ae509dcdf3005fb0f50ab84

commit 069767091e54a2537ae509dcdf3005fb0f50ab84
Author:     Kirk McKusick <[email protected]>
AuthorDate: 2023-03-18 22:36:54 +0000
Commit:     Kirk McKusick <[email protected]>
CommitDate: 2023-03-18 22:37:58 +0000

    Do not panic in case of corrupted UFS/FFS directory.
    
    Historically the system panic'ed when it encountered a corrupt
    directory. This change recovers well enough to continue operations.
    This change is made in response to a similar change made in the ext2
    filesystem as described in the cited Differential Revision.
    
    MFC after:    2 weeks
    Sponsored by: The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D38503
---
 sys/ufs/ufs/ufs_lookup.c | 18 +++++-------------
 sys/ufs/ufs/ufs_vnops.c  |  4 +++-
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 4c390f4c42ef..cabd04a50bfd 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -548,9 +548,8 @@ found:
         */
        if (i_offset + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) {
                ufs_dirbad(dp, i_offset, "i_size too small");
-               dp->i_size = i_offset + DIRSIZ(OFSFMT(vdp), ep);
-               DIP_SET(dp, i_size, dp->i_size);
-               UFS_INODE_SET_FLAG(dp, IN_SIZEMOD | IN_CHANGE | IN_UPDATE);
+               brelse(bp);
+               return (EIO);
        }
        brelse(bp);
 
@@ -758,17 +757,10 @@ found:
 void
 ufs_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("ufs_dirbad: %s: bad dir ino %ju at offset %ld: %s",
-                   mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number,
-                   (long)offset, how);
-       else
-               (void)printf("%s: bad dir ino %ju at offset %ld: %s\n",
-                   mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number,
-                   (long)offset, how);
+       (void)printf("%s: bad dir ino %ju at offset %ld: %s\n",
+           ITOV(ip)->v_mount->mnt_stat.f_mntonname, (uintmax_t)ip->i_number,
+           (long)offset, how);
 }
 
 /*
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index ae6d963920f3..54046c285fd7 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1730,7 +1730,9 @@ relock:
                        /* Journal must account for each new link. */
                        softdep_setup_dotdot_link(tdp, fip);
                SET_I_OFFSET(fip, mastertemplate.dot_reclen);
-               ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0);
+               if (ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0) != 0)
+                       ufs_dirbad(fip, mastertemplate.dot_reclen,
+                           "rename: missing ".." entry");
                cache_purge(fdvp);
        }
        error = ufs_dirremove(fdvp, fip, fcnp->cn_flags, 0);

Reply via email to