Print this page
3752 want more verifiable dbuf user eviction
Submitted by: Justin Gibbs <justing@spectralogic.com>
Submitted by: Will Andrews <willa@spectralogic.com>
@@ -239,16 +239,17 @@
return (B_TRUE);
}
/* ARGSUSED */
static void
-dsl_dataset_evict(dmu_buf_t *db, void *dsv)
+dsl_dataset_evict_impl(dsl_dataset_t *ds, boolean_t evict_deadlist)
{
- dsl_dataset_t *ds = dsv;
ASSERT(ds->ds_owner == NULL);
+ ds->ds_dbuf = NULL;
+
unique_remove(ds->ds_fsid_guid);
if (ds->ds_objset != NULL)
dmu_objset_evict(ds->ds_objset);
@@ -256,11 +257,11 @@
dsl_dataset_rele(ds->ds_prev, ds);
ds->ds_prev = NULL;
}
bplist_destroy(&ds->ds_pending_deadlist);
- if (ds->ds_phys->ds_deadlist_obj != 0)
+ if (evict_deadlist)
dsl_deadlist_close(&ds->ds_deadlist);
if (ds->ds_dir)
dsl_dir_rele(ds->ds_dir, ds);
ASSERT(!list_link_active(&ds->ds_synced_link));
@@ -270,10 +271,17 @@
refcount_destroy(&ds->ds_longholds);
kmem_free(ds, sizeof (dsl_dataset_t));
}
+/* ARGSUSED */
+static void
+dsl_dataset_evict(dmu_buf_user_t *dbu)
+{
+ dsl_dataset_evict_impl((dsl_dataset_t *)dbu, B_TRUE);
+}
+
int
dsl_dataset_get_snapname(dsl_dataset_t *ds)
{
dsl_dataset_phys_t *headphys;
int err;
@@ -357,18 +365,17 @@
/* Make sure dsobj has the correct object type. */
dmu_object_info_from_db(dbuf, &doi);
if (doi.doi_type != DMU_OT_DSL_DATASET)
return (SET_ERROR(EINVAL));
- ds = dmu_buf_get_user(dbuf);
+ ds = (dsl_dataset_t *)dmu_buf_get_user(dbuf);
if (ds == NULL) {
dsl_dataset_t *winner = NULL;
ds = kmem_zalloc(sizeof (dsl_dataset_t), KM_SLEEP);
ds->ds_dbuf = dbuf;
ds->ds_object = dsobj;
- ds->ds_phys = dbuf->db_data;
mutex_init(&ds->ds_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&ds->ds_opening_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&ds->ds_sendstream_lock, NULL, MUTEX_DEFAULT, NULL);
refcount_create(&ds->ds_longholds);
@@ -424,12 +431,16 @@
}
} else {
ds->ds_reserved = ds->ds_quota = 0;
}
- if (err != 0 || (winner = dmu_buf_set_user_ie(dbuf, ds,
- &ds->ds_phys, dsl_dataset_evict)) != NULL) {
+ dmu_buf_init_user(&ds->db_evict, dsl_dataset_evict);
+ if (err == 0)
+ winner = (dsl_dataset_t *)
+ dmu_buf_set_user_ie(dbuf, &ds->db_evict);
+
+ if (err || winner) {
bplist_destroy(&ds->ds_pending_deadlist);
dsl_deadlist_close(&ds->ds_deadlist);
if (ds->ds_prev)
dsl_dataset_rele(ds->ds_prev, ds);
dsl_dir_rele(ds->ds_dir, ds);
@@ -630,11 +641,11 @@
mutex_exit(&ds->ds_lock);
dsl_dataset_long_rele(ds, tag);
if (ds->ds_dbuf != NULL)
dsl_dataset_rele(ds, tag);
else
- dsl_dataset_evict(NULL, ds);
+ dsl_dataset_evict_impl(ds, B_FALSE);
}
boolean_t
dsl_dataset_tryown(dsl_dataset_t *ds, void *tag)
{