mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-05-29 09:54:58 +03:00
More aggressively assert that db_mtx protects db.db_data
db.db_mtx must be held any time that db.db_data is accessed. All of these functions do have the lock held by a parent; add assertions to ensure that it stays that way. See https://github.com/openzfs/zfs/discussions/17118 * Refactor dbuf_read_bonus to make it obvious why db_rwlock isn't required. * Refactor dbuf_hold_copy to eliminate the db_rwlock Copy data into the newly allocated buffer before assigning it to the db. That way, there will be no need to take db->db_rwlock. * Refactor dbuf_read_hole In the case of an indirect hole, initialize the newly allocated buffer before assigning it to the dmu_buf_impl_t. Sponsored by: ConnectWise Signed-off-by: Alan Somers <asomers@gmail.com> Closes #17209
This commit is contained in:
parent
1a8f5ad3b0
commit
c17bdc4914
@ -1410,6 +1410,7 @@ dbuf_read_done(zio_t *zio, const zbookmark_phys_t *zb, const blkptr_t *bp,
|
|||||||
static int
|
static int
|
||||||
dbuf_read_bonus(dmu_buf_impl_t *db, dnode_t *dn)
|
dbuf_read_bonus(dmu_buf_impl_t *db, dnode_t *dn)
|
||||||
{
|
{
|
||||||
|
void* db_data;
|
||||||
int bonuslen, max_bonuslen;
|
int bonuslen, max_bonuslen;
|
||||||
|
|
||||||
bonuslen = MIN(dn->dn_bonuslen, dn->dn_phys->dn_bonuslen);
|
bonuslen = MIN(dn->dn_bonuslen, dn->dn_phys->dn_bonuslen);
|
||||||
@ -1417,21 +1418,22 @@ dbuf_read_bonus(dmu_buf_impl_t *db, dnode_t *dn)
|
|||||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
ASSERT(DB_DNODE_HELD(db));
|
ASSERT(DB_DNODE_HELD(db));
|
||||||
ASSERT3U(bonuslen, <=, db->db.db_size);
|
ASSERT3U(bonuslen, <=, db->db.db_size);
|
||||||
db->db.db_data = kmem_alloc(max_bonuslen, KM_SLEEP);
|
db_data = kmem_alloc(max_bonuslen, KM_SLEEP);
|
||||||
arc_space_consume(max_bonuslen, ARC_SPACE_BONUS);
|
arc_space_consume(max_bonuslen, ARC_SPACE_BONUS);
|
||||||
if (bonuslen < max_bonuslen)
|
if (bonuslen < max_bonuslen)
|
||||||
memset(db->db.db_data, 0, max_bonuslen);
|
memset(db_data, 0, max_bonuslen);
|
||||||
if (bonuslen)
|
if (bonuslen)
|
||||||
memcpy(db->db.db_data, DN_BONUS(dn->dn_phys), bonuslen);
|
memcpy(db_data, DN_BONUS(dn->dn_phys), bonuslen);
|
||||||
|
db->db.db_data = db_data;
|
||||||
db->db_state = DB_CACHED;
|
db->db_state = DB_CACHED;
|
||||||
DTRACE_SET_STATE(db, "bonus buffer filled");
|
DTRACE_SET_STATE(db, "bonus buffer filled");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dbuf_handle_indirect_hole(dmu_buf_impl_t *db, dnode_t *dn, blkptr_t *dbbp)
|
dbuf_handle_indirect_hole(void *data, dnode_t *dn, blkptr_t *dbbp)
|
||||||
{
|
{
|
||||||
blkptr_t *bps = db->db.db_data;
|
blkptr_t *bps = data;
|
||||||
uint32_t indbs = 1ULL << dn->dn_indblkshift;
|
uint32_t indbs = 1ULL << dn->dn_indblkshift;
|
||||||
int n_bps = indbs >> SPA_BLKPTRSHIFT;
|
int n_bps = indbs >> SPA_BLKPTRSHIFT;
|
||||||
|
|
||||||
@ -1456,6 +1458,7 @@ static int
|
|||||||
dbuf_read_hole(dmu_buf_impl_t *db, dnode_t *dn, blkptr_t *bp)
|
dbuf_read_hole(dmu_buf_impl_t *db, dnode_t *dn, blkptr_t *bp)
|
||||||
{
|
{
|
||||||
ASSERT(MUTEX_HELD(&db->db_mtx));
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
|
arc_buf_t *db_data;
|
||||||
|
|
||||||
int is_hole = bp == NULL || BP_IS_HOLE(bp);
|
int is_hole = bp == NULL || BP_IS_HOLE(bp);
|
||||||
/*
|
/*
|
||||||
@ -1468,13 +1471,14 @@ dbuf_read_hole(dmu_buf_impl_t *db, dnode_t *dn, blkptr_t *bp)
|
|||||||
is_hole = dnode_block_freed(dn, db->db_blkid) || BP_IS_HOLE(bp);
|
is_hole = dnode_block_freed(dn, db->db_blkid) || BP_IS_HOLE(bp);
|
||||||
|
|
||||||
if (is_hole) {
|
if (is_hole) {
|
||||||
dbuf_set_data(db, dbuf_alloc_arcbuf(db));
|
db_data = dbuf_alloc_arcbuf(db);
|
||||||
memset(db->db.db_data, 0, db->db.db_size);
|
memset(db_data->b_data, 0, db->db.db_size);
|
||||||
|
|
||||||
if (bp != NULL && db->db_level > 0 && BP_IS_HOLE(bp) &&
|
if (bp != NULL && db->db_level > 0 && BP_IS_HOLE(bp) &&
|
||||||
BP_GET_LOGICAL_BIRTH(bp) != 0) {
|
BP_GET_LOGICAL_BIRTH(bp) != 0) {
|
||||||
dbuf_handle_indirect_hole(db, dn, bp);
|
dbuf_handle_indirect_hole(db_data->b_data, dn, bp);
|
||||||
}
|
}
|
||||||
|
dbuf_set_data(db, db_data);
|
||||||
db->db_state = DB_CACHED;
|
db->db_state = DB_CACHED;
|
||||||
DTRACE_SET_STATE(db, "hole read satisfied");
|
DTRACE_SET_STATE(db, "hole read satisfied");
|
||||||
return (0);
|
return (0);
|
||||||
@ -2493,6 +2497,7 @@ dbuf_undirty_bonus(dbuf_dirty_record_t *dr)
|
|||||||
{
|
{
|
||||||
dmu_buf_impl_t *db = dr->dr_dbuf;
|
dmu_buf_impl_t *db = dr->dr_dbuf;
|
||||||
|
|
||||||
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
if (dr->dt.dl.dr_data != db->db.db_data) {
|
if (dr->dt.dl.dr_data != db->db.db_data) {
|
||||||
struct dnode *dn = dr->dr_dnode;
|
struct dnode *dn = dr->dr_dnode;
|
||||||
int max_bonuslen = DN_SLOTS_TO_BONUSLEN(dn->dn_num_slots);
|
int max_bonuslen = DN_SLOTS_TO_BONUSLEN(dn->dn_num_slots);
|
||||||
@ -3827,6 +3832,7 @@ dbuf_hold_copy(dnode_t *dn, dmu_buf_impl_t *db)
|
|||||||
{
|
{
|
||||||
dbuf_dirty_record_t *dr = db->db_data_pending;
|
dbuf_dirty_record_t *dr = db->db_data_pending;
|
||||||
arc_buf_t *data = dr->dt.dl.dr_data;
|
arc_buf_t *data = dr->dt.dl.dr_data;
|
||||||
|
arc_buf_t *db_data;
|
||||||
enum zio_compress compress_type = arc_get_compression(data);
|
enum zio_compress compress_type = arc_get_compression(data);
|
||||||
uint8_t complevel = arc_get_complevel(data);
|
uint8_t complevel = arc_get_complevel(data);
|
||||||
|
|
||||||
@ -3837,22 +3843,21 @@ dbuf_hold_copy(dnode_t *dn, dmu_buf_impl_t *db)
|
|||||||
uint8_t mac[ZIO_DATA_MAC_LEN];
|
uint8_t mac[ZIO_DATA_MAC_LEN];
|
||||||
|
|
||||||
arc_get_raw_params(data, &byteorder, salt, iv, mac);
|
arc_get_raw_params(data, &byteorder, salt, iv, mac);
|
||||||
dbuf_set_data(db, arc_alloc_raw_buf(dn->dn_objset->os_spa, db,
|
db_data = arc_alloc_raw_buf(dn->dn_objset->os_spa, db,
|
||||||
dmu_objset_id(dn->dn_objset), byteorder, salt, iv, mac,
|
dmu_objset_id(dn->dn_objset), byteorder, salt, iv, mac,
|
||||||
dn->dn_type, arc_buf_size(data), arc_buf_lsize(data),
|
dn->dn_type, arc_buf_size(data), arc_buf_lsize(data),
|
||||||
compress_type, complevel));
|
compress_type, complevel);
|
||||||
} else if (compress_type != ZIO_COMPRESS_OFF) {
|
} else if (compress_type != ZIO_COMPRESS_OFF) {
|
||||||
dbuf_set_data(db, arc_alloc_compressed_buf(
|
db_data = arc_alloc_compressed_buf(
|
||||||
dn->dn_objset->os_spa, db, arc_buf_size(data),
|
dn->dn_objset->os_spa, db, arc_buf_size(data),
|
||||||
arc_buf_lsize(data), compress_type, complevel));
|
arc_buf_lsize(data), compress_type, complevel);
|
||||||
} else {
|
} else {
|
||||||
dbuf_set_data(db, arc_alloc_buf(dn->dn_objset->os_spa, db,
|
db_data = arc_alloc_buf(dn->dn_objset->os_spa, db,
|
||||||
DBUF_GET_BUFC_TYPE(db), db->db.db_size));
|
DBUF_GET_BUFC_TYPE(db), db->db.db_size);
|
||||||
}
|
}
|
||||||
|
memcpy(db_data->b_data, data->b_data, arc_buf_size(data));
|
||||||
|
|
||||||
rw_enter(&db->db_rwlock, RW_WRITER);
|
dbuf_set_data(db, db_data);
|
||||||
memcpy(db->db.db_data, data->b_data, arc_buf_size(data));
|
|
||||||
rw_exit(&db->db_rwlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3913,6 +3918,7 @@ dbuf_hold_impl(dnode_t *dn, uint8_t level, uint64_t blkid,
|
|||||||
|
|
||||||
if (db->db_buf != NULL) {
|
if (db->db_buf != NULL) {
|
||||||
arc_buf_access(db->db_buf);
|
arc_buf_access(db->db_buf);
|
||||||
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
ASSERT3P(db->db.db_data, ==, db->db_buf->b_data);
|
ASSERT3P(db->db.db_data, ==, db->db_buf->b_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2272,8 +2272,10 @@ dmu_objset_userquota_find_data(dmu_buf_impl_t *db, dmu_tx_t *tx)
|
|||||||
dbuf_dirty_record_t *dr;
|
dbuf_dirty_record_t *dr;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
if (db->db_dirtycnt == 0)
|
if (db->db_dirtycnt == 0) {
|
||||||
|
ASSERT(MUTEX_HELD(&db->db_mtx));
|
||||||
return (db->db.db_data); /* Nothing is changing */
|
return (db->db.db_data); /* Nothing is changing */
|
||||||
|
}
|
||||||
|
|
||||||
dr = dbuf_find_dirty_eq(db, tx->tx_txg);
|
dr = dbuf_find_dirty_eq(db, tx->tx_txg);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user