mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 04:43:53 +00:00
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
This commit is contained in:
parent
595ed4d767
commit
2c9a1c22c3
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue