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,16 +174,10 @@
         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)

@@ -198,15 +192,15 @@
         bpo->bpo_object = 0;
 
         mutex_destroy(&bpo->bpo_lock);
 }
 
-boolean_t
-bpobj_is_empty(bpobj_t *bpo)
+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));
+        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,13 +209,15 @@
         int epb;
         int64_t i;
         int err = 0;
         dmu_buf_t *dbuf = NULL;
 
-        ASSERT(bpobj_is_open(bpo));
         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,11 +343,11 @@
                     (i + 1) * sizeof (uint64_t), -1ULL, tx));
         }
 
 out:
         /* If there are no entries, there should be no bytes. */
-        if (bpobj_is_empty(bpo)) {
+        if (!bpobj_hasentries(bpo)) {
                 ASSERT0(bpo->bpo_phys->bpo_bytes);
                 ASSERT0(bpo->bpo_phys->bpo_comp);
                 ASSERT0(bpo->bpo_phys->bpo_uncomp);
         }
 

@@ -382,12 +378,10 @@
 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) {

@@ -396,11 +390,11 @@
         }
 
         VERIFY3U(0, ==, bpobj_open(&subbpo, bpo->bpo_os, subobj));
         VERIFY3U(0, ==, bpobj_space(&subbpo, &used, &comp, &uncomp));
 
-        if (bpobj_is_empty(&subbpo)) {
+        if (!bpobj_hasentries(&subbpo)) {
                 /* No point in having an empty subobj. */
                 bpobj_close(&subbpo);
                 bpobj_free(bpo->bpo_os, subobj, tx);
                 return;
         }

@@ -470,11 +464,10 @@
         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)) {
                 /*

@@ -556,11 +549,10 @@
 }
 
 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;

@@ -583,12 +575,10 @@
     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)