]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/dsl_scan.c
Verify block pointers before writing them out
[mirror_zfs.git] / module / zfs / dsl_scan.c
index 2cc77eab62753a2828c6e137e79737aeeb2a2dea..d398b6705551575918be7f6f9759047fe66422ad 100644 (file)
@@ -47,6 +47,7 @@
 #include <sys/vdev_impl.h>
 #include <sys/zil_impl.h>
 #include <sys/zio_checksum.h>
+#include <sys/brt.h>
 #include <sys/ddt.h>
 #include <sys/sa.h>
 #include <sys/sa_impl.h>
@@ -1880,7 +1881,7 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype,
        if (dnp != NULL &&
            dnp->dn_bonuslen > DN_MAX_BONUS_LEN(dnp)) {
                scn->scn_phys.scn_errors++;
-               spa_log_error(spa, zb);
+               spa_log_error(spa, zb, &bp->blk_birth);
                return (SET_ERROR(EINVAL));
        }
 
@@ -1969,13 +1970,14 @@ dsl_scan_recurse(dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype,
                            DMU_USERUSED_OBJECT, tx);
                }
                arc_buf_destroy(buf, &buf);
-       } else if (!zfs_blkptr_verify(spa, bp, B_FALSE, BLK_VERIFY_LOG)) {
+       } else if (!zfs_blkptr_verify(spa, bp,
+           BLK_CONFIG_NEEDED, BLK_VERIFY_LOG)) {
                /*
                 * Sanity check the block pointer contents, this is handled
                 * by arc_read() for the cases above.
                 */
                scn->scn_phys.scn_errors++;
-               spa_log_error(spa, zb);
+               spa_log_error(spa, zb, &bp->blk_birth);
                return (SET_ERROR(EINVAL));
        }
 
@@ -2038,6 +2040,21 @@ dsl_scan_visitbp(blkptr_t *bp, const zbookmark_phys_t *zb,
                return;
        }
 
+       /*
+        * Check if this block contradicts any filesystem flags.
+        */
+       spa_feature_t f = SPA_FEATURE_LARGE_BLOCKS;
+       if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE)
+               ASSERT(dsl_dataset_feature_is_active(ds, f));
+
+       f = zio_checksum_to_feature(BP_GET_CHECKSUM(bp));
+       if (f != SPA_FEATURE_NONE)
+               ASSERT(dsl_dataset_feature_is_active(ds, f));
+
+       f = zio_compress_to_feature(BP_GET_COMPRESS(bp));
+       if (f != SPA_FEATURE_NONE)
+               ASSERT(dsl_dataset_feature_is_active(ds, f));
+
        if (bp->blk_birth <= scn->scn_phys.scn_cur_min_txg) {
                scn->scn_lt_min_this_txg++;
                return;
@@ -3484,11 +3501,12 @@ dsl_process_async_destroys(dsl_pool_t *dp, dmu_tx_t *tx)
                scn->scn_dedup_frees_this_txg = 0;
 
                /*
-                * Write out changes to the DDT that may be required as a
-                * result of the blocks freed.  This ensures that the DDT
-                * is clean when a scrub/resilver runs.
+                * Write out changes to the DDT and the BRT that may be required
+                * as a result of the blocks freed.  This ensures that the DDT
+                * and the BRT are clean when a scrub/resilver runs.
                 */
                ddt_sync(spa, tx->tx_txg);
+               brt_sync(spa, tx->tx_txg);
        }
        if (err != 0)
                return (err);