aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2023-03-18 22:36:54 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2023-03-18 22:37:58 +0000
commit069767091e54a2537ae509dcdf3005fb0f50ab84 (patch)
tree7a2a2c624b1465e39aefcac26b39d6a66e993223
parentbad8f86843fa34bf4d4d2bfb8183331c02ced87f (diff)
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
-rw-r--r--sys/ufs/ufs/ufs_lookup.c18
-rw-r--r--sys/ufs/ufs/ufs_vnops.c4
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);