diff options
author | Matthew Ahrens <[email protected]> | 2014-06-05 13:19:08 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-08-01 14:28:05 -0700 |
commit | 9b67f605601c77c814037613d8129562db642a29 (patch) | |
tree | 21a3270ed7eda24858e56a9584f64f6359f4b28f /module/zfs/bpobj.c | |
parent | faf0f58c69607a15e2d1563567afb815842805de (diff) |
Illumos 4757, 4913
4757 ZFS embedded-data block pointers ("zero block compression")
4913 zfs release should not be subject to space checks
Reviewed by: Adam Leventhal <[email protected]>
Reviewed by: Max Grossman <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Christopher Siden <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Approved by: Dan McDonald <[email protected]>
References:
https://www.illumos.org/issues/4757
https://www.illumos.org/issues/4913
https://github.com/illumos/illumos-gate/commit/5d7b4d4
Porting notes:
For compatibility with the fastpath code the zio_done() function
needed to be updated. Because embedded-data block pointers do
not require DVAs to be allocated the associated vdevs will not
be marked and therefore should not be unmarked.
Ported by: Tim Chase <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2544
Diffstat (limited to 'module/zfs/bpobj.c')
-rw-r--r-- | module/zfs/bpobj.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/module/zfs/bpobj.c b/module/zfs/bpobj.c index eb3233b10..7c8f932f5 100644 --- a/module/zfs/bpobj.c +++ b/module/zfs/bpobj.c @@ -192,6 +192,13 @@ bpobj_close(bpobj_t *bpo) mutex_destroy(&bpo->bpo_lock); } +static boolean_t +bpobj_hasentries(bpobj_t *bpo) +{ + return (bpo->bpo_phys->bpo_num_blkptrs != 0 || + (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_num_subobjs != 0)); +} + static int bpobj_iterate_impl(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx, boolean_t free) @@ -332,9 +339,11 @@ bpobj_iterate_impl(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx, out: /* If there are no entries, there should be no bytes. */ - ASSERT(bpo->bpo_phys->bpo_num_blkptrs > 0 || - (bpo->bpo_havesubobj && bpo->bpo_phys->bpo_num_subobjs > 0) || - bpo->bpo_phys->bpo_bytes == 0); + if (!bpobj_hasentries(bpo)) { + ASSERT0(bpo->bpo_phys->bpo_bytes); + ASSERT0(bpo->bpo_phys->bpo_comp); + ASSERT0(bpo->bpo_phys->bpo_uncomp); + } mutex_exit(&bpo->bpo_lock); return (err); @@ -378,7 +387,7 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj)); VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp)); - if (used == 0) { + if (!bpobj_hasentries(&subbpo)) { /* No point in having an empty subobj. */ bpobj_close(&subbpo); bpobj_free(bpo->bpo_os, subobj, tx); @@ -453,13 +462,29 @@ bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, dmu_tx_t *tx) ASSERT(!BP_IS_HOLE(bp)); ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj); + if (BP_IS_EMBEDDED(bp)) { + /* + * The bpobj will compress better without the payload. + * + * Note that we store EMBEDDED bp's because they have an + * uncompressed size, which must be accounted for. An + * alternative would be to add their size to bpo_uncomp + * without storing the bp, but that would create additional + * complications: bpo_uncomp would be inconsistent with the + * set of BP's stored, and bpobj_iterate() wouldn't visit + * all the space accounted for in the bpobj. + */ + bzero(&stored_bp, sizeof (stored_bp)); + stored_bp.blk_prop = bp->blk_prop; + stored_bp.blk_birth = bp->blk_birth; + } else if (!BP_GET_DEDUP(bp)) { + /* The bpobj will compress better without the checksum */ + bzero(&stored_bp.blk_cksum, sizeof (stored_bp.blk_cksum)); + } + /* We never need the fill count. */ stored_bp.blk_fill = 0; - /* The bpobj will compress better if we can leave off the checksum */ - if (!BP_GET_DEDUP(bp)) - bzero(&stored_bp.blk_cksum, sizeof (stored_bp.blk_cksum)); - mutex_enter(&bpo->bpo_lock); offset = bpo->bpo_phys->bpo_num_blkptrs * sizeof (stored_bp); |