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 <mav@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Brian Atkinson <batkinson@lanl.gov>
Closes #14875
This commit is contained in:
parent
577e835f30
commit
ad0a554614
|
@ -2716,8 +2716,10 @@ dmu_buf_will_not_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
|
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
|
||||||
|
|
||||||
|
mutex_enter(&db->db_mtx);
|
||||||
db->db_state = DB_NOFILL;
|
db->db_state = DB_NOFILL;
|
||||||
DTRACE_SET_STATE(db, "allocating NOFILL buffer");
|
DTRACE_SET_STATE(db, "allocating NOFILL buffer");
|
||||||
|
mutex_exit(&db->db_mtx);
|
||||||
|
|
||||||
dbuf_noread(db);
|
dbuf_noread(db);
|
||||||
(void) dbuf_dirty(db, tx);
|
(void) dbuf_dirty(db, tx);
|
||||||
|
@ -2736,6 +2738,7 @@ dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
|
||||||
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT ||
|
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT ||
|
||||||
dmu_tx_private_ok(tx));
|
dmu_tx_private_ok(tx));
|
||||||
|
|
||||||
|
mutex_enter(&db->db_mtx);
|
||||||
if (db->db_state == DB_NOFILL) {
|
if (db->db_state == DB_NOFILL) {
|
||||||
/*
|
/*
|
||||||
* Block cloning: We will be completely overwriting a block
|
* Block cloning: We will be completely overwriting a block
|
||||||
|
@ -2743,11 +2746,10 @@ dmu_buf_will_fill(dmu_buf_t *db_fake, dmu_tx_t *tx)
|
||||||
* pending clone and mark the block as uncached. This will be
|
* pending clone and mark the block as uncached. This will be
|
||||||
* as if the clone was never done.
|
* as if the clone was never done.
|
||||||
*/
|
*/
|
||||||
mutex_enter(&db->db_mtx);
|
|
||||||
VERIFY(!dbuf_undirty(db, tx));
|
VERIFY(!dbuf_undirty(db, tx));
|
||||||
mutex_exit(&db->db_mtx);
|
|
||||||
db->db_state = DB_UNCACHED;
|
db->db_state = DB_UNCACHED;
|
||||||
}
|
}
|
||||||
|
mutex_exit(&db->db_mtx);
|
||||||
|
|
||||||
dbuf_noread(db);
|
dbuf_noread(db);
|
||||||
(void) dbuf_dirty(db, tx);
|
(void) dbuf_dirty(db, tx);
|
||||||
|
|
Loading…
Reference in New Issue