1219089Spjd/* 2219089Spjd * CDDL HEADER START 3219089Spjd * 4219089Spjd * The contents of this file are subject to the terms of the 5219089Spjd * Common Development and Distribution License (the "License"). 6219089Spjd * You may not use this file except in compliance with the License. 7219089Spjd * 8219089Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9219089Spjd * or http://www.opensolaris.org/os/licensing. 10219089Spjd * See the License for the specific language governing permissions 11219089Spjd * and limitations under the License. 12219089Spjd * 13219089Spjd * When distributing Covered Code, include this CDDL HEADER in each 14219089Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15219089Spjd * If applicable, add the following below this CDDL HEADER, with the 16219089Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17219089Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18219089Spjd * 19219089Spjd * CDDL HEADER END 20219089Spjd */ 21219089Spjd/* 22219089Spjd * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23243674Smm * Copyright (c) 2012 by Delphix. All rights reserved. 24219089Spjd */ 25219089Spjd 26219089Spjd#include <sys/dsl_dataset.h> 27219089Spjd#include <sys/dmu.h> 28219089Spjd#include <sys/refcount.h> 29219089Spjd#include <sys/zap.h> 30219089Spjd#include <sys/zfs_context.h> 31219089Spjd#include <sys/dsl_pool.h> 32219089Spjd 33229578Smm/* 34229578Smm * Deadlist concurrency: 35229578Smm * 36229578Smm * Deadlists can only be modified from the syncing thread. 37229578Smm * 38229578Smm * Except for dsl_deadlist_insert(), it can only be modified with the 39229578Smm * dp_config_rwlock held with RW_WRITER. 40229578Smm * 41229578Smm * The accessors (dsl_deadlist_space() and dsl_deadlist_space_range()) can 42229578Smm * be called concurrently, from open context, with the dl_config_rwlock held 43229578Smm * with RW_READER. 44229578Smm * 45229578Smm * Therefore, we only need to provide locking between dsl_deadlist_insert() and 46229578Smm * the accessors, protecting: 47229578Smm * dl_phys->dl_used,comp,uncomp 48229578Smm * and protecting the dl_tree from being loaded. 49229578Smm * The locking is provided by dl_lock. Note that locking on the bpobj_t 50229578Smm * provides its own locking, and dl_oldfmt is immutable. 51229578Smm */ 52229578Smm 53219089Spjdstatic int 54219089Spjddsl_deadlist_compare(const void *arg1, const void *arg2) 55219089Spjd{ 56219089Spjd const dsl_deadlist_entry_t *dle1 = arg1; 57219089Spjd const dsl_deadlist_entry_t *dle2 = arg2; 58219089Spjd 59219089Spjd if (dle1->dle_mintxg < dle2->dle_mintxg) 60219089Spjd return (-1); 61219089Spjd else if (dle1->dle_mintxg > dle2->dle_mintxg) 62219089Spjd return (+1); 63219089Spjd else 64219089Spjd return (0); 65219089Spjd} 66219089Spjd 67219089Spjdstatic void 68219089Spjddsl_deadlist_load_tree(dsl_deadlist_t *dl) 69219089Spjd{ 70219089Spjd zap_cursor_t zc; 71219089Spjd zap_attribute_t za; 72219089Spjd 73219089Spjd ASSERT(!dl->dl_oldfmt); 74219089Spjd if (dl->dl_havetree) 75219089Spjd return; 76219089Spjd 77219089Spjd avl_create(&dl->dl_tree, dsl_deadlist_compare, 78219089Spjd sizeof (dsl_deadlist_entry_t), 79219089Spjd offsetof(dsl_deadlist_entry_t, dle_node)); 80219089Spjd for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object); 81219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 82219089Spjd zap_cursor_advance(&zc)) { 83219089Spjd dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 84219089Spjd dle->dle_mintxg = strtonum(za.za_name, NULL); 85219089Spjd VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, 86219089Spjd za.za_first_integer)); 87219089Spjd avl_add(&dl->dl_tree, dle); 88219089Spjd } 89219089Spjd zap_cursor_fini(&zc); 90219089Spjd dl->dl_havetree = B_TRUE; 91219089Spjd} 92219089Spjd 93219089Spjdvoid 94219089Spjddsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object) 95219089Spjd{ 96219089Spjd dmu_object_info_t doi; 97219089Spjd 98219089Spjd mutex_init(&dl->dl_lock, NULL, MUTEX_DEFAULT, NULL); 99219089Spjd dl->dl_os = os; 100219089Spjd dl->dl_object = object; 101219089Spjd VERIFY3U(0, ==, dmu_bonus_hold(os, object, dl, &dl->dl_dbuf)); 102219089Spjd dmu_object_info_from_db(dl->dl_dbuf, &doi); 103219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 104219089Spjd dmu_buf_rele(dl->dl_dbuf, dl); 105219089Spjd dl->dl_dbuf = NULL; 106219089Spjd dl->dl_oldfmt = B_TRUE; 107219089Spjd VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object)); 108219089Spjd return; 109219089Spjd } 110219089Spjd 111219089Spjd dl->dl_oldfmt = B_FALSE; 112219089Spjd dl->dl_phys = dl->dl_dbuf->db_data; 113219089Spjd dl->dl_havetree = B_FALSE; 114219089Spjd} 115219089Spjd 116219089Spjdvoid 117219089Spjddsl_deadlist_close(dsl_deadlist_t *dl) 118219089Spjd{ 119219089Spjd void *cookie = NULL; 120219089Spjd dsl_deadlist_entry_t *dle; 121219089Spjd 122219089Spjd if (dl->dl_oldfmt) { 123219089Spjd dl->dl_oldfmt = B_FALSE; 124219089Spjd bpobj_close(&dl->dl_bpobj); 125219089Spjd return; 126219089Spjd } 127219089Spjd 128219089Spjd if (dl->dl_havetree) { 129219089Spjd while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie)) 130219089Spjd != NULL) { 131219089Spjd bpobj_close(&dle->dle_bpobj); 132219089Spjd kmem_free(dle, sizeof (*dle)); 133219089Spjd } 134219089Spjd avl_destroy(&dl->dl_tree); 135219089Spjd } 136219089Spjd dmu_buf_rele(dl->dl_dbuf, dl); 137219089Spjd mutex_destroy(&dl->dl_lock); 138219089Spjd dl->dl_dbuf = NULL; 139219089Spjd dl->dl_phys = NULL; 140219089Spjd} 141219089Spjd 142219089Spjduint64_t 143219089Spjddsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx) 144219089Spjd{ 145219089Spjd if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS) 146219089Spjd return (bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx)); 147219089Spjd return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR, 148219089Spjd sizeof (dsl_deadlist_phys_t), tx)); 149219089Spjd} 150219089Spjd 151219089Spjdvoid 152219089Spjddsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx) 153219089Spjd{ 154219089Spjd dmu_object_info_t doi; 155219089Spjd zap_cursor_t zc; 156219089Spjd zap_attribute_t za; 157219089Spjd 158219089Spjd VERIFY3U(0, ==, dmu_object_info(os, dlobj, &doi)); 159219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 160219089Spjd bpobj_free(os, dlobj, tx); 161219089Spjd return; 162219089Spjd } 163219089Spjd 164219089Spjd for (zap_cursor_init(&zc, os, dlobj); 165219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 166243674Smm zap_cursor_advance(&zc)) { 167243674Smm uint64_t obj = za.za_first_integer; 168243674Smm if (obj == dmu_objset_pool(os)->dp_empty_bpobj) 169243674Smm bpobj_decr_empty(os, tx); 170243674Smm else 171243674Smm bpobj_free(os, obj, tx); 172243674Smm } 173219089Spjd zap_cursor_fini(&zc); 174219089Spjd VERIFY3U(0, ==, dmu_object_free(os, dlobj, tx)); 175219089Spjd} 176219089Spjd 177243674Smmstatic void 178243674Smmdle_enqueue(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle, 179243674Smm const blkptr_t *bp, dmu_tx_t *tx) 180243674Smm{ 181243674Smm if (dle->dle_bpobj.bpo_object == 182243674Smm dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) { 183243674Smm uint64_t obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 184243674Smm bpobj_close(&dle->dle_bpobj); 185243674Smm bpobj_decr_empty(dl->dl_os, tx); 186243674Smm VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); 187243674Smm VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object, 188243674Smm dle->dle_mintxg, obj, tx)); 189243674Smm } 190243674Smm bpobj_enqueue(&dle->dle_bpobj, bp, tx); 191243674Smm} 192243674Smm 193243674Smmstatic void 194243674Smmdle_enqueue_subobj(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle, 195243674Smm uint64_t obj, dmu_tx_t *tx) 196243674Smm{ 197243674Smm if (dle->dle_bpobj.bpo_object != 198243674Smm dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) { 199243674Smm bpobj_enqueue_subobj(&dle->dle_bpobj, obj, tx); 200243674Smm } else { 201243674Smm bpobj_close(&dle->dle_bpobj); 202243674Smm bpobj_decr_empty(dl->dl_os, tx); 203243674Smm VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); 204243674Smm VERIFY3U(0, ==, zap_update_int_key(dl->dl_os, dl->dl_object, 205243674Smm dle->dle_mintxg, obj, tx)); 206243674Smm } 207243674Smm} 208243674Smm 209219089Spjdvoid 210219089Spjddsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx) 211219089Spjd{ 212219089Spjd dsl_deadlist_entry_t dle_tofind; 213219089Spjd dsl_deadlist_entry_t *dle; 214219089Spjd avl_index_t where; 215219089Spjd 216219089Spjd if (dl->dl_oldfmt) { 217219089Spjd bpobj_enqueue(&dl->dl_bpobj, bp, tx); 218219089Spjd return; 219219089Spjd } 220219089Spjd 221219089Spjd dsl_deadlist_load_tree(dl); 222219089Spjd 223219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 224219089Spjd mutex_enter(&dl->dl_lock); 225219089Spjd dl->dl_phys->dl_used += 226219089Spjd bp_get_dsize_sync(dmu_objset_spa(dl->dl_os), bp); 227219089Spjd dl->dl_phys->dl_comp += BP_GET_PSIZE(bp); 228219089Spjd dl->dl_phys->dl_uncomp += BP_GET_UCSIZE(bp); 229219089Spjd mutex_exit(&dl->dl_lock); 230219089Spjd 231219089Spjd dle_tofind.dle_mintxg = bp->blk_birth; 232219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 233219089Spjd if (dle == NULL) 234219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 235219089Spjd else 236219089Spjd dle = AVL_PREV(&dl->dl_tree, dle); 237243674Smm dle_enqueue(dl, dle, bp, tx); 238219089Spjd} 239219089Spjd 240219089Spjd/* 241219089Spjd * Insert new key in deadlist, which must be > all current entries. 242219089Spjd * mintxg is not inclusive. 243219089Spjd */ 244219089Spjdvoid 245219089Spjddsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 246219089Spjd{ 247219089Spjd uint64_t obj; 248219089Spjd dsl_deadlist_entry_t *dle; 249219089Spjd 250219089Spjd if (dl->dl_oldfmt) 251219089Spjd return; 252219089Spjd 253219089Spjd dsl_deadlist_load_tree(dl); 254219089Spjd 255219089Spjd dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 256219089Spjd dle->dle_mintxg = mintxg; 257243674Smm obj = bpobj_alloc_empty(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 258219089Spjd VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); 259219089Spjd avl_add(&dl->dl_tree, dle); 260219089Spjd 261219089Spjd VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, dl->dl_object, 262219089Spjd mintxg, obj, tx)); 263219089Spjd} 264219089Spjd 265219089Spjd/* 266219089Spjd * Remove this key, merging its entries into the previous key. 267219089Spjd */ 268219089Spjdvoid 269219089Spjddsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 270219089Spjd{ 271219089Spjd dsl_deadlist_entry_t dle_tofind; 272219089Spjd dsl_deadlist_entry_t *dle, *dle_prev; 273219089Spjd 274219089Spjd if (dl->dl_oldfmt) 275219089Spjd return; 276219089Spjd 277219089Spjd dsl_deadlist_load_tree(dl); 278219089Spjd 279219089Spjd dle_tofind.dle_mintxg = mintxg; 280219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, NULL); 281219089Spjd dle_prev = AVL_PREV(&dl->dl_tree, dle); 282219089Spjd 283243674Smm dle_enqueue_subobj(dl, dle_prev, dle->dle_bpobj.bpo_object, tx); 284219089Spjd 285219089Spjd avl_remove(&dl->dl_tree, dle); 286219089Spjd bpobj_close(&dle->dle_bpobj); 287219089Spjd kmem_free(dle, sizeof (*dle)); 288219089Spjd 289219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, mintxg, tx)); 290219089Spjd} 291219089Spjd 292219089Spjd/* 293219089Spjd * Walk ds's snapshots to regenerate generate ZAP & AVL. 294219089Spjd */ 295219089Spjdstatic void 296219089Spjddsl_deadlist_regenerate(objset_t *os, uint64_t dlobj, 297219089Spjd uint64_t mrs_obj, dmu_tx_t *tx) 298219089Spjd{ 299219089Spjd dsl_deadlist_t dl; 300219089Spjd dsl_pool_t *dp = dmu_objset_pool(os); 301219089Spjd 302219089Spjd dsl_deadlist_open(&dl, os, dlobj); 303219089Spjd if (dl.dl_oldfmt) { 304219089Spjd dsl_deadlist_close(&dl); 305219089Spjd return; 306219089Spjd } 307219089Spjd 308219089Spjd while (mrs_obj != 0) { 309219089Spjd dsl_dataset_t *ds; 310219089Spjd VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, mrs_obj, FTAG, &ds)); 311219089Spjd dsl_deadlist_add_key(&dl, ds->ds_phys->ds_prev_snap_txg, tx); 312219089Spjd mrs_obj = ds->ds_phys->ds_prev_snap_obj; 313219089Spjd dsl_dataset_rele(ds, FTAG); 314219089Spjd } 315219089Spjd dsl_deadlist_close(&dl); 316219089Spjd} 317219089Spjd 318219089Spjduint64_t 319219089Spjddsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg, 320219089Spjd uint64_t mrs_obj, dmu_tx_t *tx) 321219089Spjd{ 322219089Spjd dsl_deadlist_entry_t *dle; 323219089Spjd uint64_t newobj; 324219089Spjd 325219089Spjd newobj = dsl_deadlist_alloc(dl->dl_os, tx); 326219089Spjd 327219089Spjd if (dl->dl_oldfmt) { 328219089Spjd dsl_deadlist_regenerate(dl->dl_os, newobj, mrs_obj, tx); 329219089Spjd return (newobj); 330219089Spjd } 331219089Spjd 332219089Spjd dsl_deadlist_load_tree(dl); 333219089Spjd 334219089Spjd for (dle = avl_first(&dl->dl_tree); dle; 335219089Spjd dle = AVL_NEXT(&dl->dl_tree, dle)) { 336219089Spjd uint64_t obj; 337219089Spjd 338219089Spjd if (dle->dle_mintxg >= maxtxg) 339219089Spjd break; 340219089Spjd 341243674Smm obj = bpobj_alloc_empty(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 342219089Spjd VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj, 343219089Spjd dle->dle_mintxg, obj, tx)); 344219089Spjd } 345219089Spjd return (newobj); 346219089Spjd} 347219089Spjd 348219089Spjdvoid 349219089Spjddsl_deadlist_space(dsl_deadlist_t *dl, 350219089Spjd uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 351219089Spjd{ 352219089Spjd if (dl->dl_oldfmt) { 353219089Spjd VERIFY3U(0, ==, bpobj_space(&dl->dl_bpobj, 354219089Spjd usedp, compp, uncompp)); 355219089Spjd return; 356219089Spjd } 357219089Spjd 358219089Spjd mutex_enter(&dl->dl_lock); 359219089Spjd *usedp = dl->dl_phys->dl_used; 360219089Spjd *compp = dl->dl_phys->dl_comp; 361219089Spjd *uncompp = dl->dl_phys->dl_uncomp; 362219089Spjd mutex_exit(&dl->dl_lock); 363219089Spjd} 364219089Spjd 365219089Spjd/* 366219089Spjd * return space used in the range (mintxg, maxtxg]. 367219089Spjd * Includes maxtxg, does not include mintxg. 368219089Spjd * mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is 369229578Smm * larger than any bp in the deadlist (eg. UINT64_MAX)). 370219089Spjd */ 371219089Spjdvoid 372219089Spjddsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg, 373219089Spjd uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 374219089Spjd{ 375229578Smm dsl_deadlist_entry_t *dle; 376219089Spjd dsl_deadlist_entry_t dle_tofind; 377219089Spjd avl_index_t where; 378219089Spjd 379219089Spjd if (dl->dl_oldfmt) { 380219089Spjd VERIFY3U(0, ==, bpobj_space_range(&dl->dl_bpobj, 381219089Spjd mintxg, maxtxg, usedp, compp, uncompp)); 382219089Spjd return; 383219089Spjd } 384219089Spjd 385219089Spjd *usedp = *compp = *uncompp = 0; 386219089Spjd 387229578Smm mutex_enter(&dl->dl_lock); 388229578Smm dsl_deadlist_load_tree(dl); 389219089Spjd dle_tofind.dle_mintxg = mintxg; 390219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 391219089Spjd /* 392219089Spjd * If we don't find this mintxg, there shouldn't be anything 393219089Spjd * after it either. 394219089Spjd */ 395219089Spjd ASSERT(dle != NULL || 396219089Spjd avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL); 397229578Smm 398219089Spjd for (; dle && dle->dle_mintxg < maxtxg; 399219089Spjd dle = AVL_NEXT(&dl->dl_tree, dle)) { 400219089Spjd uint64_t used, comp, uncomp; 401219089Spjd 402219089Spjd VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 403219089Spjd &used, &comp, &uncomp)); 404219089Spjd 405219089Spjd *usedp += used; 406219089Spjd *compp += comp; 407219089Spjd *uncompp += uncomp; 408219089Spjd } 409229578Smm mutex_exit(&dl->dl_lock); 410219089Spjd} 411219089Spjd 412219089Spjdstatic void 413219089Spjddsl_deadlist_insert_bpobj(dsl_deadlist_t *dl, uint64_t obj, uint64_t birth, 414219089Spjd dmu_tx_t *tx) 415219089Spjd{ 416219089Spjd dsl_deadlist_entry_t dle_tofind; 417219089Spjd dsl_deadlist_entry_t *dle; 418219089Spjd avl_index_t where; 419219089Spjd uint64_t used, comp, uncomp; 420219089Spjd bpobj_t bpo; 421219089Spjd 422219089Spjd VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 423219089Spjd VERIFY3U(0, ==, bpobj_space(&bpo, &used, &comp, &uncomp)); 424219089Spjd bpobj_close(&bpo); 425219089Spjd 426219089Spjd dsl_deadlist_load_tree(dl); 427219089Spjd 428219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 429219089Spjd mutex_enter(&dl->dl_lock); 430219089Spjd dl->dl_phys->dl_used += used; 431219089Spjd dl->dl_phys->dl_comp += comp; 432219089Spjd dl->dl_phys->dl_uncomp += uncomp; 433219089Spjd mutex_exit(&dl->dl_lock); 434219089Spjd 435219089Spjd dle_tofind.dle_mintxg = birth; 436219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 437219089Spjd if (dle == NULL) 438219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 439243674Smm dle_enqueue_subobj(dl, dle, obj, tx); 440219089Spjd} 441219089Spjd 442219089Spjdstatic int 443219089Spjddsl_deadlist_insert_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) 444219089Spjd{ 445219089Spjd dsl_deadlist_t *dl = arg; 446219089Spjd dsl_deadlist_insert(dl, bp, tx); 447219089Spjd return (0); 448219089Spjd} 449219089Spjd 450219089Spjd/* 451219089Spjd * Merge the deadlist pointed to by 'obj' into dl. obj will be left as 452219089Spjd * an empty deadlist. 453219089Spjd */ 454219089Spjdvoid 455219089Spjddsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx) 456219089Spjd{ 457219089Spjd zap_cursor_t zc; 458219089Spjd zap_attribute_t za; 459219089Spjd dmu_buf_t *bonus; 460219089Spjd dsl_deadlist_phys_t *dlp; 461219089Spjd dmu_object_info_t doi; 462219089Spjd 463219089Spjd VERIFY3U(0, ==, dmu_object_info(dl->dl_os, obj, &doi)); 464219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 465219089Spjd bpobj_t bpo; 466219089Spjd VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 467219089Spjd VERIFY3U(0, ==, bpobj_iterate(&bpo, 468219089Spjd dsl_deadlist_insert_cb, dl, tx)); 469219089Spjd bpobj_close(&bpo); 470219089Spjd return; 471219089Spjd } 472219089Spjd 473219089Spjd for (zap_cursor_init(&zc, dl->dl_os, obj); 474219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 475219089Spjd zap_cursor_advance(&zc)) { 476219089Spjd uint64_t mintxg = strtonum(za.za_name, NULL); 477219089Spjd dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx); 478219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx)); 479219089Spjd } 480219089Spjd zap_cursor_fini(&zc); 481219089Spjd 482219089Spjd VERIFY3U(0, ==, dmu_bonus_hold(dl->dl_os, obj, FTAG, &bonus)); 483219089Spjd dlp = bonus->db_data; 484219089Spjd dmu_buf_will_dirty(bonus, tx); 485219089Spjd bzero(dlp, sizeof (*dlp)); 486219089Spjd dmu_buf_rele(bonus, FTAG); 487219089Spjd} 488219089Spjd 489219089Spjd/* 490219089Spjd * Remove entries on dl that are >= mintxg, and put them on the bpobj. 491219089Spjd */ 492219089Spjdvoid 493219089Spjddsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg, 494219089Spjd dmu_tx_t *tx) 495219089Spjd{ 496219089Spjd dsl_deadlist_entry_t dle_tofind; 497219089Spjd dsl_deadlist_entry_t *dle; 498219089Spjd avl_index_t where; 499219089Spjd 500219089Spjd ASSERT(!dl->dl_oldfmt); 501219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 502219089Spjd dsl_deadlist_load_tree(dl); 503219089Spjd 504219089Spjd dle_tofind.dle_mintxg = mintxg; 505219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 506219089Spjd if (dle == NULL) 507219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_AFTER); 508219089Spjd while (dle) { 509219089Spjd uint64_t used, comp, uncomp; 510219089Spjd dsl_deadlist_entry_t *dle_next; 511219089Spjd 512219089Spjd bpobj_enqueue_subobj(bpo, dle->dle_bpobj.bpo_object, tx); 513219089Spjd 514219089Spjd VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 515219089Spjd &used, &comp, &uncomp)); 516219089Spjd mutex_enter(&dl->dl_lock); 517219089Spjd ASSERT3U(dl->dl_phys->dl_used, >=, used); 518219089Spjd ASSERT3U(dl->dl_phys->dl_comp, >=, comp); 519219089Spjd ASSERT3U(dl->dl_phys->dl_uncomp, >=, uncomp); 520219089Spjd dl->dl_phys->dl_used -= used; 521219089Spjd dl->dl_phys->dl_comp -= comp; 522219089Spjd dl->dl_phys->dl_uncomp -= uncomp; 523219089Spjd mutex_exit(&dl->dl_lock); 524219089Spjd 525219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, 526219089Spjd dle->dle_mintxg, tx)); 527219089Spjd 528219089Spjd dle_next = AVL_NEXT(&dl->dl_tree, dle); 529219089Spjd avl_remove(&dl->dl_tree, dle); 530219089Spjd bpobj_close(&dle->dle_bpobj); 531219089Spjd kmem_free(dle, sizeof (*dle)); 532219089Spjd dle = dle_next; 533219089Spjd } 534219089Spjd} 535