diff options
author | Matthew Ahrens <[email protected]> | 2014-06-05 13:34:21 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-08-06 14:44:10 -0700 |
commit | 1fa8f795d586208defe2ed499c691c5bc2e28eee (patch) | |
tree | 8bed6d3a5b9d1737426f458b4a2762f675679b16 /module/zfs/dmu_traverse.c | |
parent | 3bec585e6c86de869ba1bf132567ed2a01d6a15b (diff) |
Illumos 4881 - zfs send performance regression with embedded data
4881 zfs send performance degradation when embedded block pointers
are encountered
Reviewed by: George Wilson <[email protected]>
Reviewed by: Christopher Siden <[email protected]>
Approved by: Dan McDonald <[email protected]>
References:
https://www.illumos.org/issues/4881
https://github.com/illumos/illumos-gate/commit/06315b7
Ported by: Tim Chase <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2547
Diffstat (limited to 'module/zfs/dmu_traverse.c')
-rw-r--r-- | module/zfs/dmu_traverse.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/module/zfs/dmu_traverse.c b/module/zfs/dmu_traverse.c index fe352469b..77843f438 100644 --- a/module/zfs/dmu_traverse.c +++ b/module/zfs/dmu_traverse.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ #include <sys/zfs_context.h> @@ -197,6 +197,16 @@ traverse_prefetch_metadata(traverse_data_t *td, ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb); } +static boolean_t +prefetch_needed(prefetch_data_t *pfd, const blkptr_t *bp) +{ + ASSERT(pfd->pd_flags & TRAVERSE_PREFETCH_DATA); + if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp) || + BP_GET_TYPE(bp) == DMU_OT_INTENT_LOG) + return (B_FALSE); + return (B_TRUE); +} + static int traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb) @@ -239,16 +249,8 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, return (0); } - if (BP_IS_HOLE(bp)) { - err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg); - if (err != 0) - goto post; - return (0); - } - - if (td->td_pfd && !td->td_pfd->pd_exited && - ((td->td_pfd->pd_flags & TRAVERSE_PREFETCH_DATA) || - BP_GET_TYPE(bp) == DMU_OT_DNODE || BP_GET_LEVEL(bp) > 0)) { + if (td->td_pfd != NULL && !td->td_pfd->pd_exited && + prefetch_needed(td->td_pfd, bp)) { mutex_enter(&td->td_pfd->pd_mtx); ASSERT(td->td_pfd->pd_blks_fetched >= 0); while (td->td_pfd->pd_blks_fetched == 0 && @@ -259,6 +261,13 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp, mutex_exit(&td->td_pfd->pd_mtx); } + if (BP_IS_HOLE(bp)) { + err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg); + if (err != 0) + goto post; + return (0); + } + if (td->td_flags & TRAVERSE_PRE) { err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg); @@ -448,10 +457,7 @@ traverse_prefetcher(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, if (pfd->pd_cancel) return (SET_ERROR(EINTR)); - if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp) || - !((pfd->pd_flags & TRAVERSE_PREFETCH_DATA) || - BP_GET_TYPE(bp) == DMU_OT_DNODE || BP_GET_LEVEL(bp) > 0) || - BP_GET_TYPE(bp) == DMU_OT_INTENT_LOG) + if (!prefetch_needed(pfd, bp)) return (0); mutex_enter(&pfd->pd_mtx); |