diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 72c597609..d2d61819c 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -2137,7 +2137,9 @@ dbuf_release_bp(dmu_buf_impl_t *db) list_link_active(&os->os_dsl_dataset->ds_synced_link)); ASSERT(db->db_parent == NULL || arc_released(db->db_parent->db_buf)); + mutex_enter(&db->db_mtx); (void) arc_release(db->db_buf, db); + mutex_exit(&db->db_mtx); } /* diff --git a/module/zfs/sa.c b/module/zfs/sa.c index 7ad25d4d8..bd565bb71 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -1250,10 +1250,15 @@ sa_byteswap(sa_handle_t *hdl, sa_buf_type_t buftype) db = SA_GET_DB(hdl, buftype); - if (buftype == SA_SPILL) { + /* + * Acquire db_mtx to protect against concurrent access to the buffer + * by dmu_objset_userquota_get_ids() while we perform byte-swapping. + * We also need it for doing arc_release()/arc_buf_freeze(). + */ + mutex_enter(&db->db_mtx); + + if (buftype == SA_SPILL) arc_release(db->db_buf, NULL); - arc_buf_thaw(db->db_buf); - } sa_hdr_phys->sa_magic = BSWAP_32(sa_hdr_phys->sa_magic); sa_hdr_phys->sa_layout_info = BSWAP_16(sa_hdr_phys->sa_layout_info); @@ -1273,7 +1278,9 @@ sa_byteswap(sa_handle_t *hdl, sa_buf_type_t buftype) sa_byteswap_cb, NULL, hdl); if (buftype == SA_SPILL) - arc_buf_freeze(((dmu_buf_impl_t *)hdl->sa_spill)->db_buf); + arc_buf_freeze(db->db_buf); + + mutex_exit(&db->db_mtx); } static int