diff --git a/include/sys/dsl_scan.h b/include/sys/dsl_scan.h index bf8c5ac824a1..5d40d6fed6a7 100644 --- a/include/sys/dsl_scan.h +++ b/include/sys/dsl_scan.h @@ -62,7 +62,7 @@ typedef struct dsl_scan_phys { uint64_t scn_errors; /* scan I/O error count */ uint64_t scn_ddt_class_max; ddt_bookmark_t scn_ddt_bookmark; - zbookmark_t scn_bookmark; + zbookmark_phys_t scn_bookmark; uint64_t scn_flags; /* dsl_scan_flags_t */ } dsl_scan_phys_t; diff --git a/include/sys/spa.h b/include/sys/spa.h index e7cbff806d98..6553b80fbc9f 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -52,6 +52,7 @@ typedef struct spa_aux_vdev spa_aux_vdev_t; typedef struct ddt ddt_t; typedef struct ddt_entry ddt_entry_t; typedef struct zbookmark zbookmark_t; +typedef struct zbookmark_phys zbookmark_phys_t; struct dsl_pool; struct dsl_dataset; diff --git a/include/sys/zio.h b/include/sys/zio.h index d4350badc100..7af136862574 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -255,6 +255,13 @@ extern const char *zio_type_name[ZIO_TYPES]; * Therefore it must not change size or alignment between 32/64 bit * compilation options. */ +struct zbookmark_phys { + uint64_t zb_objset; + uint64_t zb_object; + int64_t zb_level; + uint64_t zb_blkid; +}; + struct zbookmark { uint64_t zb_objset; uint64_t zb_object; @@ -272,6 +279,14 @@ struct zbookmark { (zb)->zb_func = FTAG; \ } +#define SET_BOOKMARK_PHYS(zb, objset, object, level, blkid) \ +{ \ + (zb)->zb_objset = objset; \ + (zb)->zb_object = object; \ + (zb)->zb_level = level; \ + (zb)->zb_blkid = blkid; \ +} + #define ZB_DESTROYED_OBJSET (-1ULL) #define ZB_ROOT_OBJECT (0ULL) @@ -588,6 +603,14 @@ extern void spa_handle_ignored_writes(spa_t *spa); /* zbookmark functions */ boolean_t zbookmark_is_before(const struct dnode_phys *dnp, const zbookmark_t *zb1, const zbookmark_t *zb2); +static inline boolean_t zbookmark_is_before_phys(const struct dnode_phys *dnp, + const zbookmark_t *zb1, const zbookmark_phys_t *zb2) +{ + zbookmark_t zb2a; + SET_BOOKMARK_PHYS(&zb2a, zb2->zb_objset, zb2->zb_object, + zb2->zb_level, zb2->zb_blkid); + return zbookmark_is_before(dnp, zb1, &zb2a); +} #ifdef __cplusplus } diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index ea04507813f7..09cd55b63fc9 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -123,7 +123,7 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t txg) err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SCAN, sizeof (uint64_t), SCAN_PHYS_NUMINTS, &scn->scn_phys); - if (err == ENOENT) + if (err == ENOENT || err == EOVERFLOW) return (0); else if (err) return (err); @@ -421,7 +421,8 @@ dsl_scan_check_pause(dsl_scan_t *scn, const zbookmark_t *zb) (longlong_t)zb->zb_object, (longlong_t)zb->zb_level, (longlong_t)zb->zb_blkid); - scn->scn_phys.scn_bookmark = *zb; + SET_BOOKMARK_PHYS(&scn->scn_phys.scn_bookmark, zb->zb_objset, + zb->zb_object, zb->zb_level, zb->zb_blkid); } dprintf("pausing at DDT bookmark %llx/%llx/%llx/%llx\n", (longlong_t)scn->scn_phys.scn_ddt_bookmark.ddb_class, @@ -558,7 +559,7 @@ dsl_scan_check_resume(dsl_scan_t *scn, const dnode_phys_t *dnp, * If we already visited this bp & everything below (in * a prior txg sync), don't bother doing it again. */ - if (zbookmark_is_before(dnp, zb, &scn->scn_phys.scn_bookmark)) + if (zbookmark_is_before_phys(dnp, zb, &scn->scn_phys.scn_bookmark)) return (B_TRUE); /* @@ -823,7 +824,7 @@ dsl_scan_ds_destroyed(dsl_dataset_t *ds, dmu_tx_t *tx) (u_longlong_t)ds->ds_phys->ds_next_snap_obj); scn->scn_phys.scn_flags |= DSF_VISIT_DS_AGAIN; } else { - SET_BOOKMARK(&scn->scn_phys.scn_bookmark, + SET_BOOKMARK_PHYS(&scn->scn_phys.scn_bookmark, ZB_DESTROYED_OBJSET, 0, 0, 0); zfs_dbgmsg("destroying ds %llu; currently traversing; " "reset bookmark to -1,0,0,0",