Print this page
3752 want more verifiable dbuf user eviction
Submitted by:   Justin Gibbs <justing@spectralogic.com>
Submitted by:   Will Andrews <willa@spectralogic.com>

@@ -375,10 +375,13 @@
 void
 dnode_evict_dbufs(dnode_t *dn)
 {
         int progress;
         int pass = 0;
+        list_t evict_list;
+
+        dmu_buf_create_user_evict_list(&evict_list);
 
         do {
                 dmu_buf_impl_t *db, marker;
                 int evicting = FALSE;
 

@@ -400,15 +403,16 @@
                                 progress = TRUE;
                                 evicting = TRUE;
                                 mutex_exit(&db->db_mtx);
                         } else if (refcount_is_zero(&db->db_holds)) {
                                 progress = TRUE;
-                                dbuf_clear(db); /* exits db_mtx for us */
+                                dbuf_clear(db, &evict_list); /* exits db_mtx */
                         } else {
                                 mutex_exit(&db->db_mtx);
                         }
-
+                        ASSERT(MUTEX_NOT_HELD(&db->db_mtx));
+                        dmu_buf_process_user_evicts(&evict_list);
                 }
                 list_remove(&dn->dn_dbufs, &marker);
                 /*
                  * NB: we need to drop dn_dbufs_mtx between passes so
                  * that any DB_EVICTING dbufs can make progress.

@@ -424,14 +428,15 @@
         } while (progress);
 
         rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
         if (dn->dn_bonus && refcount_is_zero(&dn->dn_bonus->db_holds)) {
                 mutex_enter(&dn->dn_bonus->db_mtx);
-                dbuf_evict(dn->dn_bonus);
+                dbuf_evict(dn->dn_bonus, &evict_list);
                 dn->dn_bonus = NULL;
         }
         rw_exit(&dn->dn_struct_rwlock);
+        dmu_buf_destroy_user_evict_list(&evict_list);
 }
 
 static void
 dnode_undirty_dbufs(list_t *list)
 {