1cde58dbcSMatthew Ahrens /* 2cde58dbcSMatthew Ahrens * CDDL HEADER START 3cde58dbcSMatthew Ahrens * 4cde58dbcSMatthew Ahrens * The contents of this file are subject to the terms of the 5cde58dbcSMatthew Ahrens * Common Development and Distribution License (the "License"). 6cde58dbcSMatthew Ahrens * You may not use this file except in compliance with the License. 7cde58dbcSMatthew Ahrens * 8cde58dbcSMatthew Ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9cde58dbcSMatthew Ahrens * or http://www.opensolaris.org/os/licensing. 10cde58dbcSMatthew Ahrens * See the License for the specific language governing permissions 11cde58dbcSMatthew Ahrens * and limitations under the License. 12cde58dbcSMatthew Ahrens * 13cde58dbcSMatthew Ahrens * When distributing Covered Code, include this CDDL HEADER in each 14cde58dbcSMatthew Ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15cde58dbcSMatthew Ahrens * If applicable, add the following below this CDDL HEADER, with the 16cde58dbcSMatthew Ahrens * fields enclosed by brackets "[]" replaced with your own identifying 17cde58dbcSMatthew Ahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18cde58dbcSMatthew Ahrens * 19cde58dbcSMatthew Ahrens * CDDL HEADER END 20cde58dbcSMatthew Ahrens */ 21cde58dbcSMatthew Ahrens /* 22cde58dbcSMatthew Ahrens * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23cde58dbcSMatthew Ahrens */ 24cde58dbcSMatthew Ahrens 25cde58dbcSMatthew Ahrens #include <sys/dsl_dataset.h> 26cde58dbcSMatthew Ahrens #include <sys/dmu.h> 27cde58dbcSMatthew Ahrens #include <sys/refcount.h> 28cde58dbcSMatthew Ahrens #include <sys/zap.h> 29cde58dbcSMatthew Ahrens #include <sys/zfs_context.h> 30cde58dbcSMatthew Ahrens #include <sys/dsl_pool.h> 31cde58dbcSMatthew Ahrens 32cde58dbcSMatthew Ahrens static int 33cde58dbcSMatthew Ahrens dsl_deadlist_compare(const void *arg1, const void *arg2) 34cde58dbcSMatthew Ahrens { 35cde58dbcSMatthew Ahrens const dsl_deadlist_entry_t *dle1 = arg1; 36cde58dbcSMatthew Ahrens const dsl_deadlist_entry_t *dle2 = arg2; 37cde58dbcSMatthew Ahrens 38cde58dbcSMatthew Ahrens if (dle1->dle_mintxg < dle2->dle_mintxg) 39cde58dbcSMatthew Ahrens return (-1); 40cde58dbcSMatthew Ahrens else if (dle1->dle_mintxg > dle2->dle_mintxg) 41cde58dbcSMatthew Ahrens return (+1); 42cde58dbcSMatthew Ahrens else 43cde58dbcSMatthew Ahrens return (0); 44cde58dbcSMatthew Ahrens } 45cde58dbcSMatthew Ahrens 46cde58dbcSMatthew Ahrens static void 47cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dsl_deadlist_t *dl) 48cde58dbcSMatthew Ahrens { 49cde58dbcSMatthew Ahrens zap_cursor_t zc; 50cde58dbcSMatthew Ahrens zap_attribute_t za; 51cde58dbcSMatthew Ahrens 52cde58dbcSMatthew Ahrens ASSERT(!dl->dl_oldfmt); 53cde58dbcSMatthew Ahrens if (dl->dl_havetree) 54cde58dbcSMatthew Ahrens return; 55cde58dbcSMatthew Ahrens 56cde58dbcSMatthew Ahrens avl_create(&dl->dl_tree, dsl_deadlist_compare, 57cde58dbcSMatthew Ahrens sizeof (dsl_deadlist_entry_t), 58cde58dbcSMatthew Ahrens offsetof(dsl_deadlist_entry_t, dle_node)); 59cde58dbcSMatthew Ahrens for (zap_cursor_init(&zc, dl->dl_os, dl->dl_object); 60cde58dbcSMatthew Ahrens zap_cursor_retrieve(&zc, &za) == 0; 61cde58dbcSMatthew Ahrens zap_cursor_advance(&zc)) { 62cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 63cde58dbcSMatthew Ahrens dle->dle_mintxg = strtonum(za.za_name, NULL); 64cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, 65cde58dbcSMatthew Ahrens za.za_first_integer)); 66cde58dbcSMatthew Ahrens avl_add(&dl->dl_tree, dle); 67cde58dbcSMatthew Ahrens } 68cde58dbcSMatthew Ahrens zap_cursor_fini(&zc); 69cde58dbcSMatthew Ahrens dl->dl_havetree = B_TRUE; 70cde58dbcSMatthew Ahrens } 71cde58dbcSMatthew Ahrens 72cde58dbcSMatthew Ahrens void 73cde58dbcSMatthew Ahrens dsl_deadlist_open(dsl_deadlist_t *dl, objset_t *os, uint64_t object) 74cde58dbcSMatthew Ahrens { 75cde58dbcSMatthew Ahrens dmu_object_info_t doi; 76cde58dbcSMatthew Ahrens 77cde58dbcSMatthew Ahrens mutex_init(&dl->dl_lock, NULL, MUTEX_DEFAULT, NULL); 78cde58dbcSMatthew Ahrens dl->dl_os = os; 79cde58dbcSMatthew Ahrens dl->dl_object = object; 80cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dmu_bonus_hold(os, object, dl, &dl->dl_dbuf)); 81cde58dbcSMatthew Ahrens dmu_object_info_from_db(dl->dl_dbuf, &doi); 82cde58dbcSMatthew Ahrens if (doi.doi_type == DMU_OT_BPOBJ) { 83cde58dbcSMatthew Ahrens dmu_buf_rele(dl->dl_dbuf, dl); 84cde58dbcSMatthew Ahrens dl->dl_dbuf = NULL; 85cde58dbcSMatthew Ahrens dl->dl_oldfmt = B_TRUE; 86cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_open(&dl->dl_bpobj, os, object)); 87cde58dbcSMatthew Ahrens return; 88cde58dbcSMatthew Ahrens } 89cde58dbcSMatthew Ahrens 90cde58dbcSMatthew Ahrens dl->dl_oldfmt = B_FALSE; 91cde58dbcSMatthew Ahrens dl->dl_phys = dl->dl_dbuf->db_data; 92cde58dbcSMatthew Ahrens dl->dl_havetree = B_FALSE; 93cde58dbcSMatthew Ahrens } 94cde58dbcSMatthew Ahrens 95cde58dbcSMatthew Ahrens void 96cde58dbcSMatthew Ahrens dsl_deadlist_close(dsl_deadlist_t *dl) 97cde58dbcSMatthew Ahrens { 98cde58dbcSMatthew Ahrens void *cookie = NULL; 99cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 100cde58dbcSMatthew Ahrens 101cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) { 102cde58dbcSMatthew Ahrens dl->dl_oldfmt = B_FALSE; 103cde58dbcSMatthew Ahrens bpobj_close(&dl->dl_bpobj); 104cde58dbcSMatthew Ahrens return; 105cde58dbcSMatthew Ahrens } 106cde58dbcSMatthew Ahrens 107cde58dbcSMatthew Ahrens if (dl->dl_havetree) { 108cde58dbcSMatthew Ahrens while ((dle = avl_destroy_nodes(&dl->dl_tree, &cookie)) 109cde58dbcSMatthew Ahrens != NULL) { 110cde58dbcSMatthew Ahrens bpobj_close(&dle->dle_bpobj); 111cde58dbcSMatthew Ahrens kmem_free(dle, sizeof (*dle)); 112cde58dbcSMatthew Ahrens } 113cde58dbcSMatthew Ahrens avl_destroy(&dl->dl_tree); 114cde58dbcSMatthew Ahrens } 115cde58dbcSMatthew Ahrens dmu_buf_rele(dl->dl_dbuf, dl); 116cde58dbcSMatthew Ahrens mutex_destroy(&dl->dl_lock); 117cde58dbcSMatthew Ahrens dl->dl_dbuf = NULL; 118cde58dbcSMatthew Ahrens dl->dl_phys = NULL; 119cde58dbcSMatthew Ahrens } 120cde58dbcSMatthew Ahrens 121cde58dbcSMatthew Ahrens uint64_t 122cde58dbcSMatthew Ahrens dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx) 123cde58dbcSMatthew Ahrens { 124cde58dbcSMatthew Ahrens if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS) 125cde58dbcSMatthew Ahrens return (bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx)); 126cde58dbcSMatthew Ahrens return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR, 127cde58dbcSMatthew Ahrens sizeof (dsl_deadlist_phys_t), tx)); 128cde58dbcSMatthew Ahrens } 129cde58dbcSMatthew Ahrens 130cde58dbcSMatthew Ahrens void 131cde58dbcSMatthew Ahrens dsl_deadlist_free(objset_t *os, uint64_t dlobj, dmu_tx_t *tx) 132cde58dbcSMatthew Ahrens { 133cde58dbcSMatthew Ahrens dmu_object_info_t doi; 134cde58dbcSMatthew Ahrens zap_cursor_t zc; 135cde58dbcSMatthew Ahrens zap_attribute_t za; 136cde58dbcSMatthew Ahrens 137cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dmu_object_info(os, dlobj, &doi)); 138cde58dbcSMatthew Ahrens if (doi.doi_type == DMU_OT_BPOBJ) { 139cde58dbcSMatthew Ahrens bpobj_free(os, dlobj, tx); 140cde58dbcSMatthew Ahrens return; 141cde58dbcSMatthew Ahrens } 142cde58dbcSMatthew Ahrens 143cde58dbcSMatthew Ahrens for (zap_cursor_init(&zc, os, dlobj); 144cde58dbcSMatthew Ahrens zap_cursor_retrieve(&zc, &za) == 0; 145cde58dbcSMatthew Ahrens zap_cursor_advance(&zc)) 146cde58dbcSMatthew Ahrens bpobj_free(os, za.za_first_integer, tx); 147cde58dbcSMatthew Ahrens zap_cursor_fini(&zc); 148cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dmu_object_free(os, dlobj, tx)); 149cde58dbcSMatthew Ahrens } 150cde58dbcSMatthew Ahrens 151cde58dbcSMatthew Ahrens void 152cde58dbcSMatthew Ahrens dsl_deadlist_insert(dsl_deadlist_t *dl, const blkptr_t *bp, dmu_tx_t *tx) 153cde58dbcSMatthew Ahrens { 154cde58dbcSMatthew Ahrens dsl_deadlist_entry_t dle_tofind; 155cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 156cde58dbcSMatthew Ahrens avl_index_t where; 157cde58dbcSMatthew Ahrens 158cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) { 159cde58dbcSMatthew Ahrens bpobj_enqueue(&dl->dl_bpobj, bp, tx); 160cde58dbcSMatthew Ahrens return; 161cde58dbcSMatthew Ahrens } 162cde58dbcSMatthew Ahrens 163cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 164cde58dbcSMatthew Ahrens 165cde58dbcSMatthew Ahrens dmu_buf_will_dirty(dl->dl_dbuf, tx); 166cde58dbcSMatthew Ahrens mutex_enter(&dl->dl_lock); 167cde58dbcSMatthew Ahrens dl->dl_phys->dl_used += 168cde58dbcSMatthew Ahrens bp_get_dsize_sync(dmu_objset_spa(dl->dl_os), bp); 169cde58dbcSMatthew Ahrens dl->dl_phys->dl_comp += BP_GET_PSIZE(bp); 170cde58dbcSMatthew Ahrens dl->dl_phys->dl_uncomp += BP_GET_UCSIZE(bp); 171cde58dbcSMatthew Ahrens mutex_exit(&dl->dl_lock); 172cde58dbcSMatthew Ahrens 173cde58dbcSMatthew Ahrens dle_tofind.dle_mintxg = bp->blk_birth; 174cde58dbcSMatthew Ahrens dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 175cde58dbcSMatthew Ahrens if (dle == NULL) 176cde58dbcSMatthew Ahrens dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 177cde58dbcSMatthew Ahrens else 178cde58dbcSMatthew Ahrens dle = AVL_PREV(&dl->dl_tree, dle); 179cde58dbcSMatthew Ahrens bpobj_enqueue(&dle->dle_bpobj, bp, tx); 180cde58dbcSMatthew Ahrens } 181cde58dbcSMatthew Ahrens 182cde58dbcSMatthew Ahrens /* 183cde58dbcSMatthew Ahrens * Insert new key in deadlist, which must be > all current entries. 184cde58dbcSMatthew Ahrens * mintxg is not inclusive. 185cde58dbcSMatthew Ahrens */ 186cde58dbcSMatthew Ahrens void 187cde58dbcSMatthew Ahrens dsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 188cde58dbcSMatthew Ahrens { 189cde58dbcSMatthew Ahrens uint64_t obj; 190cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 191cde58dbcSMatthew Ahrens 192cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) 193cde58dbcSMatthew Ahrens return; 194cde58dbcSMatthew Ahrens 195cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 196cde58dbcSMatthew Ahrens 197cde58dbcSMatthew Ahrens dle = kmem_alloc(sizeof (*dle), KM_SLEEP); 198cde58dbcSMatthew Ahrens dle->dle_mintxg = mintxg; 199cde58dbcSMatthew Ahrens obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 200cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); 201cde58dbcSMatthew Ahrens avl_add(&dl->dl_tree, dle); 202cde58dbcSMatthew Ahrens 203cde58dbcSMatthew Ahrens VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, dl->dl_object, 204cde58dbcSMatthew Ahrens mintxg, obj, tx)); 205cde58dbcSMatthew Ahrens } 206cde58dbcSMatthew Ahrens 207cde58dbcSMatthew Ahrens /* 208cde58dbcSMatthew Ahrens * Remove this key, merging its entries into the previous key. 209cde58dbcSMatthew Ahrens */ 210cde58dbcSMatthew Ahrens void 211cde58dbcSMatthew Ahrens dsl_deadlist_remove_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) 212cde58dbcSMatthew Ahrens { 213cde58dbcSMatthew Ahrens dsl_deadlist_entry_t dle_tofind; 214cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle, *dle_prev; 215cde58dbcSMatthew Ahrens 216cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) 217cde58dbcSMatthew Ahrens return; 218cde58dbcSMatthew Ahrens 219cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 220cde58dbcSMatthew Ahrens 221cde58dbcSMatthew Ahrens dle_tofind.dle_mintxg = mintxg; 222cde58dbcSMatthew Ahrens dle = avl_find(&dl->dl_tree, &dle_tofind, NULL); 223cde58dbcSMatthew Ahrens dle_prev = AVL_PREV(&dl->dl_tree, dle); 224cde58dbcSMatthew Ahrens 225cde58dbcSMatthew Ahrens bpobj_enqueue_subobj(&dle_prev->dle_bpobj, 226cde58dbcSMatthew Ahrens dle->dle_bpobj.bpo_object, tx); 227cde58dbcSMatthew Ahrens 228cde58dbcSMatthew Ahrens avl_remove(&dl->dl_tree, dle); 229cde58dbcSMatthew Ahrens bpobj_close(&dle->dle_bpobj); 230cde58dbcSMatthew Ahrens kmem_free(dle, sizeof (*dle)); 231cde58dbcSMatthew Ahrens 232cde58dbcSMatthew Ahrens VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, mintxg, tx)); 233cde58dbcSMatthew Ahrens } 234cde58dbcSMatthew Ahrens 235cde58dbcSMatthew Ahrens /* 236cde58dbcSMatthew Ahrens * Walk ds's snapshots to regenerate generate ZAP & AVL. 237cde58dbcSMatthew Ahrens */ 238cde58dbcSMatthew Ahrens static void 239cde58dbcSMatthew Ahrens dsl_deadlist_regenerate(objset_t *os, uint64_t dlobj, 240cde58dbcSMatthew Ahrens uint64_t mrs_obj, dmu_tx_t *tx) 241cde58dbcSMatthew Ahrens { 242cde58dbcSMatthew Ahrens dsl_deadlist_t dl; 243cde58dbcSMatthew Ahrens dsl_pool_t *dp = dmu_objset_pool(os); 244cde58dbcSMatthew Ahrens 245cde58dbcSMatthew Ahrens dsl_deadlist_open(&dl, os, dlobj); 246cde58dbcSMatthew Ahrens if (dl.dl_oldfmt) { 247cde58dbcSMatthew Ahrens dsl_deadlist_close(&dl); 248cde58dbcSMatthew Ahrens return; 249cde58dbcSMatthew Ahrens } 250cde58dbcSMatthew Ahrens 251cde58dbcSMatthew Ahrens while (mrs_obj != 0) { 252cde58dbcSMatthew Ahrens dsl_dataset_t *ds; 253cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, mrs_obj, FTAG, &ds)); 254cde58dbcSMatthew Ahrens dsl_deadlist_add_key(&dl, ds->ds_phys->ds_prev_snap_txg, tx); 255cde58dbcSMatthew Ahrens mrs_obj = ds->ds_phys->ds_prev_snap_obj; 256cde58dbcSMatthew Ahrens dsl_dataset_rele(ds, FTAG); 257cde58dbcSMatthew Ahrens } 258cde58dbcSMatthew Ahrens dsl_deadlist_close(&dl); 259cde58dbcSMatthew Ahrens } 260cde58dbcSMatthew Ahrens 261cde58dbcSMatthew Ahrens uint64_t 262cde58dbcSMatthew Ahrens dsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg, 263cde58dbcSMatthew Ahrens uint64_t mrs_obj, dmu_tx_t *tx) 264cde58dbcSMatthew Ahrens { 265cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 266cde58dbcSMatthew Ahrens uint64_t newobj; 267cde58dbcSMatthew Ahrens 268cde58dbcSMatthew Ahrens newobj = dsl_deadlist_alloc(dl->dl_os, tx); 269cde58dbcSMatthew Ahrens 270cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) { 271cde58dbcSMatthew Ahrens dsl_deadlist_regenerate(dl->dl_os, newobj, mrs_obj, tx); 272cde58dbcSMatthew Ahrens return (newobj); 273cde58dbcSMatthew Ahrens } 274cde58dbcSMatthew Ahrens 275cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 276cde58dbcSMatthew Ahrens 277cde58dbcSMatthew Ahrens for (dle = avl_first(&dl->dl_tree); dle; 278cde58dbcSMatthew Ahrens dle = AVL_NEXT(&dl->dl_tree, dle)) { 279cde58dbcSMatthew Ahrens uint64_t obj; 280cde58dbcSMatthew Ahrens 281cde58dbcSMatthew Ahrens if (dle->dle_mintxg >= maxtxg) 282cde58dbcSMatthew Ahrens break; 283cde58dbcSMatthew Ahrens 284cde58dbcSMatthew Ahrens obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); 285cde58dbcSMatthew Ahrens VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj, 286cde58dbcSMatthew Ahrens dle->dle_mintxg, obj, tx)); 287cde58dbcSMatthew Ahrens } 288cde58dbcSMatthew Ahrens return (newobj); 289cde58dbcSMatthew Ahrens } 290cde58dbcSMatthew Ahrens 291cde58dbcSMatthew Ahrens void 292cde58dbcSMatthew Ahrens dsl_deadlist_space(dsl_deadlist_t *dl, 293cde58dbcSMatthew Ahrens uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 294cde58dbcSMatthew Ahrens { 295cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) { 296cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_space(&dl->dl_bpobj, 297cde58dbcSMatthew Ahrens usedp, compp, uncompp)); 298cde58dbcSMatthew Ahrens return; 299cde58dbcSMatthew Ahrens } 300cde58dbcSMatthew Ahrens 301cde58dbcSMatthew Ahrens mutex_enter(&dl->dl_lock); 302cde58dbcSMatthew Ahrens *usedp = dl->dl_phys->dl_used; 303cde58dbcSMatthew Ahrens *compp = dl->dl_phys->dl_comp; 304cde58dbcSMatthew Ahrens *uncompp = dl->dl_phys->dl_uncomp; 305cde58dbcSMatthew Ahrens mutex_exit(&dl->dl_lock); 306cde58dbcSMatthew Ahrens } 307cde58dbcSMatthew Ahrens 308cde58dbcSMatthew Ahrens /* 309cde58dbcSMatthew Ahrens * return space used in the range (mintxg, maxtxg]. 310cde58dbcSMatthew Ahrens * Includes maxtxg, does not include mintxg. 311cde58dbcSMatthew Ahrens * mintxg and maxtxg must both be keys in the deadlist (unless maxtxg is 312*8ac09fceSRichard Lowe * UINT64_MAX). 313cde58dbcSMatthew Ahrens */ 314cde58dbcSMatthew Ahrens void 315cde58dbcSMatthew Ahrens dsl_deadlist_space_range(dsl_deadlist_t *dl, uint64_t mintxg, uint64_t maxtxg, 316cde58dbcSMatthew Ahrens uint64_t *usedp, uint64_t *compp, uint64_t *uncompp) 317cde58dbcSMatthew Ahrens { 318e5351341SMatthew Ahrens dsl_deadlist_entry_t dle_tofind; 319*8ac09fceSRichard Lowe dsl_deadlist_entry_t *dle; 320cde58dbcSMatthew Ahrens avl_index_t where; 321cde58dbcSMatthew Ahrens 322cde58dbcSMatthew Ahrens if (dl->dl_oldfmt) { 323cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_space_range(&dl->dl_bpobj, 324cde58dbcSMatthew Ahrens mintxg, maxtxg, usedp, compp, uncompp)); 325cde58dbcSMatthew Ahrens return; 326cde58dbcSMatthew Ahrens } 327cde58dbcSMatthew Ahrens 328*8ac09fceSRichard Lowe dsl_deadlist_load_tree(dl); 329cde58dbcSMatthew Ahrens *usedp = *compp = *uncompp = 0; 330cde58dbcSMatthew Ahrens 331cde58dbcSMatthew Ahrens dle_tofind.dle_mintxg = mintxg; 332cde58dbcSMatthew Ahrens dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 333cde58dbcSMatthew Ahrens /* 334cde58dbcSMatthew Ahrens * If we don't find this mintxg, there shouldn't be anything 335cde58dbcSMatthew Ahrens * after it either. 336cde58dbcSMatthew Ahrens */ 337cde58dbcSMatthew Ahrens ASSERT(dle != NULL || 338cde58dbcSMatthew Ahrens avl_nearest(&dl->dl_tree, where, AVL_AFTER) == NULL); 339cde58dbcSMatthew Ahrens for (; dle && dle->dle_mintxg < maxtxg; 340cde58dbcSMatthew Ahrens dle = AVL_NEXT(&dl->dl_tree, dle)) { 341cde58dbcSMatthew Ahrens uint64_t used, comp, uncomp; 342cde58dbcSMatthew Ahrens 343cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 344cde58dbcSMatthew Ahrens &used, &comp, &uncomp)); 345cde58dbcSMatthew Ahrens 346cde58dbcSMatthew Ahrens *usedp += used; 347cde58dbcSMatthew Ahrens *compp += comp; 348cde58dbcSMatthew Ahrens *uncompp += uncomp; 349cde58dbcSMatthew Ahrens } 350cde58dbcSMatthew Ahrens } 351cde58dbcSMatthew Ahrens 352cde58dbcSMatthew Ahrens static void 353cde58dbcSMatthew Ahrens dsl_deadlist_insert_bpobj(dsl_deadlist_t *dl, uint64_t obj, uint64_t birth, 354cde58dbcSMatthew Ahrens dmu_tx_t *tx) 355cde58dbcSMatthew Ahrens { 356cde58dbcSMatthew Ahrens dsl_deadlist_entry_t dle_tofind; 357cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 358cde58dbcSMatthew Ahrens avl_index_t where; 359cde58dbcSMatthew Ahrens uint64_t used, comp, uncomp; 360cde58dbcSMatthew Ahrens bpobj_t bpo; 361cde58dbcSMatthew Ahrens 362cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 363cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_space(&bpo, &used, &comp, &uncomp)); 364cde58dbcSMatthew Ahrens bpobj_close(&bpo); 365cde58dbcSMatthew Ahrens 366cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 367cde58dbcSMatthew Ahrens 368cde58dbcSMatthew Ahrens dmu_buf_will_dirty(dl->dl_dbuf, tx); 369cde58dbcSMatthew Ahrens mutex_enter(&dl->dl_lock); 370cde58dbcSMatthew Ahrens dl->dl_phys->dl_used += used; 371cde58dbcSMatthew Ahrens dl->dl_phys->dl_comp += comp; 372cde58dbcSMatthew Ahrens dl->dl_phys->dl_uncomp += uncomp; 373cde58dbcSMatthew Ahrens mutex_exit(&dl->dl_lock); 374cde58dbcSMatthew Ahrens 375cde58dbcSMatthew Ahrens dle_tofind.dle_mintxg = birth; 376cde58dbcSMatthew Ahrens dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 377cde58dbcSMatthew Ahrens if (dle == NULL) 378cde58dbcSMatthew Ahrens dle = avl_nearest(&dl->dl_tree, where, AVL_BEFORE); 379cde58dbcSMatthew Ahrens bpobj_enqueue_subobj(&dle->dle_bpobj, obj, tx); 380cde58dbcSMatthew Ahrens } 381cde58dbcSMatthew Ahrens 382cde58dbcSMatthew Ahrens static int 383cde58dbcSMatthew Ahrens dsl_deadlist_insert_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) 384cde58dbcSMatthew Ahrens { 385cde58dbcSMatthew Ahrens dsl_deadlist_t *dl = arg; 386cde58dbcSMatthew Ahrens dsl_deadlist_insert(dl, bp, tx); 387cde58dbcSMatthew Ahrens return (0); 388cde58dbcSMatthew Ahrens } 389cde58dbcSMatthew Ahrens 390cde58dbcSMatthew Ahrens /* 391cde58dbcSMatthew Ahrens * Merge the deadlist pointed to by 'obj' into dl. obj will be left as 392cde58dbcSMatthew Ahrens * an empty deadlist. 393cde58dbcSMatthew Ahrens */ 394cde58dbcSMatthew Ahrens void 395cde58dbcSMatthew Ahrens dsl_deadlist_merge(dsl_deadlist_t *dl, uint64_t obj, dmu_tx_t *tx) 396cde58dbcSMatthew Ahrens { 397cde58dbcSMatthew Ahrens zap_cursor_t zc; 398cde58dbcSMatthew Ahrens zap_attribute_t za; 399cde58dbcSMatthew Ahrens dmu_buf_t *bonus; 400cde58dbcSMatthew Ahrens dsl_deadlist_phys_t *dlp; 401cde58dbcSMatthew Ahrens dmu_object_info_t doi; 402cde58dbcSMatthew Ahrens 403cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dmu_object_info(dl->dl_os, obj, &doi)); 404cde58dbcSMatthew Ahrens if (doi.doi_type == DMU_OT_BPOBJ) { 405cde58dbcSMatthew Ahrens bpobj_t bpo; 406cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_open(&bpo, dl->dl_os, obj)); 407cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_iterate(&bpo, 408cde58dbcSMatthew Ahrens dsl_deadlist_insert_cb, dl, tx)); 409cde58dbcSMatthew Ahrens bpobj_close(&bpo); 410cde58dbcSMatthew Ahrens return; 411cde58dbcSMatthew Ahrens } 412cde58dbcSMatthew Ahrens 413cde58dbcSMatthew Ahrens for (zap_cursor_init(&zc, dl->dl_os, obj); 414cde58dbcSMatthew Ahrens zap_cursor_retrieve(&zc, &za) == 0; 415cde58dbcSMatthew Ahrens zap_cursor_advance(&zc)) { 416cde58dbcSMatthew Ahrens uint64_t mintxg = strtonum(za.za_name, NULL); 417cde58dbcSMatthew Ahrens dsl_deadlist_insert_bpobj(dl, za.za_first_integer, mintxg, tx); 418cde58dbcSMatthew Ahrens VERIFY3U(0, ==, zap_remove_int(dl->dl_os, obj, mintxg, tx)); 419cde58dbcSMatthew Ahrens } 420cde58dbcSMatthew Ahrens zap_cursor_fini(&zc); 421cde58dbcSMatthew Ahrens 422cde58dbcSMatthew Ahrens VERIFY3U(0, ==, dmu_bonus_hold(dl->dl_os, obj, FTAG, &bonus)); 423cde58dbcSMatthew Ahrens dlp = bonus->db_data; 424cde58dbcSMatthew Ahrens dmu_buf_will_dirty(bonus, tx); 425cde58dbcSMatthew Ahrens bzero(dlp, sizeof (*dlp)); 426cde58dbcSMatthew Ahrens dmu_buf_rele(bonus, FTAG); 427cde58dbcSMatthew Ahrens } 428cde58dbcSMatthew Ahrens 429cde58dbcSMatthew Ahrens /* 430cde58dbcSMatthew Ahrens * Remove entries on dl that are >= mintxg, and put them on the bpobj. 431cde58dbcSMatthew Ahrens */ 432cde58dbcSMatthew Ahrens void 433cde58dbcSMatthew Ahrens dsl_deadlist_move_bpobj(dsl_deadlist_t *dl, bpobj_t *bpo, uint64_t mintxg, 434cde58dbcSMatthew Ahrens dmu_tx_t *tx) 435cde58dbcSMatthew Ahrens { 436cde58dbcSMatthew Ahrens dsl_deadlist_entry_t dle_tofind; 437cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle; 438cde58dbcSMatthew Ahrens avl_index_t where; 439cde58dbcSMatthew Ahrens 440cde58dbcSMatthew Ahrens ASSERT(!dl->dl_oldfmt); 441cde58dbcSMatthew Ahrens dmu_buf_will_dirty(dl->dl_dbuf, tx); 442cde58dbcSMatthew Ahrens dsl_deadlist_load_tree(dl); 443cde58dbcSMatthew Ahrens 444cde58dbcSMatthew Ahrens dle_tofind.dle_mintxg = mintxg; 445cde58dbcSMatthew Ahrens dle = avl_find(&dl->dl_tree, &dle_tofind, &where); 446cde58dbcSMatthew Ahrens if (dle == NULL) 447cde58dbcSMatthew Ahrens dle = avl_nearest(&dl->dl_tree, where, AVL_AFTER); 448cde58dbcSMatthew Ahrens while (dle) { 449cde58dbcSMatthew Ahrens uint64_t used, comp, uncomp; 450cde58dbcSMatthew Ahrens dsl_deadlist_entry_t *dle_next; 451cde58dbcSMatthew Ahrens 452cde58dbcSMatthew Ahrens bpobj_enqueue_subobj(bpo, dle->dle_bpobj.bpo_object, tx); 453cde58dbcSMatthew Ahrens 454cde58dbcSMatthew Ahrens VERIFY3U(0, ==, bpobj_space(&dle->dle_bpobj, 455cde58dbcSMatthew Ahrens &used, &comp, &uncomp)); 456cde58dbcSMatthew Ahrens mutex_enter(&dl->dl_lock); 457cde58dbcSMatthew Ahrens ASSERT3U(dl->dl_phys->dl_used, >=, used); 458cde58dbcSMatthew Ahrens ASSERT3U(dl->dl_phys->dl_comp, >=, comp); 459cde58dbcSMatthew Ahrens ASSERT3U(dl->dl_phys->dl_uncomp, >=, uncomp); 460cde58dbcSMatthew Ahrens dl->dl_phys->dl_used -= used; 461cde58dbcSMatthew Ahrens dl->dl_phys->dl_comp -= comp; 462cde58dbcSMatthew Ahrens dl->dl_phys->dl_uncomp -= uncomp; 463cde58dbcSMatthew Ahrens mutex_exit(&dl->dl_lock); 464cde58dbcSMatthew Ahrens 465cde58dbcSMatthew Ahrens VERIFY3U(0, ==, zap_remove_int(dl->dl_os, dl->dl_object, 466cde58dbcSMatthew Ahrens dle->dle_mintxg, tx)); 467cde58dbcSMatthew Ahrens 468cde58dbcSMatthew Ahrens dle_next = AVL_NEXT(&dl->dl_tree, dle); 469cde58dbcSMatthew Ahrens avl_remove(&dl->dl_tree, dle); 470cde58dbcSMatthew Ahrens bpobj_close(&dle->dle_bpobj); 471cde58dbcSMatthew Ahrens kmem_free(dle, sizeof (*dle)); 472cde58dbcSMatthew Ahrens dle = dle_next; 473cde58dbcSMatthew Ahrens } 474cde58dbcSMatthew Ahrens } 475