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
026fe79646
commit
97d7228f42
|
@ -4550,11 +4550,10 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||||
if (os->os_encrypted && dn->dn_object == DMU_META_DNODE_OBJECT)
|
if (os->os_encrypted && dn->dn_object == DMU_META_DNODE_OBJECT)
|
||||||
dbuf_prepare_encrypted_dnode_leaf(dr);
|
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 &&
|
dn->dn_object != DMU_META_DNODE_OBJECT &&
|
||||||
zfs_refcount_count(&db->db_holds) > 1 &&
|
zfs_refcount_count(&db->db_holds) > 1 &&
|
||||||
dr->dt.dl.dr_override_state != DR_OVERRIDDEN &&
|
dr->dt.dl.dr_override_state != DR_OVERRIDDEN) {
|
||||||
*datap == db->db_buf) {
|
|
||||||
/*
|
/*
|
||||||
* If this buffer is currently "in use" (i.e., there
|
* If this buffer is currently "in use" (i.e., there
|
||||||
* are active holds and db_data still references it),
|
* are active holds and db_data still references it),
|
||||||
|
@ -4839,11 +4838,9 @@ dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
|
||||||
if (db->db_level == 0) {
|
if (db->db_level == 0) {
|
||||||
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
|
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
|
||||||
ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN);
|
ASSERT(dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN);
|
||||||
if (db->db_state != DB_NOFILL) {
|
if (dr->dt.dl.dr_data != NULL &&
|
||||||
if (dr->dt.dl.dr_data != NULL &&
|
dr->dt.dl.dr_data != db->db_buf) {
|
||||||
dr->dt.dl.dr_data != db->db_buf) {
|
arc_buf_destroy(dr->dt.dl.dr_data, db);
|
||||||
arc_buf_destroy(dr->dt.dl.dr_data, db);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
|
ASSERT(list_head(&dr->dt.di.dr_children) == NULL);
|
||||||
|
@ -5042,21 +5039,18 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
|
||||||
|
|
||||||
os = dn->dn_objset;
|
os = dn->dn_objset;
|
||||||
|
|
||||||
if (db->db_state != DB_NOFILL) {
|
if (db->db_level > 0 || dn->dn_type == DMU_OT_DNODE) {
|
||||||
if (db->db_level > 0 || dn->dn_type == DMU_OT_DNODE) {
|
/*
|
||||||
/*
|
* Private object buffers are released here rather than in
|
||||||
* Private object buffers are released here rather
|
* dbuf_dirty() since they are only modified in the syncing
|
||||||
* than in dbuf_dirty() since they are only modified
|
* context and we don't want the overhead of making multiple
|
||||||
* in the syncing context and we don't want the
|
* copies of the data.
|
||||||
* 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);
|
||||||
arc_buf_thaw(data);
|
else
|
||||||
} else {
|
dbuf_release_bp(db);
|
||||||
dbuf_release_bp(db);
|
dbuf_remap(dn, db, tx);
|
||||||
}
|
|
||||||
dbuf_remap(dn, db, tx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent != dn->dn_dbuf) {
|
if (parent != dn->dn_dbuf) {
|
||||||
|
@ -5092,7 +5086,7 @@ dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx)
|
||||||
|
|
||||||
if (db->db_blkid == DMU_SPILL_BLKID)
|
if (db->db_blkid == DMU_SPILL_BLKID)
|
||||||
wp_flag = WP_SPILL;
|
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);
|
dmu_write_policy(os, dn, db->db_level, wp_flag, &zp);
|
||||||
|
|
||||||
|
@ -5124,7 +5118,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_copies, dr->dt.dl.dr_nopwrite,
|
||||||
dr->dt.dl.dr_brtwrite);
|
dr->dt.dl.dr_brtwrite);
|
||||||
mutex_exit(&db->db_mtx);
|
mutex_exit(&db->db_mtx);
|
||||||
} else if (db->db_state == DB_NOFILL) {
|
} else if (data == NULL) {
|
||||||
ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF ||
|
ASSERT(zp.zp_checksum == ZIO_CHECKSUM_OFF ||
|
||||||
zp.zp_checksum == ZIO_CHECKSUM_NOPARITY);
|
zp.zp_checksum == ZIO_CHECKSUM_NOPARITY);
|
||||||
dr->dr_zio = zio_write(pio, os->os_spa, txg,
|
dr->dr_zio = zio_write(pio, os->os_spa, txg,
|
||||||
|
|
Loading…
Reference in New Issue