1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-23 11:18:54 +00:00

Eliminate a deadlock that can occur during the cgaccount() processing due to

the cg map buffer being held when writing indirect blocks.  The process ends up
in ffs_copyonwrite(), attempting to get snaplk while holding the cg map buffer
lock.

Another process might be in ffs_copyonwrite(), trying to allocate a new block
for a copy.  It would hold snaplk while trying to get the cg map buffer lock.

Release the cg map buffer early and use the copy for most of the cgaccount
processing to avoid this deadlock.
This commit is contained in:
Tor Egge 2005-10-09 20:00:16 +00:00
parent 17026ff61a
commit 45f91051da
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151178

View File

@ -752,6 +752,8 @@ cgaccount(cg, vp, nbp, passno)
if (fs->fs_cgsize < fs->fs_bsize)
bzero(&nbp->b_data[fs->fs_cgsize],
fs->fs_bsize - fs->fs_cgsize);
cgp = (struct cg *)nbp->b_data;
bqrelse(bp);
if (passno == 2)
nbp->b_flags |= B_VALIDSUSPWRT;
numblks = howmany(fs->fs_size, fs->fs_frag);
@ -773,7 +775,6 @@ cgaccount(cg, vp, nbp, passno)
error = UFS_BALLOC(vp, lblktosize(fs, (off_t)(base + loc)),
fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
if (error) {
brelse(bp);
return (error);
}
indiroff = (base + loc - NDADDR) % NINDIR(fs);
@ -786,7 +787,6 @@ cgaccount(cg, vp, nbp, passno)
lblktosize(fs, (off_t)(base + loc)),
fs->fs_bsize, KERNCRED, BA_METAONLY, &ibp);
if (error) {
brelse(bp);
return (error);
}
indiroff = 0;
@ -812,7 +812,6 @@ cgaccount(cg, vp, nbp, passno)
((ufs2_daddr_t *)(ibp->b_data)) [indiroff] == BLK_NOCOPY)
panic("ffs_snapshot: lost indirect block");
}
bqrelse(bp);
if (passno == 2)
ibp->b_flags |= B_VALIDSUSPWRT;
bdwrite(ibp);