diff options
author | Kirk McKusick <mckusick@FreeBSD.org> | 2023-03-18 22:36:54 +0000 |
---|---|---|
committer | Kirk McKusick <mckusick@FreeBSD.org> | 2023-03-18 22:37:58 +0000 |
commit | 069767091e54a2537ae509dcdf3005fb0f50ab84 (patch) | |
tree | 7a2a2c624b1465e39aefcac26b39d6a66e993223 | |
parent | bad8f86843fa34bf4d4d2bfb8183331c02ced87f (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.c | 18 | ||||
-rw-r--r-- | 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); |