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