mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-06-25 02:28:01 +03:00
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:
parent
3ff2eca0be
commit
4ae931aa93
@ -1185,16 +1185,9 @@ 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);
|
||||||
/*
|
ASSERT3P(db->db_blkptr, ==,
|
||||||
* dnode_grow_indblksz() can make this fail if we don't
|
((blkptr_t *)db->db_parent->db.db_data +
|
||||||
* have the parent's rwlock. XXX indblksz no longer
|
db->db_blkid % epb));
|
||||||
* grows. safe to do this now?
|
|
||||||
*/
|
|
||||||
if (RW_LOCK_HELD(&db->db_parent->db_rwlock)) {
|
|
||||||
ASSERT3P(db->db_blkptr, ==,
|
|
||||||
((blkptr_t *)db->db_parent->db.db_data +
|
|
||||||
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)) &&
|
||||||
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user