Remove db_state DB_NOFILL checks from syncing context
Syncing context should not depend on current state of dbuf, which could already change several times in later transaction groups, but rely solely on dirty record for the transaction group being synced. Some of the checks seem already impossible, while instead of others I think we should better check for absence of data in the specific dirty record rather than DB_NOFILL. Reviewed-by: Robert Evans <evansr@google.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Sponsored by: iXsystems, Inc. Closes #16057
This commit is contained in:
parent
5e5fd0a178
commit
aa5445c28b
|
@ -4596,11 +4596,10 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
|||
if (os->os_encrypted && dn->dn_object == DMU_META_DNODE_OBJECT)
|
||||
dbuf_prepare_encrypted_dnode_leaf(dr);
|
||||
|
||||
if (db->db_state != DB_NOFILL &&
|
||||
if (*datap != NULL && *datap == db->db_buf &&
|
||||
dn->dn_object != DMU_META_DNODE_OBJECT &&
|
||||
zfs_refcount_count(&db->db_holds) > 1 &&
|
||||
dr->dt.dl.dr_override_state != DR_OVERRIDDEN &&
|
||||
*datap == db->db_buf) {
|
||||
dr->dt.dl.dr_override_state != DR_OVERRIDDEN) {
|
||||
/*
|
||||
* If this buffer is currently "in use" (i.e., there
|
||||
* are active holds and db_data still references it),
|
||||
|
@ -4889,12 +4888,10 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
|
|||
if (db->db_level == 0) {
|
||||
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
|
||||
ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN);
|
||||
if (db->db_state != DB_NOFILL) {
|
||||
if (dr->dt.dl.dr_data != NULL &&
|
||||
dr->dt.dl.dr_data != db->db_buf) {
|
||||
arc_buf_destroy(dr->dt.dl.dr_data, db);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
|
||||
ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
|
||||
|
@ -5096,22 +5093,19 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
|
|||
|
||||
os = dn->dn_objset;
|
||||
|
||||
if (db->db_state != DB_NOFILL) {
|
||||
if (db->db_level > 0 || dn->dn_type == DMU_OT_DNODE) {
|
||||
/*
|
||||
* Private object buffers are released here rather
|
||||
* than in dbuf_dirty() since they are only modified
|
||||
* in the syncing context and we don't want the
|
||||
* overhead of making multiple copies of the data.
|
||||
* Private object buffers are released here rather than in
|
||||
* dbuf_dirty() since they are only modified in the syncing
|
||||
* context and we don't want the overhead of making multiple
|
||||
* copies of the data.
|
||||
*/
|
||||
if (BP_IS_HOLE(db->db_blkptr)) {
|
||||
if (BP_IS_HOLE(db->db_blkptr))
|
||||
arc_buf_thaw(data);
|
||||
} else {
|
||||
else
|
||||
dbuf_release_bp(db);
|
||||
}
|
||||
dbuf_remap(dn, db, tx);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent != dn->dn_dbuf) {
|
||||
/* Our parent is an indirect block. */
|
||||
|
@ -5146,7 +5140,7 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
|
|||
|
||||
if (db->db_blkid == DMU_SPILL_BLKID)
|
||||
wp_flag = WP_SPILL;
|
||||
wp_flag |= (db->db_state == DB_NOFILL) ? WP_NOFILL : 0;
|
||||
wp_flag |= (data == NULL) ? WP_NOFILL : 0;
|
||||
|
||||
dmu_write_policy(os, dn, db->db_level, wp_flag, &zp);
|
||||
|
||||
|
@ -5178,7 +5172,7 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
|
|||
dr->dt.dl.dr_copies, dr->dt.dl.dr_nopwrite,
|
||||
dr->dt.dl.dr_brtwrite);
|
||||
mutex_exit(&db->db_mtx);
|
||||
} else if (db->db_state == DB_NOFILL) {
|
||||
} else if (data == NULL) {
|
||||
ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF ||
|
||||
zp.zp_checksum == ZIO_CHECKSUM_NOPARITY);
|
||||
dr->dr_zio = zio_write(pio, os->os_spa, txg,
|
||||
|
|
Loading…
Reference in New Issue