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,12 +4838,10 @@ 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);
|
||||||
ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
|
ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
|
||||||
|
@ -5042,22 +5039,19 @@ 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
|
* Private object buffers are released here rather than in
|
||||||
* than in dbuf_dirty() since they are only modified
|
* dbuf_dirty() since they are only modified in the syncing
|
||||||
* in the syncing context and we don't want the
|
* context and we don't want the overhead of making multiple
|
||||||
* overhead of making multiple copies of the data.
|
* 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) {
|
||||||
/* Our parent is an indirect block. */
|
/* Our parent is an indirect block. */
|
||||||
|
@ -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