Print this page
5814 bpobj_iterate_impl(): Close a refcount leak iterating on a sublist.
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Paul Dagnelie <paul.dagnelie@delphix.com>
Reviewed by: Simon Klinkert <simon.klinkert@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
5812 assertion failed in zrl_tryenter(): zr_owner==NULL
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Will Andrews <will@freebsd.org>
Approved by: Gordon Ross <gwr@nexenta.com>
5810 zdb should print details of bpobj
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Will Andrews <will@freebsd.org>
Reviewed by: Simon Klinkert <simon.klinkert@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>

*** 174,189 **** bpo->bpo_havesubobj = (doi.doi_bonus_size > BPOBJ_SIZE_V1); bpo->bpo_phys = bpo->bpo_dbuf->db_data; return (0); } - boolean_t - bpobj_is_open(const bpobj_t *bpo) - { - return (bpo->bpo_object != 0); - } - void bpobj_close(bpobj_t *bpo) { /* Lame workaround for closing a bpobj that was never opened. */ if (bpo->bpo_object == 0) --- 174,183 ----
*** 198,212 **** bpo->bpo_object = 0; mutex_destroy(&bpo->bpo_lock); } ! boolean_t ! bpobj_is_empty(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) --- 192,206 ---- bpo->bpo_object = 0; 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)
*** 215,227 **** int epb; int64_t i; int err = 0; dmu_buf_t *dbuf = NULL; - ASSERT(bpobj_is_open(bpo)); mutex_enter(&bpo->bpo_lock); if (free) dmu_buf_will_dirty(bpo->bpo_dbuf, tx); for (i = bpo->bpo_phys->bpo_num_blkptrs - 1; i >= 0; i--) { blkptr_t *bparray; --- 209,223 ---- int epb; int64_t i; int err = 0; dmu_buf_t *dbuf = NULL; mutex_enter(&bpo->bpo_lock); + if (!bpobj_hasentries(bpo)) + goto out; + if (free) dmu_buf_will_dirty(bpo->bpo_dbuf, tx); for (i = bpo->bpo_phys->bpo_num_blkptrs - 1; i >= 0; i--) { blkptr_t *bparray;
*** 347,357 **** (i + 1) * sizeof (uint64_t), -1ULL, tx)); } out: /* If there are no entries, there should be no bytes. */ ! if (bpobj_is_empty(bpo)) { ASSERT0(bpo->bpo_phys->bpo_bytes); ASSERT0(bpo->bpo_phys->bpo_comp); ASSERT0(bpo->bpo_phys->bpo_uncomp); } --- 343,353 ---- (i + 1) * sizeof (uint64_t), -1ULL, tx)); } out: /* If there are no entries, there should be no bytes. */ ! if (!bpobj_hasentries(bpo)) { ASSERT0(bpo->bpo_phys->bpo_bytes); ASSERT0(bpo->bpo_phys->bpo_comp); ASSERT0(bpo->bpo_phys->bpo_uncomp); }
*** 382,393 **** bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) { bpobj_t subbpo; uint64_t used, comp, uncomp, subsubobjs; - ASSERT(bpobj_is_open(bpo)); - ASSERT(subobj != 0); ASSERT(bpo->bpo_havesubobj); ASSERT(bpo->bpo_havecomp); ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj); if (subobj == dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj) { --- 378,387 ----
*** 396,406 **** } VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj)); VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp)); ! if (bpobj_is_empty(&subbpo)) { /* No point in having an empty subobj. */ bpobj_close(&subbpo); bpobj_free(bpo->bpo_os, subobj, tx); return; } --- 390,400 ---- } VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj)); VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp)); ! if (!bpobj_hasentries(&subbpo)) { /* No point in having an empty subobj. */ bpobj_close(&subbpo); bpobj_free(bpo->bpo_os, subobj, tx); return; }
*** 470,480 **** blkptr_t stored_bp = *bp; uint64_t offset; int blkoff; blkptr_t *bparray; - ASSERT(bpobj_is_open(bpo)); ASSERT(!BP_IS_HOLE(bp)); ASSERT(bpo->bpo_object != dmu_objset_pool(bpo->bpo_os)->dp_empty_bpobj); if (BP_IS_EMBEDDED(bp)) { /* --- 464,473 ----
*** 556,566 **** } int bpobj_space(bpobj_t *bpo, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) { - ASSERT(bpobj_is_open(bpo)); mutex_enter(&bpo->bpo_lock); *usedp = bpo->bpo_phys->bpo_bytes; if (bpo->bpo_havecomp) { *compp = bpo->bpo_phys->bpo_comp; --- 549,558 ----
*** 583,594 **** uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) { struct space_range_arg sra = { 0 }; int err; - ASSERT(bpobj_is_open(bpo)); - /* * As an optimization, if they want the whole txg range, just * get bpo_bytes rather than iterating over the bps. */ if (mintxg < TXG_INITIAL && maxtxg == UINT64_MAX && bpo->bpo_havecomp) --- 575,584 ----