Skip to content

Commit 35b2d39

Browse files
authored
Lock db_mtx around arc_release() in couple places
* Lock db_mtx around arc_release() in dbuf_release_bp() While this function is called only in sync context, the same buffer can be touched by dbuf_hold_impl() in open context, creating races. All other accesses to arc_release() are already protected by db_mtx, so just take it here too. Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com> * Lock db_mtx in sa_byteswap() While SA code seems protected by sa_lock, there is a back door of dmu_objset_userquota_get_ids(), that may hold and access the dbuf without sa_lock, relying only on db_mtx. Taking db_mtx here should protect both the arc_release() and the data for db_buf. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com> Closes #18146
1 parent cd895f0 commit 35b2d39

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

module/zfs/dbuf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,7 +2137,9 @@ dbuf_release_bp(dmu_buf_impl_t *db)
21372137
list_link_active(&os->os_dsl_dataset->ds_synced_link));
21382138
ASSERT(db->db_parent == NULL || arc_released(db->db_parent->db_buf));
21392139

2140+
mutex_enter(&db->db_mtx);
21402141
(void) arc_release(db->db_buf, db);
2142+
mutex_exit(&db->db_mtx);
21412143
}
21422144

21432145
/*

module/zfs/sa.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,10 +1250,15 @@ sa_byteswap(sa_handle_t *hdl, sa_buf_type_t buftype)
12501250

12511251
db = SA_GET_DB(hdl, buftype);
12521252

1253-
if (buftype == SA_SPILL) {
1253+
/*
1254+
* Acquire db_mtx to protect against concurrent access to the buffer
1255+
* by dmu_objset_userquota_get_ids() while we perform byte-swapping.
1256+
* We also need it for doing arc_release()/arc_buf_freeze().
1257+
*/
1258+
mutex_enter(&db->db_mtx);
1259+
1260+
if (buftype == SA_SPILL)
12541261
arc_release(db->db_buf, NULL);
1255-
arc_buf_thaw(db->db_buf);
1256-
}
12571262

12581263
sa_hdr_phys->sa_magic = BSWAP_32(sa_hdr_phys->sa_magic);
12591264
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)
12731278
sa_byteswap_cb, NULL, hdl);
12741279

12751280
if (buftype == SA_SPILL)
1276-
arc_buf_freeze(((dmu_buf_impl_t *)hdl->sa_spill)->db_buf);
1281+
arc_buf_freeze(db->db_buf);
1282+
1283+
mutex_exit(&db->db_mtx);
12771284
}
12781285

12791286
static int

0 commit comments

Comments
 (0)