]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Remove db_state DB_NOFILL checks from syncing context
authorAlexander Motin <mav@FreeBSD.org>
Mon, 8 Apr 2024 22:23:43 +0000 (18:23 -0400)
committerGitHub <noreply@github.com>
Mon, 8 Apr 2024 22:23:43 +0000 (15:23 -0700)
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

module/zfs/dbuf.c

index 8c42b116d7e1d6f4fad4e7fc92bcdf082121f19a..d9fc6cf6af34b0598eb2f464999b1496213892fd 100644 (file)
@@ -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,11 +4888,9 @@ 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);
-                       }
+               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);
@@ -5096,21 +5093,18 @@ 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.
-                        */
-                       if (BP_IS_HOLE(db->db_blkptr)) {
-                               arc_buf_thaw(data);
-                       } else {
-                               dbuf_release_bp(db);
-                       }
-                       dbuf_remap(dn, db, tx);
-               }
+       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.
+                */
+               if (BP_IS_HOLE(db->db_blkptr))
+                       arc_buf_thaw(data);
+               else
+                       dbuf_release_bp(db);
+               dbuf_remap(dn, db, tx);
        }
 
        if (parent != dn->dn_dbuf) {
@@ -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,