| 781 | } |
| 782 | |
| 783 | void |
| 784 | bpobj_enqueue(bpobj_t *bpo, const blkptr_t *bp, boolean_t bp_freed, |
| 785 | dmu_tx_t *tx) |
| 786 | { |
| 787 | blkptr_t stored_bp = *bp; |
| 788 | uint64_t offset; |
| 789 | int blkoff; |
| 790 | blkptr_t *bparray; |
| 791 | |
| 792 | ASSERT(bpobj_is_open(bpo)); |
| 793 | ASSERT(!BP_IS_HOLE(bp)); |
| 794 | ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj); |
| 795 | |
| 796 | if (BP_IS_EMBEDDED(bp)) { |
| 797 | /* |
| 798 | * The bpobj will compress better without the payload. |
| 799 | * |
| 800 | * Note that we store EMBEDDED bp's because they have an |
| 801 | * uncompressed size, which must be accounted for. An |
| 802 | * alternative would be to add their size to bpo_uncomp |
| 803 | * without storing the bp, but that would create additional |
| 804 | * complications: bpo_uncomp would be inconsistent with the |
| 805 | * set of BP's stored, and bpobj_iterate() wouldn't visit |
| 806 | * all the space accounted for in the bpobj. |
| 807 | */ |
| 808 | bzero(&stored_bp, sizeof (stored_bp)); |
| 809 | stored_bp.blk_prop = bp->blk_prop; |
| 810 | stored_bp.blk_birth = bp->blk_birth; |
| 811 | } else if (!BP_GET_DEDUP(bp)) { |
| 812 | /* The bpobj will compress better without the checksum */ |
| 813 | bzero(&stored_bp.blk_cksum, sizeof (stored_bp.blk_cksum)); |
| 814 | } |
| 815 | |
| 816 | stored_bp.blk_fill = 0; |
| 817 | BP_SET_FREE(&stored_bp, bp_freed); |
| 818 | |
| 819 | mutex_enter(&bpo->bpo_lock); |
| 820 | |
| 821 | offset = bpo->bpo_phys->bpo_num_blkptrs * sizeof (stored_bp); |
| 822 | blkoff = P2PHASE(bpo->bpo_phys->bpo_num_blkptrs, bpo->bpo_epb); |
| 823 | |
| 824 | if (bpo->bpo_cached_dbuf == NULL || |
| 825 | offset < bpo->bpo_cached_dbuf->db_offset || |
| 826 | offset >= bpo->bpo_cached_dbuf->db_offset + |
| 827 | bpo->bpo_cached_dbuf->db_size) { |
| 828 | if (bpo->bpo_cached_dbuf) |
| 829 | dmu_buf_rele(bpo->bpo_cached_dbuf, bpo); |
| 830 | VERIFY3U(0, ==, dmu_buf_hold(bpo->bpo_os, bpo->bpo_object, |
| 831 | offset, bpo, &bpo->bpo_cached_dbuf, 0)); |
| 832 | } |
| 833 | |
| 834 | dmu_buf_will_dirty(bpo->bpo_cached_dbuf, tx); |
| 835 | bparray = bpo->bpo_cached_dbuf->db_data; |
| 836 | bparray[blkoff] = stored_bp; |
| 837 | |
| 838 | dmu_buf_will_dirty(bpo->bpo_dbuf, tx); |
| 839 | bpo->bpo_phys->bpo_num_blkptrs++; |
| 840 | int sign = bp_freed ? -1 : +1; |
no test coverage detected