aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/msdosfs/msdosfs_denode.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-12-23 23:21:53 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2022-01-08 03:41:44 +0000
commit595ed4d76713c1e9cab7d8a160ed59f8f4e5ecb4 (patch)
tree0b971243f5a32863457ff31456c38a2e32a878a0 /sys/fs/msdosfs/msdosfs_denode.c
parent9f4073d44628bc70dbe67df5163266cbfbe37167 (diff)
downloadsrc-595ed4d76713c1e9cab7d8a160ed59f8f4e5ecb4.tar.gz
src-595ed4d76713c1e9cab7d8a160ed59f8f4e5ecb4.zip
msdosfs: handle inconsistently hashed denodes
It is possible, on the corrupted msdosfs volume, to have file which denode inode number does not match the one calculated using directory cluster. Instead of asserting the condition as impossible, handle it and return error, after reclaiming the aliased vnode. In collaboration with: pho Reviewed by: markj, mckusick Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D33721
Diffstat (limited to 'sys/fs/msdosfs/msdosfs_denode.c')
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
index 64f75c267959..8ca9fa38b1cf 100644
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -142,9 +142,23 @@ deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
return (error);
if (nvp != NULL) {
*depp = VTODE(nvp);
- KASSERT((*depp)->de_dirclust == dirclust, ("wrong dirclust"));
- KASSERT((*depp)->de_diroffset == diroffset, ("wrong diroffset"));
+ if ((*depp)->de_dirclust != dirclust) {
+ printf("%s: wrong dir cluster %lu %lu\n",
+ pmp->pm_mountp->mnt_stat.f_mntonname,
+ (*depp)->de_dirclust, dirclust);
+ goto badoff;
+ }
+ if ((*depp)->de_diroffset != diroffset) {
+ printf("%s: wrong dir offset %lu %lu\n",
+ pmp->pm_mountp->mnt_stat.f_mntonname,
+ (*depp)->de_diroffset, diroffset);
+ goto badoff;
+ }
return (0);
+badoff:
+ vgone(nvp);
+ vput(nvp);
+ return (EBADF);
}
ldep = malloc(sizeof(struct denode), M_MSDOSFSNODE, M_WAITOK | M_ZERO);