Fixed (?) races in mark_buffer_dirty(). We abuse the buffer cache

by hacking on locked buffers without getblk()ing them, and we didn't
even use splbio() to prevent biodone() changing the buffer underneath
use when a write completes.  I think there was no problem in practice
on i386's because the operations on b_flags and numdirtybufs happen to
be atomic.  We still depend on biodone()'s operations on b_flags not
interfering with ours.  I think there is only interference for B_ERROR,
and this is harmless because errors for async writes are ignored anyway.

Don't use mark_buffer_dirty() except for superblock-related metadata.
It was used in just one case where ordinary BSD buffering is more
natural.
This commit is contained in:
Bruce Evans 1998-06-21 21:06:04 +00:00
parent 9b7a8fb7d8
commit add4ae9324
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=37103
2 changed files with 12 additions and 6 deletions

View File

@ -53,11 +53,15 @@
*/
void mark_buffer_dirty(struct buf *bh)
{
int s;
s = splbio();
if (!(bh->b_flags & B_DELWRI)) {
numdirtybuffers++;
bh->b_flags |= B_DELWRI;
bh->b_flags &= ~(B_READ | B_ERROR);
}
bh->b_flags &= ~(B_READ | B_ERROR);
splx(s);
}
struct ext2_group_desc * get_group_desc (struct mount * mp,
@ -274,8 +278,7 @@ static void inc_inode_version (struct inode * inode,
EXT2_INODES_PER_BLOCK(inode->i_sb));
raw_inode->i_version++;
inode->u.ext2_i.i_version = raw_inode->i_version;
mark_buffer_dirty(bh);
brelse (bh);
bdwrite (bh);
}
#endif /* linux */

View File

@ -53,11 +53,15 @@
*/
void mark_buffer_dirty(struct buf *bh)
{
int s;
s = splbio();
if (!(bh->b_flags & B_DELWRI)) {
numdirtybuffers++;
bh->b_flags |= B_DELWRI;
bh->b_flags &= ~(B_READ | B_ERROR);
}
bh->b_flags &= ~(B_READ | B_ERROR);
splx(s);
}
struct ext2_group_desc * get_group_desc (struct mount * mp,
@ -274,8 +278,7 @@ static void inc_inode_version (struct inode * inode,
EXT2_INODES_PER_BLOCK(inode->i_sb));
raw_inode->i_version++;
inode->u.ext2_i.i_version = raw_inode->i_version;
mark_buffer_dirty(bh);
brelse (bh);
bdwrite (bh);
}
#endif /* linux */