Print this page
6267 dn_bonus evicted too early
Reviewed by: Richard Yao <ryao@gentoo.org>
Reviewed by: Xin LI <delphij@freebsd.org>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>

@@ -422,10 +422,11 @@
                         dbuf_clear(db);
 
                         db_next = AVL_NEXT(&dn->dn_dbufs, &db_marker);
                         avl_remove(&dn->dn_dbufs, &db_marker);
                 } else {
+                        db->db_pending_evict = TRUE;
                         mutex_exit(&db->db_mtx);
                         db_next = AVL_NEXT(&dn->dn_dbufs, db);
                 }
         }
         mutex_exit(&dn->dn_dbufs_mtx);

@@ -435,15 +436,19 @@
 
 void
 dnode_evict_bonus(dnode_t *dn)
 {
         rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
-        if (dn->dn_bonus && refcount_is_zero(&dn->dn_bonus->db_holds)) {
+        if (dn->dn_bonus != NULL) {
+                if (refcount_is_zero(&dn->dn_bonus->db_holds)) {
                 mutex_enter(&dn->dn_bonus->db_mtx);
                 dbuf_evict(dn->dn_bonus);
                 dn->dn_bonus = NULL;
+                } else {
+                        dn->dn_bonus->db_pending_evict = TRUE;
         }
+        }
         rw_exit(&dn->dn_struct_rwlock);
 }
 
 static void
 dnode_undirty_dbufs(list_t *list)

@@ -490,11 +495,10 @@
         ASSERT0(DN_USED_BYTES(dn->dn_phys));
         ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr));
 
         dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]);
         dnode_evict_dbufs(dn);
-        ASSERT(avl_is_empty(&dn->dn_dbufs));
 
         /*
          * XXX - It would be nice to assert this, but we may still
          * have residual holds from async evictions from the arc...
          *