Polish db_rwlock scope

dbuf_verify(): Don't need the lock, since we only compare pointers.

dbuf_findbp(): Don't need the lock, since aside of unneeded assert
we only produce the pointer, but don't de-reference it.

dnode_next_offset_level(): When working on top level indirection
should lock dnode buffer's db_rwlock, since it is our parent.  If
dnode has no buffer, then it is meta-dnode or one of quotas and we
should lock the dataset's ds_bp_rwlock instead.

Reviewed-by: Alan Somers <asomers@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #17441
This commit is contained in:
Alexander Motin 2025-06-11 14:13:48 -04:00 committed by GitHub
parent 3ff2eca0be
commit 4ae931aa93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 14 deletions

View File

@ -1185,18 +1185,11 @@ dbuf_verify(dmu_buf_impl_t *db)
ASSERT3U(db->db_parent->db_level, ==, db->db_level+1); ASSERT3U(db->db_parent->db_level, ==, db->db_level+1);
ASSERT3U(db->db_parent->db.db_object, ==, ASSERT3U(db->db_parent->db.db_object, ==,
db->db.db_object); db->db.db_object);
/*
* dnode_grow_indblksz() can make this fail if we don't
* have the parent's rwlock. XXX indblksz no longer
* grows. safe to do this now?
*/
if (RW_LOCK_HELD(&db->db_parent->db_rwlock)) {
ASSERT3P(db->db_blkptr, ==, ASSERT3P(db->db_blkptr, ==,
((blkptr_t *)db->db_parent->db.db_data + ((blkptr_t *)db->db_parent->db.db_data +
db->db_blkid % epb)); db->db_blkid % epb));
} }
} }
}
if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) && if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
(db->db_buf == NULL || db->db_buf->b_data) && (db->db_buf == NULL || db->db_buf->b_data) &&
db->db.db_data && db->db_blkid != DMU_BONUS_BLKID && db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
@ -3381,12 +3374,8 @@ dbuf_findbp(dnode_t *dn, int level, uint64_t blkid, int fail_sparse,
*parentp = NULL; *parentp = NULL;
return (err); return (err);
} }
rw_enter(&(*parentp)->db_rwlock, RW_READER);
*bpp = ((blkptr_t *)(*parentp)->db.db_data) + *bpp = ((blkptr_t *)(*parentp)->db.db_data) +
(blkid & ((1ULL << epbs) - 1)); (blkid & ((1ULL << epbs) - 1));
if (blkid > (dn->dn_phys->dn_maxblkid >> (level * epbs)))
ASSERT(BP_IS_HOLE(*bpp));
rw_exit(&(*parentp)->db_rwlock);
return (0); return (0);
} else { } else {
/* the block is referenced from the dnode */ /* the block is referenced from the dnode */

View File

@ -2559,6 +2559,11 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
error = 0; error = 0;
epb = dn->dn_phys->dn_nblkptr; epb = dn->dn_phys->dn_nblkptr;
data = dn->dn_phys->dn_blkptr; data = dn->dn_phys->dn_blkptr;
if (dn->dn_dbuf != NULL)
rw_enter(&dn->dn_dbuf->db_rwlock, RW_READER);
else if (dmu_objset_ds(dn->dn_objset) != NULL)
rrw_enter(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock,
RW_READER, FTAG);
} else { } else {
uint64_t blkid = dbuf_whichblock(dn, lvl, *offset); uint64_t blkid = dbuf_whichblock(dn, lvl, *offset);
error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db); error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db);
@ -2663,6 +2668,12 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
if (db != NULL) { if (db != NULL) {
rw_exit(&db->db_rwlock); rw_exit(&db->db_rwlock);
dbuf_rele(db, FTAG); dbuf_rele(db, FTAG);
} else {
if (dn->dn_dbuf != NULL)
rw_exit(&dn->dn_dbuf->db_rwlock);
else if (dmu_objset_ds(dn->dn_objset) != NULL)
rrw_exit(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock,
FTAG);
} }
return (error); return (error);