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,254 ****
return (B_TRUE);
}
/* ARGSUSED */
static void
! dsl_dataset_evict(dmu_buf_t *db, void *dsv)
{
- dsl_dataset_t *ds = dsv;
ASSERT(ds->ds_owner == NULL);
unique_remove(ds->ds_fsid_guid);
if (ds->ds_objset != NULL)
dmu_objset_evict(ds->ds_objset);
--- 239,255 ----
return (B_TRUE);
}
/* ARGSUSED */
static void
! dsl_dataset_evict_impl(dsl_dataset_t *ds, boolean_t evict_deadlist)
{
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,266 ****
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)
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));
--- 257,267 ----
dsl_dataset_rele(ds->ds_prev, ds);
ds->ds_prev = NULL;
}
bplist_destroy(&ds->ds_pending_deadlist);
! 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,279 ****
--- 271,287 ----
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,374 ****
/* 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);
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);
--- 365,381 ----
/* 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 = (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;
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,435 ****
}
} 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) {
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);
--- 431,446 ----
}
} else {
ds->ds_reserved = ds->ds_quota = 0;
}
! 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,640 ****
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);
}
boolean_t
dsl_dataset_tryown(dsl_dataset_t *ds, void *tag)
{
--- 641,651 ----
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_impl(ds, B_FALSE);
}
boolean_t
dsl_dataset_tryown(dsl_dataset_t *ds, void *tag)
{