git: 2c9a1c22c323 - main - msdosfs: take inusemap inconsistency as an error, not invariants violation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 08 Jan 2022 04:29:30 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=2c9a1c22c323b069d1f4883170349545c94b7b8d
commit 2c9a1c22c323b069d1f4883170349545c94b7b8d
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-12-25 18:39:15 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-01-08 03:41:44 +0000
msdosfs: take inusemap inconsistency as an error, not invariants violation
In other words, stop silently accepting freeing free cluster in
non-debug kernels, but return the error to the caller. Modify callers
to handle errors from usemap_free().
In collaboration with: pho
Reviewed by: markj, mckusick
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D33721
---
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);