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:
parent
17026ff61a
commit
45f91051da
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151178
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user