diff options
Diffstat (limited to 'usr/src/uts/common/fs/zfs/dsl_scrub.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_scrub.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/usr/src/uts/common/fs/zfs/dsl_scrub.c b/usr/src/uts/common/fs/zfs/dsl_scrub.c index dbad7b60ab..d8c383a158 100644 --- a/usr/src/uts/common/fs/zfs/dsl_scrub.c +++ b/usr/src/uts/common/fs/zfs/dsl_scrub.c @@ -45,6 +45,8 @@ typedef int (scrub_cb_t)(dsl_pool_t *, const blkptr_t *, const zbookmark_t *); static scrub_cb_t dsl_pool_scrub_clean_cb; static dsl_syncfunc_t dsl_pool_scrub_cancel_sync; +static void scrub_visitdnode(dsl_pool_t *dp, dnode_phys_t *dnp, arc_buf_t *buf, + uint64_t objset, uint64_t object); int zfs_scrub_min_time = 1; /* scrub for at least 1 sec each txg */ int zfs_resilver_min_time = 3; /* resilver for at least 3 sec each txg */ @@ -483,7 +485,7 @@ scrub_visitbp(dsl_pool_t *dp, dnode_phys_t *dnp, } else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) { uint32_t flags = ARC_WAIT; dnode_phys_t *child_dnp; - int i, j; + int i; int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; err = arc_read(NULL, dp->dp_spa, bp, pbuf, @@ -498,20 +500,12 @@ scrub_visitbp(dsl_pool_t *dp, dnode_phys_t *dnp, child_dnp = buf->b_data; for (i = 0; i < epb; i++, child_dnp++) { - for (j = 0; j < child_dnp->dn_nblkptr; j++) { - zbookmark_t czb; - - SET_BOOKMARK(&czb, zb->zb_objset, - zb->zb_blkid * epb + i, - child_dnp->dn_nlevels - 1, j); - scrub_visitbp(dp, child_dnp, buf, - &child_dnp->dn_blkptr[j], &czb); - } + scrub_visitdnode(dp, child_dnp, buf, zb->zb_objset, + zb->zb_blkid * epb + i); } } else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) { uint32_t flags = ARC_WAIT; objset_phys_t *osp; - int j; err = arc_read_nolock(NULL, dp->dp_spa, bp, arc_getbuf_func, &buf, @@ -527,13 +521,13 @@ scrub_visitbp(dsl_pool_t *dp, dnode_phys_t *dnp, traverse_zil(dp, &osp->os_zil_header); - for (j = 0; j < osp->os_meta_dnode.dn_nblkptr; j++) { - zbookmark_t czb; - - SET_BOOKMARK(&czb, zb->zb_objset, 0, - osp->os_meta_dnode.dn_nlevels - 1, j); - scrub_visitbp(dp, &osp->os_meta_dnode, buf, - &osp->os_meta_dnode.dn_blkptr[j], &czb); + scrub_visitdnode(dp, &osp->os_meta_dnode, + buf, zb->zb_objset, 0); + if (arc_buf_size(buf) >= sizeof (objset_phys_t)) { + scrub_visitdnode(dp, &osp->os_userused_dnode, + buf, zb->zb_objset, 0); + scrub_visitdnode(dp, &osp->os_groupused_dnode, + buf, zb->zb_objset, 0); } } @@ -543,6 +537,21 @@ scrub_visitbp(dsl_pool_t *dp, dnode_phys_t *dnp, } static void +scrub_visitdnode(dsl_pool_t *dp, dnode_phys_t *dnp, arc_buf_t *buf, + uint64_t objset, uint64_t object) +{ + int j; + + for (j = 0; j < dnp->dn_nblkptr; j++) { + zbookmark_t czb; + + SET_BOOKMARK(&czb, objset, object, dnp->dn_nlevels - 1, j); + scrub_visitbp(dp, dnp, buf, &dnp->dn_blkptr[j], &czb); + } + +} + +static void scrub_visit_rootbp(dsl_pool_t *dp, dsl_dataset_t *ds, blkptr_t *bp) { zbookmark_t zb; |