MFC r204471:

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

View File

@ -720,7 +720,10 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
/* /*
* Have the inuse map filled in. * 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; goto error_exit;
/* /*