dsl_deadlist.c revision 219089
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. 23219089Spjd */ 24219089Spjd 25219089Spjd#include <sys/dsl_dataset.h> 26219089Spjd#include <sys/dmu.h> 27219089Spjd#include <sys/refcount.h> 28219089Spjd#include <sys/zap.h> 29219089Spjd#include <sys/zfs_context.h> 30219089Spjd#include <sys/dsl_pool.h> 31219089Spjd 32219089Spjdstatic int 33219089Spjddsl_deadlist_compare(const void *arg1, const void *arg2) 34219089Spjd{ 35219089Spjd const dsl_deadlist_entry_t *dle1 = arg1; 36219089Spjd const dsl_deadlist_entry_t *dle2 = arg2; 37219089Spjd 38219089Spjd if (dle1->dle_mintxg < dle2->dle_mintxg) 39219089Spjd return (-1); 40219089Spjd else if (dle1->dle_mintxg > dle2->dle_mintxg) 41219089Spjd return (+1); 42219089Spjd else 43219089Spjd return (0); 44219089Spjd} 45219089Spjd 46219089Spjdstatic void 47219089Spjddsl_deadlist_load_tree(dsl_deadlist_t *dl) 48219089Spjd{ 49219089Spjd zap_cursor_t zc; 50219089Spjd zap_attribute_t za; 51219089Spjd 52219089Spjd ASSERT(!dl->dl_oldfmt); 53219089Spjd if (dl->dl_havetree) 54219089Spjd return; 55219089Spjd 56219089Spjd avl_create(&dl->dl_tree, dsl_deadlist_compare, 57219089Spjd sizeof (dsl_deadlist_entry_t), 58219089Spjd offsetof(dsl_deadlist_entry_t, dle_node)); 59219089Spjd for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object); 60219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 61219089Spjd zap_cursor_advance(&zc)) { 62219089Spjd dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 63219089Spjd dle->dle_mintxg = strtonum(za.za_name, NULL); 64219089Spjd VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, 65219089Spjd za.za_first_integer)); 66219089Spjd avl_add(&dl->dl_tree, dle); 67219089Spjd } 68219089Spjd zap_cursor_fini(&zc); 69219089Spjd dl->dl_havetree = B_TRUE; 70219089Spjd} 71219089Spjd 72219089Spjdvoid 73219089Spjddsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object) 74219089Spjd{ 75219089Spjd dmu_object_info_t doi; 76219089Spjd 77219089Spjd mutex_init(&dl->dl_lock, NULL, MUTEX_DEFAULT, NULL); 78219089Spjd dl->dl_os = os; 79219089Spjd dl->dl_object = object; 80219089Spjd VERIFY3U(0, ==, dmu_bonus_hold(os, object, dl, &dl->dl_dbuf)); 81219089Spjd dmu_object_info_from_db(dl->dl_dbuf, &doi); 82219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 83219089Spjd dmu_buf_rele(dl->dl_dbuf, dl); 84219089Spjd dl->dl_dbuf = NULL; 85219089Spjd dl->dl_oldfmt = B_TRUE; 86219089Spjd VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object)); 87219089Spjd return; 88219089Spjd } 89219089Spjd 90219089Spjd dl->dl_oldfmt = B_FALSE; 91219089Spjd dl->dl_phys = dl->dl_dbuf->db_data; 92219089Spjd dl->dl_havetree = B_FALSE; 93219089Spjd} 94219089Spjd 95219089Spjdvoid 96219089Spjddsl_deadlist_close(dsl_deadlist_t *dl) 97219089Spjd{ 98219089Spjd void *cookie = NULL; 99219089Spjd dsl_deadlist_entry_t *dle; 100219089Spjd 101219089Spjd if (dl->dl_oldfmt) { 102219089Spjd dl->dl_oldfmt = B_FALSE; 103219089Spjd bpobj_close(&dl->dl_bpobj); 104219089Spjd return; 105219089Spjd } 106219089Spjd 107219089Spjd if (dl->dl_havetree) { 108219089Spjd while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie)) 109219089Spjd != NULL) { 110219089Spjd bpobj_close(&dle->dle_bpobj); 111219089Spjd kmem_free(dle, sizeof (*dle)); 112219089Spjd } 113219089Spjd avl_destroy(&dl->dl_tree); 114219089Spjd } 115219089Spjd dmu_buf_rele(dl->dl_dbuf, dl); 116219089Spjd mutex_destroy(&dl->dl_lock); 117219089Spjd dl->dl_dbuf = NULL; 118219089Spjd dl->dl_phys = NULL; 119219089Spjd} 120219089Spjd 121219089Spjduint64_t 122219089Spjddsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx) 123219089Spjd{ 124219089Spjd if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS) 125219089Spjd return (bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx)); 126219089Spjd return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR, 127219089Spjd sizeof (dsl_deadlist_phys_t), tx)); 128219089Spjd} 129219089Spjd 130219089Spjdvoid 131219089Spjddsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx) 132219089Spjd{ 133219089Spjd dmu_object_info_t doi; 134219089Spjd zap_cursor_t zc; 135219089Spjd zap_attribute_t za; 136219089Spjd 137219089Spjd VERIFY3U(0, ==, dmu_object_info(os, dlobj, &doi)); 138219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 139219089Spjd bpobj_free(os, dlobj, tx); 140219089Spjd return; 141219089Spjd } 142219089Spjd 143219089Spjd for (zap_cursor_init(&zc, os, dlobj); 144219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 145219089Spjd zap_cursor_advance(&zc)) 146219089Spjd bpobj_free(os, za.za_first_integer, tx); 147219089Spjd zap_cursor_fini(&zc); 148219089Spjd VERIFY3U(0, ==, dmu_object_free(os, dlobj, tx)); 149219089Spjd} 150219089Spjd 151219089Spjdvoid 152219089Spjddsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx) 153219089Spjd{ 154219089Spjd dsl_deadlist_entry_t dle_tofind; 155219089Spjd dsl_deadlist_entry_t *dle; 156219089Spjd avl_index_t where; 157219089Spjd 158219089Spjd if (dl->dl_oldfmt) { 159219089Spjd bpobj_enqueue(&dl->dl_bpobj, bp, tx); 160219089Spjd return; 161219089Spjd } 162219089Spjd 163219089Spjd dsl_deadlist_load_tree(dl); 164219089Spjd 165219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 166219089Spjd mutex_enter(&dl->dl_lock); 167219089Spjd dl->dl_phys->dl_used += 168219089Spjd bp_get_dsize_sync(dmu_objset_spa(dl->dl_os), bp); 169219089Spjd dl->dl_phys->dl_comp += BP_GET_PSIZE(bp); 170219089Spjd dl->dl_phys->dl_uncomp += BP_GET_UCSIZE(bp); 171219089Spjd mutex_exit(&dl->dl_lock); 172219089Spjd 173219089Spjd dle_tofind.dle_mintxg = bp->blk_birth; 174219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 175219089Spjd if (dle == NULL) 176219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 177219089Spjd else 178219089Spjd dle = AVL_PREV(&dl->dl_tree, dle); 179219089Spjd bpobj_enqueue(&dle->dle_bpobj, bp, tx); 180219089Spjd} 181219089Spjd 182219089Spjd/* 183219089Spjd * Insert new key in deadlist, which must be > all current entries. 184219089Spjd * mintxg is not inclusive. 185219089Spjd */ 186219089Spjdvoid 187219089Spjddsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 188219089Spjd{ 189219089Spjd uint64_t obj; 190219089Spjd dsl_deadlist_entry_t *dle; 191219089Spjd 192219089Spjd if (dl->dl_oldfmt) 193219089Spjd return; 194219089Spjd 195219089Spjd dsl_deadlist_load_tree(dl); 196219089Spjd 197219089Spjd dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 198219089Spjd dle->dle_mintxg = mintxg; 199219089Spjd obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 200219089Spjd VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); 201219089Spjd avl_add(&dl->dl_tree, dle); 202219089Spjd 203219089Spjd VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, dl->dl_object, 204219089Spjd mintxg, obj, tx)); 205219089Spjd} 206219089Spjd 207219089Spjd/* 208219089Spjd * Remove this key, merging its entries into the previous key. 209219089Spjd */ 210219089Spjdvoid 211219089Spjddsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 212219089Spjd{ 213219089Spjd dsl_deadlist_entry_t dle_tofind; 214219089Spjd dsl_deadlist_entry_t *dle, *dle_prev; 215219089Spjd 216219089Spjd if (dl->dl_oldfmt) 217219089Spjd return; 218219089Spjd 219219089Spjd dsl_deadlist_load_tree(dl); 220219089Spjd 221219089Spjd dle_tofind.dle_mintxg = mintxg; 222219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, NULL); 223219089Spjd dle_prev = AVL_PREV(&dl->dl_tree, dle); 224219089Spjd 225219089Spjd bpobj_enqueue_subobj(&dle_prev->dle_bpobj, 226219089Spjd dle->dle_bpobj.bpo_object, tx); 227219089Spjd 228219089Spjd avl_remove(&dl->dl_tree, dle); 229219089Spjd bpobj_close(&dle->dle_bpobj); 230219089Spjd kmem_free(dle, sizeof (*dle)); 231219089Spjd 232219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, mintxg, tx)); 233219089Spjd} 234219089Spjd 235219089Spjd/* 236219089Spjd * Walk ds's snapshots to regenerate generate ZAP & AVL. 237219089Spjd */ 238219089Spjdstatic void 239219089Spjddsl_deadlist_regenerate(objset_t *os, uint64_t dlobj, 240219089Spjd uint64_t mrs_obj, dmu_tx_t *tx) 241219089Spjd{ 242219089Spjd dsl_deadlist_t dl; 243219089Spjd dsl_pool_t *dp = dmu_objset_pool(os); 244219089Spjd 245219089Spjd dsl_deadlist_open(&dl, os, dlobj); 246219089Spjd if (dl.dl_oldfmt) { 247219089Spjd dsl_deadlist_close(&dl); 248219089Spjd return; 249219089Spjd } 250219089Spjd 251219089Spjd while (mrs_obj != 0) { 252219089Spjd dsl_dataset_t *ds; 253219089Spjd VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, mrs_obj, FTAG, &ds)); 254219089Spjd dsl_deadlist_add_key(&dl, ds->ds_phys->ds_prev_snap_txg, tx); 255219089Spjd mrs_obj = ds->ds_phys->ds_prev_snap_obj; 256219089Spjd dsl_dataset_rele(ds, FTAG); 257219089Spjd } 258219089Spjd dsl_deadlist_close(&dl); 259219089Spjd} 260219089Spjd 261219089Spjduint64_t 262219089Spjddsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg, 263219089Spjd uint64_t mrs_obj, dmu_tx_t *tx) 264219089Spjd{ 265219089Spjd dsl_deadlist_entry_t *dle; 266219089Spjd uint64_t newobj; 267219089Spjd 268219089Spjd newobj = dsl_deadlist_alloc(dl->dl_os, tx); 269219089Spjd 270219089Spjd if (dl->dl_oldfmt) { 271219089Spjd dsl_deadlist_regenerate(dl->dl_os, newobj, mrs_obj, tx); 272219089Spjd return (newobj); 273219089Spjd } 274219089Spjd 275219089Spjd dsl_deadlist_load_tree(dl); 276219089Spjd 277219089Spjd for (dle = avl_first(&dl->dl_tree); dle; 278219089Spjd dle = AVL_NEXT(&dl->dl_tree, dle)) { 279219089Spjd uint64_t obj; 280219089Spjd 281219089Spjd if (dle->dle_mintxg >= maxtxg) 282219089Spjd break; 283219089Spjd 284219089Spjd obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 285219089Spjd VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj, 286219089Spjd dle->dle_mintxg, obj, tx)); 287219089Spjd } 288219089Spjd return (newobj); 289219089Spjd} 290219089Spjd 291219089Spjdvoid 292219089Spjddsl_deadlist_space(dsl_deadlist_t *dl, 293219089Spjd uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 294219089Spjd{ 295219089Spjd if (dl->dl_oldfmt) { 296219089Spjd VERIFY3U(0, ==, bpobj_space(&dl->dl_bpobj, 297219089Spjd usedp, compp, uncompp)); 298219089Spjd return; 299219089Spjd } 300219089Spjd 301219089Spjd mutex_enter(&dl->dl_lock); 302219089Spjd *usedp = dl->dl_phys->dl_used; 303219089Spjd *compp = dl->dl_phys->dl_comp; 304219089Spjd *uncompp = dl->dl_phys->dl_uncomp; 305219089Spjd mutex_exit(&dl->dl_lock); 306219089Spjd} 307219089Spjd 308219089Spjd/* 309219089Spjd * return space used in the range (mintxg, maxtxg]. 310219089Spjd * Includes maxtxg, does not include mintxg. 311219089Spjd * mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is 312219089Spjd * UINT64_MAX). 313219089Spjd */ 314219089Spjdvoid 315219089Spjddsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg, 316219089Spjd uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 317219089Spjd{ 318219089Spjd dsl_deadlist_entry_t dle_tofind; 319219089Spjd dsl_deadlist_entry_t *dle; 320219089Spjd avl_index_t where; 321219089Spjd 322219089Spjd if (dl->dl_oldfmt) { 323219089Spjd VERIFY3U(0, ==, bpobj_space_range(&dl->dl_bpobj, 324219089Spjd mintxg, maxtxg, usedp, compp, uncompp)); 325219089Spjd return; 326219089Spjd } 327219089Spjd 328219089Spjd dsl_deadlist_load_tree(dl); 329219089Spjd *usedp = *compp = *uncompp = 0; 330219089Spjd 331219089Spjd dle_tofind.dle_mintxg = mintxg; 332219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 333219089Spjd /* 334219089Spjd * If we don't find this mintxg, there shouldn't be anything 335219089Spjd * after it either. 336219089Spjd */ 337219089Spjd ASSERT(dle != NULL || 338219089Spjd avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL); 339219089Spjd for (; dle && dle->dle_mintxg < maxtxg; 340219089Spjd dle = AVL_NEXT(&dl->dl_tree, dle)) { 341219089Spjd uint64_t used, comp, uncomp; 342219089Spjd 343219089Spjd VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 344219089Spjd &used, &comp, &uncomp)); 345219089Spjd 346219089Spjd *usedp += used; 347219089Spjd *compp += comp; 348219089Spjd *uncompp += uncomp; 349219089Spjd } 350219089Spjd} 351219089Spjd 352219089Spjdstatic void 353219089Spjddsl_deadlist_insert_bpobj(dsl_deadlist_t *dl, uint64_t obj, uint64_t birth, 354219089Spjd dmu_tx_t *tx) 355219089Spjd{ 356219089Spjd dsl_deadlist_entry_t dle_tofind; 357219089Spjd dsl_deadlist_entry_t *dle; 358219089Spjd avl_index_t where; 359219089Spjd uint64_t used, comp, uncomp; 360219089Spjd bpobj_t bpo; 361219089Spjd 362219089Spjd VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 363219089Spjd VERIFY3U(0, ==, bpobj_space(&bpo, &used, &comp, &uncomp)); 364219089Spjd bpobj_close(&bpo); 365219089Spjd 366219089Spjd dsl_deadlist_load_tree(dl); 367219089Spjd 368219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 369219089Spjd mutex_enter(&dl->dl_lock); 370219089Spjd dl->dl_phys->dl_used += used; 371219089Spjd dl->dl_phys->dl_comp += comp; 372219089Spjd dl->dl_phys->dl_uncomp += uncomp; 373219089Spjd mutex_exit(&dl->dl_lock); 374219089Spjd 375219089Spjd dle_tofind.dle_mintxg = birth; 376219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 377219089Spjd if (dle == NULL) 378219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 379219089Spjd bpobj_enqueue_subobj(&dle->dle_bpobj, obj, tx); 380219089Spjd} 381219089Spjd 382219089Spjdstatic int 383219089Spjddsl_deadlist_insert_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) 384219089Spjd{ 385219089Spjd dsl_deadlist_t *dl = arg; 386219089Spjd dsl_deadlist_insert(dl, bp, tx); 387219089Spjd return (0); 388219089Spjd} 389219089Spjd 390219089Spjd/* 391219089Spjd * Merge the deadlist pointed to by 'obj' into dl. obj will be left as 392219089Spjd * an empty deadlist. 393219089Spjd */ 394219089Spjdvoid 395219089Spjddsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx) 396219089Spjd{ 397219089Spjd zap_cursor_t zc; 398219089Spjd zap_attribute_t za; 399219089Spjd dmu_buf_t *bonus; 400219089Spjd dsl_deadlist_phys_t *dlp; 401219089Spjd dmu_object_info_t doi; 402219089Spjd 403219089Spjd VERIFY3U(0, ==, dmu_object_info(dl->dl_os, obj, &doi)); 404219089Spjd if (doi.doi_type == DMU_OT_BPOBJ) { 405219089Spjd bpobj_t bpo; 406219089Spjd VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 407219089Spjd VERIFY3U(0, ==, bpobj_iterate(&bpo, 408219089Spjd dsl_deadlist_insert_cb, dl, tx)); 409219089Spjd bpobj_close(&bpo); 410219089Spjd return; 411219089Spjd } 412219089Spjd 413219089Spjd for (zap_cursor_init(&zc, dl->dl_os, obj); 414219089Spjd zap_cursor_retrieve(&zc, &za) == 0; 415219089Spjd zap_cursor_advance(&zc)) { 416219089Spjd uint64_t mintxg = strtonum(za.za_name, NULL); 417219089Spjd dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx); 418219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx)); 419219089Spjd } 420219089Spjd zap_cursor_fini(&zc); 421219089Spjd 422219089Spjd VERIFY3U(0, ==, dmu_bonus_hold(dl->dl_os, obj, FTAG, &bonus)); 423219089Spjd dlp = bonus->db_data; 424219089Spjd dmu_buf_will_dirty(bonus, tx); 425219089Spjd bzero(dlp, sizeof (*dlp)); 426219089Spjd dmu_buf_rele(bonus, FTAG); 427219089Spjd} 428219089Spjd 429219089Spjd/* 430219089Spjd * Remove entries on dl that are >= mintxg, and put them on the bpobj. 431219089Spjd */ 432219089Spjdvoid 433219089Spjddsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg, 434219089Spjd dmu_tx_t *tx) 435219089Spjd{ 436219089Spjd dsl_deadlist_entry_t dle_tofind; 437219089Spjd dsl_deadlist_entry_t *dle; 438219089Spjd avl_index_t where; 439219089Spjd 440219089Spjd ASSERT(!dl->dl_oldfmt); 441219089Spjd dmu_buf_will_dirty(dl->dl_dbuf, tx); 442219089Spjd dsl_deadlist_load_tree(dl); 443219089Spjd 444219089Spjd dle_tofind.dle_mintxg = mintxg; 445219089Spjd dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 446219089Spjd if (dle == NULL) 447219089Spjd dle = avl_nearest(&dl->dl_tree, where, AVL_AFTER); 448219089Spjd while (dle) { 449219089Spjd uint64_t used, comp, uncomp; 450219089Spjd dsl_deadlist_entry_t *dle_next; 451219089Spjd 452219089Spjd bpobj_enqueue_subobj(bpo, dle->dle_bpobj.bpo_object, tx); 453219089Spjd 454219089Spjd VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 455219089Spjd &used, &comp, &uncomp)); 456219089Spjd mutex_enter(&dl->dl_lock); 457219089Spjd ASSERT3U(dl->dl_phys->dl_used, >=, used); 458219089Spjd ASSERT3U(dl->dl_phys->dl_comp, >=, comp); 459219089Spjd ASSERT3U(dl->dl_phys->dl_uncomp, >=, uncomp); 460219089Spjd dl->dl_phys->dl_used -= used; 461219089Spjd dl->dl_phys->dl_comp -= comp; 462219089Spjd dl->dl_phys->dl_uncomp -= uncomp; 463219089Spjd mutex_exit(&dl->dl_lock); 464219089Spjd 465219089Spjd VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, 466219089Spjd dle->dle_mintxg, tx)); 467219089Spjd 468219089Spjd dle_next = AVL_NEXT(&dl->dl_tree, dle); 469219089Spjd avl_remove(&dl->dl_tree, dle); 470219089Spjd bpobj_close(&dle->dle_bpobj); 471219089Spjd kmem_free(dle, sizeof (*dle)); 472219089Spjd dle = dle_next; 473219089Spjd } 474219089Spjd} 475