Use pm_fatlock to protect fat bitmap.

Tested by:	pho
MFC after:	3 weeks
This commit is contained in:
Konstantin Belousov 2010-02-28 17:13:59 +00:00
parent 23b6c23084
commit 6be1a4cc5f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=204471
2 changed files with 38 additions and 12 deletions

View File

@ -77,6 +77,9 @@ static __inline void
usemap_alloc(struct msdosfsmount *pmp, u_long cn);
static __inline void
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);
static void
fatblock(pmp, ofs, bnp, sizep, bop)
@ -409,6 +412,7 @@ usemap_alloc(pmp, cn)
u_long cn;
{
MSDOSFS_ASSERT_MP_LOCKED(pmp);
pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
pmp->pm_freeclustercount--;
}
@ -419,6 +423,7 @@ usemap_free(pmp, cn)
u_long cn;
{
MSDOSFS_ASSERT_MP_LOCKED(pmp);
pmp->pm_freeclustercount++;
pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS));
}
@ -432,17 +437,17 @@ clusterfree(pmp, cluster, oldcnp)
int error;
u_long oldcn;
usemap_free(pmp, cluster);
error = fatentry(FAT_GET_AND_SET, pmp, cluster, &oldcn, MSDOSFSFREE);
if (error) {
usemap_alloc(pmp, cluster);
if (error)
return (error);
}
/*
* If the cluster was successfully marked free, then update
* the count of free clusters, and turn off the "allocated"
* bit in the "in use" cluster bit map.
*/
MSDOSFS_LOCK_MP(pmp);
usemap_free(pmp, cluster);
MSDOSFS_UNLOCK_MP(pmp);
if (oldcnp)
*oldcnp = oldcn;
return (0);
@ -660,6 +665,8 @@ chainlength(pmp, start, count)
u_int map;
u_long len;
MSDOSFS_ASSERT_MP_LOCKED(pmp);
max_idx = pmp->pm_maxcluster / N_INUSEBITS;
idx = start / N_INUSEBITS;
start %= N_INUSEBITS;
@ -708,6 +715,8 @@ chainalloc(pmp, start, count, fillwith, retcluster, got)
int error;
u_long cl, n;
MSDOSFS_ASSERT_MP_LOCKED(pmp);
for (cl = start, n = count; n-- > 0;)
usemap_alloc(pmp, cl++);
@ -740,19 +749,28 @@ chainalloc(pmp, start, count, fillwith, retcluster, got)
* got - how many clusters were actually allocated.
*/
int
clusteralloc(pmp, start, count, fillwith, retcluster, got)
struct msdosfsmount *pmp;
u_long start;
u_long count;
u_long fillwith;
u_long *retcluster;
u_long *got;
clusteralloc(struct msdosfsmount *pmp, u_long start, u_long count,
u_long fillwith, u_long *retcluster, u_long *got)
{
int error;
MSDOSFS_LOCK_MP(pmp);
error = clusteralloc1(pmp, start, count, fillwith, retcluster, got);
MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
static int
clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count,
u_long fillwith, u_long *retcluster, u_long *got)
{
u_long idx;
u_long len, newst, foundl, cn, l;
u_long foundcn = 0; /* XXX: foundcn could be used unititialized */
u_int map;
MSDOSFS_ASSERT_MP_LOCKED(pmp);
#ifdef MSDOSFS_DEBUG
printf("clusteralloc(): find %lu clusters\n", count);
#endif
@ -828,6 +846,7 @@ freeclusterchain(pmp, cluster)
u_long bn, bo, bsize, byteoffset;
u_long readcn, lbn = -1;
MSDOSFS_LOCK_MP(pmp);
while (cluster >= CLUST_FIRST && cluster <= pmp->pm_maxcluster) {
byteoffset = FATOFS(pmp, cluster);
fatblock(pmp, byteoffset, &bn, &bsize, &bo);
@ -837,6 +856,7 @@ freeclusterchain(pmp, cluster)
error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
if (error) {
brelse(bp);
MSDOSFS_UNLOCK_MP(pmp);
return (error);
}
lbn = bn;
@ -872,6 +892,7 @@ freeclusterchain(pmp, cluster)
}
if (bp)
updatefats(pmp, bp, bn);
MSDOSFS_UNLOCK_MP(pmp);
return (0);
}
@ -888,6 +909,8 @@ fillinusemap(pmp)
int error;
u_long bn, bo, bsize, byteoffset;
MSDOSFS_ASSERT_MP_LOCKED(pmp);
/*
* Mark all clusters in use, we mark the free ones in the fat scan
* loop further down.

View File

@ -720,7 +720,10 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
/*
* Have the inuse map filled in.
*/
if ((error = fillinusemap(pmp)) != 0)
MSDOSFS_LOCK_MP(pmp);
error = fillinusemap(pmp);
MSDOSFS_UNLOCK_MP(pmp);
if (error != 0)
goto error_exit;
/*