git: 472f57606443 - stable/13 - msdosfs: take inusemap inconsistency as an error, not invariants violation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 15 Jan 2022 00:51:37 UTC
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=472f5760644320e59abc2b5362e84635dc650daf commit 472f5760644320e59abc2b5362e84635dc650daf Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-12-25 18:39:15 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2022-01-14 18:11:01 +0000 msdosfs: take inusemap inconsistency as an error, not invariants violation (cherry picked from commit 2c9a1c22c323b069d1f4883170349545c94b7b8d) --- sys/fs/msdosfs/msdosfs_fat.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 6d5bfc7fa46e..202feeef0102 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -80,8 +80,7 @@ static void updatefats(struct msdosfsmount *pmp, struct buf *bp, u_long fatbn); static __inline void usemap_alloc(struct msdosfsmount *pmp, u_long cn); -static __inline void - usemap_free(struct msdosfsmount *pmp, u_long cn); +static int usemap_free(struct msdosfsmount *pmp, u_long cn); static int clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, u_long *got); @@ -398,7 +397,7 @@ usemap_alloc(struct msdosfsmount *pmp, u_long cn) pmp->pm_flags |= MSDOSFS_FSIMOD; } -static __inline void +static int usemap_free(struct msdosfsmount *pmp, u_long cn) { @@ -408,13 +407,17 @@ usemap_free(struct msdosfsmount *pmp, u_long cn) pmp->pm_maxcluster)); KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0, ("usemap_free on ro msdosfs mount")); + if ((pmp->pm_inusemap[cn / N_INUSEBITS] & + (1U << (cn % N_INUSEBITS))) == 0) { + printf("%s: Freeing unused sector %ld %ld %x\n", + pmp->pm_mountp->mnt_stat.f_mntonname, cn, cn % N_INUSEBITS, + (unsigned)pmp->pm_inusemap[cn / N_INUSEBITS]); + return (EINTEGRITY); + } pmp->pm_freeclustercount++; pmp->pm_flags |= MSDOSFS_FSIMOD; - KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & - (1U << (cn % N_INUSEBITS))) != 0, - ("Freeing unused sector %ld %ld %x", cn, cn % N_INUSEBITS, - (unsigned)pmp->pm_inusemap[cn / N_INUSEBITS])); pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1U << (cn % N_INUSEBITS)); + return (0); } int @@ -432,11 +435,11 @@ clusterfree(struct msdosfsmount *pmp, u_long cluster, u_long *oldcnp) * bit in the "in use" cluster bit map. */ MSDOSFS_LOCK_MP(pmp); - usemap_free(pmp, cluster); + error = usemap_free(pmp, cluster); MSDOSFS_UNLOCK_MP(pmp); - if (oldcnp) + if (error == 0 && oldcnp != NULL) *oldcnp = oldcn; - return (0); + return (error); } /* @@ -712,7 +715,7 @@ chainalloc(struct msdosfsmount *pmp, u_long start, u_long count, error = fatchain(pmp, start, count, fillwith); if (error != 0) { for (cl = start, n = count; n-- > 0;) - usemap_free(pmp, cl++); + (void)usemap_free(pmp, cl++); return (error); } #ifdef MSDOSFS_DEBUG @@ -846,7 +849,12 @@ freeclusterchain(struct msdosfsmount *pmp, u_long cluster) } lbn = bn; } - usemap_free(pmp, cluster); + error = usemap_free(pmp, cluster); + if (error != 0) { + updatefats(pmp, bp, lbn); + MSDOSFS_UNLOCK_MP(pmp); + return (error); + } switch (pmp->pm_fatmask) { case FAT12_MASK: readcn = getushort(bp->b_data + bo); @@ -940,8 +948,13 @@ fillinusemap(struct msdosfsmount *pmp) #endif brelse(bp); return (EINVAL); - } else if (readcn == CLUST_FREE) - usemap_free(pmp, cn); + } else if (readcn == CLUST_FREE) { + error = usemap_free(pmp, cn); + if (error != 0) { + brelse(bp); + return (error); + } + } } if (bp != NULL) brelse(bp);