253 if (ds->ds_trysnap_txg >
254 spa_last_synced_txg(ds->ds_dir->dd_pool->dp_spa))
255 trysnap = ds->ds_trysnap_txg;
256 return (MAX(dsl_dataset_phys(ds)->ds_prev_snap_txg, trysnap));
257 }
258
259 boolean_t
260 dsl_dataset_block_freeable(dsl_dataset_t *ds, const blkptr_t *bp,
261 uint64_t blk_birth)
262 {
263 if (blk_birth <= dsl_dataset_prev_snap_txg(ds) ||
264 (bp != NULL && BP_IS_HOLE(bp)))
265 return (B_FALSE);
266
267 ddt_prefetch(dsl_dataset_get_spa(ds), bp);
268
269 return (B_TRUE);
270 }
271
272 static void
273 dsl_dataset_evict(void *dbu)
274 {
275 dsl_dataset_t *ds = dbu;
276
277 ASSERT(ds->ds_owner == NULL);
278
279 ds->ds_dbuf = NULL;
280
281 unique_remove(ds->ds_fsid_guid);
282
283 if (ds->ds_objset != NULL)
284 dmu_objset_evict(ds->ds_objset);
285
286 if (ds->ds_prev) {
287 dsl_dataset_rele(ds->ds_prev, ds);
288 ds->ds_prev = NULL;
289 }
290
291 bplist_destroy(&ds->ds_pending_deadlist);
292 if (ds->ds_deadlist.dl_os != NULL)
293 dsl_deadlist_close(&ds->ds_deadlist);
294 if (ds->ds_dir)
295 dsl_dir_async_rele(ds->ds_dir, ds);
296
297 ASSERT(!list_link_active(&ds->ds_synced_link));
298
299 list_destroy(&ds->ds_prop_cbs);
300 mutex_destroy(&ds->ds_lock);
301 mutex_destroy(&ds->ds_opening_lock);
302 mutex_destroy(&ds->ds_sendstream_lock);
495 err = zap_count(
496 ds->ds_dir->dd_pool->dp_meta_objset,
497 dsl_dataset_phys(ds)->ds_userrefs_obj,
498 &ds->ds_userrefs);
499 }
500 }
501
502 if (err == 0 && !ds->ds_is_snapshot) {
503 err = dsl_prop_get_int_ds(ds,
504 zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
505 &ds->ds_reserved);
506 if (err == 0) {
507 err = dsl_prop_get_int_ds(ds,
508 zfs_prop_to_name(ZFS_PROP_REFQUOTA),
509 &ds->ds_quota);
510 }
511 } else {
512 ds->ds_reserved = ds->ds_quota = 0;
513 }
514
515 dmu_buf_init_user(&ds->ds_dbu, dsl_dataset_evict, &ds->ds_dbuf);
516 if (err == 0)
517 winner = dmu_buf_set_user_ie(dbuf, &ds->ds_dbu);
518
519 if (err != 0 || winner != NULL) {
520 bplist_destroy(&ds->ds_pending_deadlist);
521 dsl_deadlist_close(&ds->ds_deadlist);
522 if (ds->ds_prev)
523 dsl_dataset_rele(ds->ds_prev, ds);
524 dsl_dir_rele(ds->ds_dir, ds);
525 mutex_destroy(&ds->ds_lock);
526 mutex_destroy(&ds->ds_opening_lock);
527 mutex_destroy(&ds->ds_sendstream_lock);
528 refcount_destroy(&ds->ds_longholds);
529 kmem_free(ds, sizeof (dsl_dataset_t));
530 if (err != 0) {
531 dmu_buf_rele(dbuf, tag);
532 return (err);
533 }
534 ds = winner;
535 } else {
|
253 if (ds->ds_trysnap_txg >
254 spa_last_synced_txg(ds->ds_dir->dd_pool->dp_spa))
255 trysnap = ds->ds_trysnap_txg;
256 return (MAX(dsl_dataset_phys(ds)->ds_prev_snap_txg, trysnap));
257 }
258
259 boolean_t
260 dsl_dataset_block_freeable(dsl_dataset_t *ds, const blkptr_t *bp,
261 uint64_t blk_birth)
262 {
263 if (blk_birth <= dsl_dataset_prev_snap_txg(ds) ||
264 (bp != NULL && BP_IS_HOLE(bp)))
265 return (B_FALSE);
266
267 ddt_prefetch(dsl_dataset_get_spa(ds), bp);
268
269 return (B_TRUE);
270 }
271
272 static void
273 dsl_dataset_evict_prep(void *dbu)
274 {
275 dsl_dataset_t *ds = dbu;
276
277 ASSERT(ds->ds_owner == NULL);
278
279 unique_remove(ds->ds_fsid_guid);
280 }
281
282 static void
283 dsl_dataset_evict(void *dbu)
284 {
285 dsl_dataset_t *ds = dbu;
286
287 ASSERT(ds->ds_owner == NULL);
288
289 ds->ds_dbuf = NULL;
290
291 if (ds->ds_objset != NULL)
292 dmu_objset_evict(ds->ds_objset);
293
294 if (ds->ds_prev) {
295 dsl_dataset_rele(ds->ds_prev, ds);
296 ds->ds_prev = NULL;
297 }
298
299 bplist_destroy(&ds->ds_pending_deadlist);
300 if (ds->ds_deadlist.dl_os != NULL)
301 dsl_deadlist_close(&ds->ds_deadlist);
302 if (ds->ds_dir)
303 dsl_dir_async_rele(ds->ds_dir, ds);
304
305 ASSERT(!list_link_active(&ds->ds_synced_link));
306
307 list_destroy(&ds->ds_prop_cbs);
308 mutex_destroy(&ds->ds_lock);
309 mutex_destroy(&ds->ds_opening_lock);
310 mutex_destroy(&ds->ds_sendstream_lock);
503 err = zap_count(
504 ds->ds_dir->dd_pool->dp_meta_objset,
505 dsl_dataset_phys(ds)->ds_userrefs_obj,
506 &ds->ds_userrefs);
507 }
508 }
509
510 if (err == 0 && !ds->ds_is_snapshot) {
511 err = dsl_prop_get_int_ds(ds,
512 zfs_prop_to_name(ZFS_PROP_REFRESERVATION),
513 &ds->ds_reserved);
514 if (err == 0) {
515 err = dsl_prop_get_int_ds(ds,
516 zfs_prop_to_name(ZFS_PROP_REFQUOTA),
517 &ds->ds_quota);
518 }
519 } else {
520 ds->ds_reserved = ds->ds_quota = 0;
521 }
522
523 dmu_buf_init_user(&ds->ds_dbu, dsl_dataset_evict_prep,
524 dsl_dataset_evict, &ds->ds_dbuf);
525 if (err == 0)
526 winner = dmu_buf_set_user_ie(dbuf, &ds->ds_dbu);
527
528 if (err != 0 || winner != NULL) {
529 bplist_destroy(&ds->ds_pending_deadlist);
530 dsl_deadlist_close(&ds->ds_deadlist);
531 if (ds->ds_prev)
532 dsl_dataset_rele(ds->ds_prev, ds);
533 dsl_dir_rele(ds->ds_dir, ds);
534 mutex_destroy(&ds->ds_lock);
535 mutex_destroy(&ds->ds_opening_lock);
536 mutex_destroy(&ds->ds_sendstream_lock);
537 refcount_destroy(&ds->ds_longholds);
538 kmem_free(ds, sizeof (dsl_dataset_t));
539 if (err != 0) {
540 dmu_buf_rele(dbuf, tag);
541 return (err);
542 }
543 ds = winner;
544 } else {
|