Skip to content

Commit ad0a554

Browse files
authored
Hold db_mtx when updating db_state
Commit 555ef90 did some general code refactoring for dmu_buf_will_not_fill() and dmu_buf_will_fill(). However, the db_mtx was not held when update db->db_state in those code block. The rest of the dbuf code always holds the db_mtx when updating db_state. This is important because cv_wait() db_changed is used to check for db_state changes. Updating dmu_buf_will_not_fill() and dmu_buf_will_fill() to hold the db_mtx when updating db_state. Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Brian Atkinson <[email protected]> Closes #14875
1 parent 577e835 commit ad0a554

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

module/zfs/dbuf.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2716,8 +2716,10 @@ dmu_buf_will_not_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
27162716
{
27172717
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
27182718

2719+
mutex_enter(&db->db_mtx);
27192720
db->db_state = DB_NOFILL;
27202721
DTRACE_SET_STATE(db, "allocating NOFILL buffer");
2722+
mutex_exit(&db->db_mtx);
27212723

27222724
dbuf_noread(db);
27232725
(void) dbuf_dirty(db, tx);
@@ -2736,18 +2738,18 @@ dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
27362738
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT ||
27372739
dmu_tx_private_ok(tx));
27382740

2741+
mutex_enter(&db->db_mtx);
27392742
if (db->db_state == DB_NOFILL) {
27402743
/*
27412744
* Block cloning: We will be completely overwriting a block
27422745
* cloned in this transaction group, so let's undirty the
27432746
* pending clone and mark the block as uncached. This will be
27442747
* as if the clone was never done.
27452748
*/
2746-
mutex_enter(&db->db_mtx);
27472749
VERIFY(!dbuf_undirty(db, tx));
2748-
mutex_exit(&db->db_mtx);
27492750
db->db_state = DB_UNCACHED;
27502751
}
2752+
mutex_exit(&db->db_mtx);
27512753

27522754
dbuf_noread(db);
27532755
(void) dbuf_dirty(db, tx);

0 commit comments

Comments
 (0)