diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c index 244b9b4cbc..809f7f6165 100644 --- a/module/zfs/dmu_traverse.c +++ b/module/zfs/dmu_traverse.c @@ -154,10 +154,10 @@ typedef enum resume_skip { * Otherwise returns RESUME_SKIP_NONE. */ static resume_skip_t -resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp, +resume_skip_check(const traverse_data_t *td, const dnode_phys_t *dnp, const zbookmark_phys_t *zb) { - if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume)) { + if (td->td_resume != NULL) { /* * If we already visited this bp & everything below, * don't bother doing it again. @@ -165,12 +165,7 @@ resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp, if (zbookmark_subtree_completed(dnp, zb, td->td_resume)) return (RESUME_SKIP_ALL); - /* - * If we found the block we're trying to resume from, zero - * the bookmark out to indicate that we have resumed. - */ if (memcmp(zb, td->td_resume, sizeof (*zb)) == 0) { - memset(td->td_resume, 0, sizeof (*zb)); if (td->td_flags & TRAVERSE_POST) return (RESUME_SKIP_CHILDREN); } @@ -182,7 +177,7 @@ resume_skip_check(traverse_data_t *td, const dnode_phys_t *dnp, * Returns B_TRUE, if prefetch read is issued, otherwise B_FALSE. */ static boolean_t -traverse_prefetch_metadata(traverse_data_t *td, +traverse_prefetch_metadata(traverse_data_t *td, const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_phys_t *zb) { arc_flags_t flags = ARC_FLAG_NOWAIT | ARC_FLAG_PREFETCH | @@ -192,11 +187,10 @@ traverse_prefetch_metadata(traverse_data_t *td, if (!(td->td_flags & TRAVERSE_PREFETCH_METADATA)) return (B_FALSE); /* - * If we are in the process of resuming, don't prefetch, because - * some children will not be needed (and in fact may have already - * been freed). + * If this bp is before the resume point, it may have already been + * freed. */ - if (td->td_resume != NULL && !ZB_IS_ZERO(td->td_resume)) + if (resume_skip_check(td, dnp, zb) != RESUME_SKIP_NONE) return (B_FALSE); if (BP_IS_HOLE(bp) || bp->blk_birth <= td->td_min_txg) return (B_FALSE); @@ -344,7 +338,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, SET_BOOKMARK(czb, zb->zb_objset, zb->zb_object, zb->zb_level - 1, zb->zb_blkid * epb + pidx); - if (traverse_prefetch_metadata(td, + if (traverse_prefetch_metadata(td, dnp, &((blkptr_t *)buf->b_data)[pidx], czb) == B_TRUE) { prefetched++; @@ -506,12 +500,12 @@ prefetch_dnode_metadata(traverse_data_t *td, const dnode_phys_t *dnp, for (j = 0; j < dnp->dn_nblkptr; j++) { SET_BOOKMARK(&czb, objset, object, dnp->dn_nlevels - 1, j); - traverse_prefetch_metadata(td, &dnp->dn_blkptr[j], &czb); + traverse_prefetch_metadata(td, dnp, &dnp->dn_blkptr[j], &czb); } if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) { SET_BOOKMARK(&czb, objset, object, 0, DMU_SPILL_BLKID); - traverse_prefetch_metadata(td, DN_SPILL_BLKPTR(dnp), &czb); + traverse_prefetch_metadata(td, dnp, DN_SPILL_BLKPTR(dnp), &czb); } }