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)
{