1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5ea8dc4b6Seschrock * Common Development and Distribution License (the "License"). 6ea8dc4b6Seschrock * You may not use this file except in compliance with the License. 7fa9e4066Sahrens * 8fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 10fa9e4066Sahrens * See the License for the specific language governing permissions 11fa9e4066Sahrens * and limitations under the License. 12fa9e4066Sahrens * 13fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e4066Sahrens * 19fa9e4066Sahrens * CDDL HEADER END 20fa9e4066Sahrens */ 21ad135b5dSChristopher Siden 22fa9e4066Sahrens /* 2306e0070dSMark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24c2919acbSMatthew Ahrens * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 25bc9014e6SJustin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. 26fa9e4066Sahrens */ 27fa9e4066Sahrens 28fa9e4066Sahrens #include <sys/zfs_context.h> 29fa9e4066Sahrens #include <sys/dbuf.h> 30fa9e4066Sahrens #include <sys/dnode.h> 31fa9e4066Sahrens #include <sys/dmu.h> 32fa9e4066Sahrens #include <sys/dmu_tx.h> 33fa9e4066Sahrens #include <sys/dmu_objset.h> 34*eb633035STom Caputi #include <sys/dmu_recv.h> 35fa9e4066Sahrens #include <sys/dsl_dataset.h> 36fa9e4066Sahrens #include <sys/spa.h> 37bf16b11eSMatthew Ahrens #include <sys/range_tree.h> 3843466aaeSMax Grossman #include <sys/zfeature.h> 39fa9e4066Sahrens 40fa9e4066Sahrens static void 41fa9e4066Sahrens dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx) 42fa9e4066Sahrens { 43fa9e4066Sahrens dmu_buf_impl_t *db; 44c717a561Smaybee int txgoff = tx->tx_txg & TXG_MASK; 45c717a561Smaybee int nblkptr = dn->dn_phys->dn_nblkptr; 46c717a561Smaybee int old_toplvl = dn->dn_phys->dn_nlevels - 1; 47c717a561Smaybee int new_level = dn->dn_next_nlevels[txgoff]; 48fa9e4066Sahrens int i; 49fa9e4066Sahrens 50c717a561Smaybee rw_enter(&dn->dn_struct_rwlock, RW_WRITER); 51c717a561Smaybee 52c717a561Smaybee /* this dnode can't be paged out because it's dirty */ 53fa9e4066Sahrens ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE); 54fa9e4066Sahrens ASSERT(RW_WRITE_HELD(&dn->dn_struct_rwlock)); 55c717a561Smaybee ASSERT(new_level > 1 && dn->dn_phys->dn_nlevels > 0); 56fa9e4066Sahrens 57fa9e4066Sahrens db = dbuf_hold_level(dn, dn->dn_phys->dn_nlevels, 0, FTAG); 58ea8dc4b6Seschrock ASSERT(db != NULL); 59c717a561Smaybee 60c717a561Smaybee dn->dn_phys->dn_nlevels = new_level; 61f82bfe17Sgw dprintf("os=%p obj=%llu, increase to %d\n", dn->dn_objset, 62f82bfe17Sgw dn->dn_object, dn->dn_phys->dn_nlevels); 63c717a561Smaybee 648df0bcf0SPaul Dagnelie /* transfer dnode's block pointers to new indirect block */ 658df0bcf0SPaul Dagnelie (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED|DB_RF_HAVESTRUCT); 668df0bcf0SPaul Dagnelie ASSERT(db->db.db_data); 678df0bcf0SPaul Dagnelie ASSERT(arc_released(db->db_buf)); 688df0bcf0SPaul Dagnelie ASSERT3U(sizeof (blkptr_t) * nblkptr, <=, db->db.db_size); 698df0bcf0SPaul Dagnelie bcopy(dn->dn_phys->dn_blkptr, db->db.db_data, 708df0bcf0SPaul Dagnelie sizeof (blkptr_t) * nblkptr); 718df0bcf0SPaul Dagnelie arc_buf_freeze(db->db_buf); 72fa9e4066Sahrens 73fa9e4066Sahrens /* set dbuf's parent pointers to new indirect buf */ 74c717a561Smaybee for (i = 0; i < nblkptr; i++) { 75e57a022bSJustin T. Gibbs dmu_buf_impl_t *child = 76e57a022bSJustin T. Gibbs dbuf_find(dn->dn_objset, dn->dn_object, old_toplvl, i); 77c717a561Smaybee 78fa9e4066Sahrens if (child == NULL) 79fa9e4066Sahrens continue; 80744947dcSTom Erickson #ifdef DEBUG 81744947dcSTom Erickson DB_DNODE_ENTER(child); 82744947dcSTom Erickson ASSERT3P(DB_DNODE(child), ==, dn); 83744947dcSTom Erickson DB_DNODE_EXIT(child); 84744947dcSTom Erickson #endif /* DEBUG */ 85c717a561Smaybee if (child->db_parent && child->db_parent != dn->dn_dbuf) { 86c717a561Smaybee ASSERT(child->db_parent->db_level == db->db_level); 87c717a561Smaybee ASSERT(child->db_blkptr != 88c717a561Smaybee &dn->dn_phys->dn_blkptr[child->db_blkid]); 89fa9e4066Sahrens mutex_exit(&child->db_mtx); 90fa9e4066Sahrens continue; 91fa9e4066Sahrens } 92c717a561Smaybee ASSERT(child->db_parent == NULL || 93c717a561Smaybee child->db_parent == dn->dn_dbuf); 94c717a561Smaybee 95c717a561Smaybee child->db_parent = db; 96c717a561Smaybee dbuf_add_ref(db, child); 97c717a561Smaybee if (db->db.db_data) 98c717a561Smaybee child->db_blkptr = (blkptr_t *)db->db.db_data + i; 99c717a561Smaybee else 100c717a561Smaybee child->db_blkptr = NULL; 101c717a561Smaybee dprintf_dbuf_bp(child, child->db_blkptr, 102c717a561Smaybee "changed db_blkptr to new indirect %s", ""); 103fa9e4066Sahrens 104fa9e4066Sahrens mutex_exit(&child->db_mtx); 105fa9e4066Sahrens } 106fa9e4066Sahrens 107c717a561Smaybee bzero(dn->dn_phys->dn_blkptr, sizeof (blkptr_t) * nblkptr); 108fa9e4066Sahrens 109ea8dc4b6Seschrock dbuf_rele(db, FTAG); 110c717a561Smaybee 111c717a561Smaybee rw_exit(&dn->dn_struct_rwlock); 112fa9e4066Sahrens } 113fa9e4066Sahrens 11443466aaeSMax Grossman static void 115fa9e4066Sahrens free_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx) 116fa9e4066Sahrens { 117cdb0ab79Smaybee dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; 118fa9e4066Sahrens uint64_t bytesfreed = 0; 119fa9e4066Sahrens 120cdb0ab79Smaybee dprintf("ds=%p obj=%llx num=%d\n", ds, dn->dn_object, num); 121fa9e4066Sahrens 12243466aaeSMax Grossman for (int i = 0; i < num; i++, bp++) { 123fa9e4066Sahrens if (BP_IS_HOLE(bp)) 124fa9e4066Sahrens continue; 125fa9e4066Sahrens 126b24ab676SJeff Bonwick bytesfreed += dsl_dataset_block_kill(ds, bp, tx, B_FALSE); 12799653d4eSeschrock ASSERT3U(bytesfreed, <=, DN_USED_BYTES(dn->dn_phys)); 12843466aaeSMax Grossman 12943466aaeSMax Grossman /* 13043466aaeSMax Grossman * Save some useful information on the holes being 13143466aaeSMax Grossman * punched, including logical size, type, and indirection 13243466aaeSMax Grossman * level. Retaining birth time enables detection of when 13343466aaeSMax Grossman * holes are punched for reducing the number of free 13443466aaeSMax Grossman * records transmitted during a zfs send. 13543466aaeSMax Grossman */ 13643466aaeSMax Grossman 13743466aaeSMax Grossman uint64_t lsize = BP_GET_LSIZE(bp); 13843466aaeSMax Grossman dmu_object_type_t type = BP_GET_TYPE(bp); 13943466aaeSMax Grossman uint64_t lvl = BP_GET_LEVEL(bp); 14043466aaeSMax Grossman 141c717a561Smaybee bzero(bp, sizeof (blkptr_t)); 14243466aaeSMax Grossman 14343466aaeSMax Grossman if (spa_feature_is_active(dn->dn_objset->os_spa, 14443466aaeSMax Grossman SPA_FEATURE_HOLE_BIRTH)) { 14543466aaeSMax Grossman BP_SET_LSIZE(bp, lsize); 14643466aaeSMax Grossman BP_SET_TYPE(bp, type); 14743466aaeSMax Grossman BP_SET_LEVEL(bp, lvl); 14843466aaeSMax Grossman BP_SET_BIRTH(bp, dmu_tx_get_txg(tx), 0); 14943466aaeSMax Grossman } 150fa9e4066Sahrens } 151fa9e4066Sahrens dnode_diduse_space(dn, -bytesfreed); 152fa9e4066Sahrens } 153fa9e4066Sahrens 1549c9dc39aSek #ifdef ZFS_DEBUG 155fa9e4066Sahrens static void 156fa9e4066Sahrens free_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx) 157fa9e4066Sahrens { 158fa9e4066Sahrens int off, num; 159fa9e4066Sahrens int i, err, epbs; 160fa9e4066Sahrens uint64_t txg = tx->tx_txg; 161744947dcSTom Erickson dnode_t *dn; 162fa9e4066Sahrens 163744947dcSTom Erickson DB_DNODE_ENTER(db); 164744947dcSTom Erickson dn = DB_DNODE(db); 165744947dcSTom Erickson epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; 166fa9e4066Sahrens off = start - (db->db_blkid * 1<<epbs); 167fa9e4066Sahrens num = end - start + 1; 168fa9e4066Sahrens 169fa9e4066Sahrens ASSERT3U(off, >=, 0); 170fa9e4066Sahrens ASSERT3U(num, >=, 0); 171fa9e4066Sahrens ASSERT3U(db->db_level, >, 0); 172744947dcSTom Erickson ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift); 173fa9e4066Sahrens ASSERT3U(off+num, <=, db->db.db_size >> SPA_BLKPTRSHIFT); 174fa9e4066Sahrens ASSERT(db->db_blkptr != NULL); 175fa9e4066Sahrens 176fa9e4066Sahrens for (i = off; i < off+num; i++) { 177fa9e4066Sahrens uint64_t *buf; 178fa9e4066Sahrens dmu_buf_impl_t *child; 179c717a561Smaybee dbuf_dirty_record_t *dr; 180c717a561Smaybee int j; 181fa9e4066Sahrens 182fa9e4066Sahrens ASSERT(db->db_level == 1); 183fa9e4066Sahrens 184744947dcSTom Erickson rw_enter(&dn->dn_struct_rwlock, RW_READER); 185744947dcSTom Erickson err = dbuf_hold_impl(dn, db->db_level-1, 186a2cdcdd2SPaul Dagnelie (db->db_blkid << epbs) + i, TRUE, FALSE, FTAG, &child); 187744947dcSTom Erickson rw_exit(&dn->dn_struct_rwlock); 188fa9e4066Sahrens if (err == ENOENT) 189fa9e4066Sahrens continue; 190fa9e4066Sahrens ASSERT(err == 0); 191fa9e4066Sahrens ASSERT(child->db_level == 0); 192c717a561Smaybee dr = child->db_last_dirty; 193c717a561Smaybee while (dr && dr->dr_txg > txg) 194c717a561Smaybee dr = dr->dr_next; 195c717a561Smaybee ASSERT(dr == NULL || dr->dr_txg == txg); 196c717a561Smaybee 197c717a561Smaybee /* data_old better be zeroed */ 198c717a561Smaybee if (dr) { 199c717a561Smaybee buf = dr->dt.dl.dr_data->b_data; 200fa9e4066Sahrens for (j = 0; j < child->db.db_size >> 3; j++) { 201fa9e4066Sahrens if (buf[j] != 0) { 202fa9e4066Sahrens panic("freed data not zero: " 203fa9e4066Sahrens "child=%p i=%d off=%d num=%d\n", 204903a11ebSrh (void *)child, i, off, num); 205fa9e4066Sahrens } 206fa9e4066Sahrens } 207fa9e4066Sahrens } 208fa9e4066Sahrens 209fa9e4066Sahrens /* 210fa9e4066Sahrens * db_data better be zeroed unless it's dirty in a 211fa9e4066Sahrens * future txg. 212fa9e4066Sahrens */ 213fa9e4066Sahrens mutex_enter(&child->db_mtx); 214fa9e4066Sahrens buf = child->db.db_data; 215fa9e4066Sahrens if (buf != NULL && child->db_state != DB_FILL && 216c717a561Smaybee child->db_last_dirty == NULL) { 217fa9e4066Sahrens for (j = 0; j < child->db.db_size >> 3; j++) { 218fa9e4066Sahrens if (buf[j] != 0) { 219fa9e4066Sahrens panic("freed data not zero: " 220fa9e4066Sahrens "child=%p i=%d off=%d num=%d\n", 221903a11ebSrh (void *)child, i, off, num); 222fa9e4066Sahrens } 223fa9e4066Sahrens } 224fa9e4066Sahrens } 225fa9e4066Sahrens mutex_exit(&child->db_mtx); 226fa9e4066Sahrens 227ea8dc4b6Seschrock dbuf_rele(child, FTAG); 228fa9e4066Sahrens } 229744947dcSTom Erickson DB_DNODE_EXIT(db); 230fa9e4066Sahrens } 2319c9dc39aSek #endif 232fa9e4066Sahrens 233738e2a3cSPaul Dagnelie /* 234738e2a3cSPaul Dagnelie * We don't usually free the indirect blocks here. If in one txg we have a 235738e2a3cSPaul Dagnelie * free_range and a write to the same indirect block, it's important that we 236738e2a3cSPaul Dagnelie * preserve the hole's birth times. Therefore, we don't free any any indirect 237738e2a3cSPaul Dagnelie * blocks in free_children(). If an indirect block happens to turn into all 238738e2a3cSPaul Dagnelie * holes, it will be freed by dbuf_write_children_ready, which happens at a 239738e2a3cSPaul Dagnelie * point in the syncing process where we know for certain the contents of the 240738e2a3cSPaul Dagnelie * indirect block. 241738e2a3cSPaul Dagnelie * 242738e2a3cSPaul Dagnelie * However, if we're freeing a dnode, its space accounting must go to zero 243738e2a3cSPaul Dagnelie * before we actually try to free the dnode, or we will trip an assertion. In 244738e2a3cSPaul Dagnelie * addition, we know the case described above cannot occur, because the dnode is 245738e2a3cSPaul Dagnelie * being freed. Therefore, we free the indirect blocks immediately in that 246738e2a3cSPaul Dagnelie * case. 247738e2a3cSPaul Dagnelie */ 24843466aaeSMax Grossman static void 24943466aaeSMax Grossman free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks, 250738e2a3cSPaul Dagnelie boolean_t free_indirects, dmu_tx_t *tx) 251fa9e4066Sahrens { 252744947dcSTom Erickson dnode_t *dn; 253fa9e4066Sahrens blkptr_t *bp; 254fa9e4066Sahrens dmu_buf_impl_t *subdb; 2551a01181fSGeorge Wilson uint64_t start, end, dbstart, dbend; 2561a01181fSGeorge Wilson unsigned int epbs, shift, i; 257cdb0ab79Smaybee 258cdb0ab79Smaybee /* 259cdb0ab79Smaybee * There is a small possibility that this block will not be cached: 260cdb0ab79Smaybee * 1 - if level > 1 and there are no children with level <= 1 26143466aaeSMax Grossman * 2 - if this block was evicted since we read it from 26243466aaeSMax Grossman * dmu_tx_hold_free(). 263cdb0ab79Smaybee */ 264cdb0ab79Smaybee if (db->db_state != DB_CACHED) 265cdb0ab79Smaybee (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED); 266fa9e4066Sahrens 26799a19144SMatthew Ahrens /* 26899a19144SMatthew Ahrens * If we modify this indirect block, and we are not freeing the 26999a19144SMatthew Ahrens * dnode (!free_indirects), then this indirect block needs to get 27099a19144SMatthew Ahrens * written to disk by dbuf_write(). If it is dirty, we know it will 27199a19144SMatthew Ahrens * be written (otherwise, we would have incorrect on-disk state 27299a19144SMatthew Ahrens * because the space would be freed but still referenced by the BP 27399a19144SMatthew Ahrens * in this indirect block). Therefore we VERIFY that it is 27499a19144SMatthew Ahrens * dirty. 27599a19144SMatthew Ahrens * 27699a19144SMatthew Ahrens * Our VERIFY covers some cases that do not actually have to be 27799a19144SMatthew Ahrens * dirty, but the open-context code happens to dirty. E.g. if the 27899a19144SMatthew Ahrens * blocks we are freeing are all holes, because in that case, we 27999a19144SMatthew Ahrens * are only freeing part of this indirect block, so it is an 28099a19144SMatthew Ahrens * ancestor of the first or last block to be freed. The first and 28199a19144SMatthew Ahrens * last L1 indirect blocks are always dirtied by dnode_free_range(). 28299a19144SMatthew Ahrens */ 28399a19144SMatthew Ahrens VERIFY(BP_GET_FILL(db->db_blkptr) == 0 || db->db_dirtycnt > 0); 28499a19144SMatthew Ahrens 2853f9d6ad7SLin Ling dbuf_release_bp(db); 28643466aaeSMax Grossman bp = db->db.db_data; 287fa9e4066Sahrens 288744947dcSTom Erickson DB_DNODE_ENTER(db); 289744947dcSTom Erickson dn = DB_DNODE(db); 290744947dcSTom Erickson epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT; 2911a01181fSGeorge Wilson ASSERT3U(epbs, <, 31); 292fa9e4066Sahrens shift = (db->db_level - 1) * epbs; 293fa9e4066Sahrens dbstart = db->db_blkid << epbs; 294fa9e4066Sahrens start = blkid >> shift; 295fa9e4066Sahrens if (dbstart < start) { 296fa9e4066Sahrens bp += start - dbstart; 297fa9e4066Sahrens } else { 298fa9e4066Sahrens start = dbstart; 299fa9e4066Sahrens } 300fa9e4066Sahrens dbend = ((db->db_blkid + 1) << epbs) - 1; 301fa9e4066Sahrens end = (blkid + nblks - 1) >> shift; 302fa9e4066Sahrens if (dbend <= end) 303fa9e4066Sahrens end = dbend; 30443466aaeSMax Grossman 305fa9e4066Sahrens ASSERT3U(start, <=, end); 306fa9e4066Sahrens 307fa9e4066Sahrens if (db->db_level == 1) { 3089c9dc39aSek FREE_VERIFY(db, start, end, tx); 30943466aaeSMax Grossman free_blocks(dn, bp, end-start+1, tx); 31043466aaeSMax Grossman } else { 3111a01181fSGeorge Wilson for (uint64_t id = start; id <= end; id++, bp++) { 31243466aaeSMax Grossman if (BP_IS_HOLE(bp)) 31343466aaeSMax Grossman continue; 31443466aaeSMax Grossman rw_enter(&dn->dn_struct_rwlock, RW_READER); 31543466aaeSMax Grossman VERIFY0(dbuf_hold_impl(dn, db->db_level - 1, 3161a01181fSGeorge Wilson id, TRUE, FALSE, FTAG, &subdb)); 31743466aaeSMax Grossman rw_exit(&dn->dn_struct_rwlock); 31843466aaeSMax Grossman ASSERT3P(bp, ==, subdb->db_blkptr); 31943466aaeSMax Grossman 320738e2a3cSPaul Dagnelie free_children(subdb, blkid, nblks, free_indirects, tx); 32143466aaeSMax Grossman dbuf_rele(subdb, FTAG); 32243466aaeSMax Grossman } 323fa9e4066Sahrens } 324fa9e4066Sahrens 325738e2a3cSPaul Dagnelie if (free_indirects) { 326738e2a3cSPaul Dagnelie for (i = 0, bp = db->db.db_data; i < 1 << epbs; i++, bp++) 327738e2a3cSPaul Dagnelie ASSERT(BP_IS_HOLE(bp)); 32843466aaeSMax Grossman bzero(db->db.db_data, db->db.db_size); 32943466aaeSMax Grossman free_blocks(dn, db->db_blkptr, 1, tx); 330fa9e4066Sahrens } 33143466aaeSMax Grossman 332744947dcSTom Erickson DB_DNODE_EXIT(db); 3336b4acc8bSahrens arc_buf_freeze(db->db_buf); 334fa9e4066Sahrens } 335fa9e4066Sahrens 336fa9e4066Sahrens /* 337f7170741SWill Andrews * Traverse the indicated range of the provided file 338fa9e4066Sahrens * and "free" all the blocks contained there. 339fa9e4066Sahrens */ 340fa9e4066Sahrens static void 341bf16b11eSMatthew Ahrens dnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks, 342738e2a3cSPaul Dagnelie boolean_t free_indirects, dmu_tx_t *tx) 343fa9e4066Sahrens { 344fa9e4066Sahrens blkptr_t *bp = dn->dn_phys->dn_blkptr; 345fa9e4066Sahrens int dnlevel = dn->dn_phys->dn_nlevels; 34643466aaeSMax Grossman boolean_t trunc = B_FALSE; 347fa9e4066Sahrens 348fa9e4066Sahrens if (blkid > dn->dn_phys->dn_maxblkid) 349fa9e4066Sahrens return; 350fa9e4066Sahrens 351fa9e4066Sahrens ASSERT(dn->dn_phys->dn_maxblkid < UINT64_MAX); 35243466aaeSMax Grossman if (blkid + nblks > dn->dn_phys->dn_maxblkid) { 353fa9e4066Sahrens nblks = dn->dn_phys->dn_maxblkid - blkid + 1; 35443466aaeSMax Grossman trunc = B_TRUE; 35543466aaeSMax Grossman } 356fa9e4066Sahrens 357fa9e4066Sahrens /* There are no indirect blocks in the object */ 358fa9e4066Sahrens if (dnlevel == 1) { 359fa9e4066Sahrens if (blkid >= dn->dn_phys->dn_nblkptr) { 360fa9e4066Sahrens /* this range was never made persistent */ 361fa9e4066Sahrens return; 362fa9e4066Sahrens } 363fa9e4066Sahrens ASSERT3U(blkid + nblks, <=, dn->dn_phys->dn_nblkptr); 36443466aaeSMax Grossman free_blocks(dn, bp + blkid, nblks, tx); 36543466aaeSMax Grossman } else { 36643466aaeSMax Grossman int shift = (dnlevel - 1) * 36743466aaeSMax Grossman (dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT); 36843466aaeSMax Grossman int start = blkid >> shift; 36943466aaeSMax Grossman int end = (blkid + nblks - 1) >> shift; 37043466aaeSMax Grossman dmu_buf_impl_t *db; 37143466aaeSMax Grossman 37243466aaeSMax Grossman ASSERT(start < dn->dn_phys->dn_nblkptr); 37343466aaeSMax Grossman bp += start; 37443466aaeSMax Grossman for (int i = start; i <= end; i++, bp++) { 37543466aaeSMax Grossman if (BP_IS_HOLE(bp)) 37643466aaeSMax Grossman continue; 37743466aaeSMax Grossman rw_enter(&dn->dn_struct_rwlock, RW_READER); 37843466aaeSMax Grossman VERIFY0(dbuf_hold_impl(dn, dnlevel - 1, i, 379a2cdcdd2SPaul Dagnelie TRUE, FALSE, FTAG, &db)); 38043466aaeSMax Grossman rw_exit(&dn->dn_struct_rwlock); 38143466aaeSMax Grossman 382738e2a3cSPaul Dagnelie free_children(db, blkid, nblks, free_indirects, tx); 38343466aaeSMax Grossman dbuf_rele(db, FTAG); 384fa9e4066Sahrens } 385fa9e4066Sahrens } 38643466aaeSMax Grossman 387*eb633035STom Caputi /* 388*eb633035STom Caputi * Do not truncate the maxblkid if we are performing a raw 389*eb633035STom Caputi * receive. The raw receive sets the maxblkid manually and 390*eb633035STom Caputi * must not be overridden. Usually, the last DRR_FREE record 391*eb633035STom Caputi * will be at the maxblkid, because the source system sets 392*eb633035STom Caputi * the maxblkid when truncating. However, if the last block 393*eb633035STom Caputi * was freed by overwriting with zeros and being compressed 394*eb633035STom Caputi * away to a hole, the source system will generate a DRR_FREE 395*eb633035STom Caputi * record while leaving the maxblkid after the end of that 396*eb633035STom Caputi * record. In this case we need to leave the maxblkid as 397*eb633035STom Caputi * indicated in the DRR_OBJECT record, so that it matches the 398*eb633035STom Caputi * source system, ensuring that the cryptographic hashes will 399*eb633035STom Caputi * match. 400*eb633035STom Caputi */ 401*eb633035STom Caputi if (trunc && !dn->dn_objset->os_raw_receive) { 40243466aaeSMax Grossman dn->dn_phys->dn_maxblkid = blkid == 0 ? 0 : blkid - 1; 40343466aaeSMax Grossman 404fa9e4066Sahrens uint64_t off = (dn->dn_phys->dn_maxblkid + 1) * 405fa9e4066Sahrens (dn->dn_phys->dn_datablkszsec << SPA_MINBLOCKSHIFT); 406fa9e4066Sahrens ASSERT(off < dn->dn_phys->dn_maxblkid || 407fa9e4066Sahrens dn->dn_phys->dn_maxblkid == 0 || 408cdb0ab79Smaybee dnode_next_offset(dn, 0, &off, 1, 1, 0) != 0); 409fa9e4066Sahrens } 410fa9e4066Sahrens } 411fa9e4066Sahrens 412bf16b11eSMatthew Ahrens typedef struct dnode_sync_free_range_arg { 413bf16b11eSMatthew Ahrens dnode_t *dsfra_dnode; 414bf16b11eSMatthew Ahrens dmu_tx_t *dsfra_tx; 415738e2a3cSPaul Dagnelie boolean_t dsfra_free_indirects; 416bf16b11eSMatthew Ahrens } dnode_sync_free_range_arg_t; 417bf16b11eSMatthew Ahrens 418bf16b11eSMatthew Ahrens static void 419bf16b11eSMatthew Ahrens dnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks) 420bf16b11eSMatthew Ahrens { 421bf16b11eSMatthew Ahrens dnode_sync_free_range_arg_t *dsfra = arg; 422bf16b11eSMatthew Ahrens dnode_t *dn = dsfra->dsfra_dnode; 423bf16b11eSMatthew Ahrens 424bf16b11eSMatthew Ahrens mutex_exit(&dn->dn_mtx); 425738e2a3cSPaul Dagnelie dnode_sync_free_range_impl(dn, blkid, nblks, 426738e2a3cSPaul Dagnelie dsfra->dsfra_free_indirects, dsfra->dsfra_tx); 427bf16b11eSMatthew Ahrens mutex_enter(&dn->dn_mtx); 428bf16b11eSMatthew Ahrens } 429bf16b11eSMatthew Ahrens 430ea8dc4b6Seschrock /* 431f7170741SWill Andrews * Try to kick all the dnode's dbufs out of the cache... 432ea8dc4b6Seschrock */ 4331934e92fSmaybee void 4341934e92fSmaybee dnode_evict_dbufs(dnode_t *dn) 435ea8dc4b6Seschrock { 436bc9014e6SJustin Gibbs dmu_buf_impl_t db_marker; 437bc9014e6SJustin Gibbs dmu_buf_impl_t *db, *db_next; 438c543ec06Sahrens 439bc9014e6SJustin Gibbs mutex_enter(&dn->dn_dbufs_mtx); 440bc9014e6SJustin Gibbs for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) { 441c543ec06Sahrens 442744947dcSTom Erickson #ifdef DEBUG 443bc9014e6SJustin Gibbs DB_DNODE_ENTER(db); 444bc9014e6SJustin Gibbs ASSERT3P(DB_DNODE(db), ==, dn); 445bc9014e6SJustin Gibbs DB_DNODE_EXIT(db); 446744947dcSTom Erickson #endif /* DEBUG */ 447ea8dc4b6Seschrock 448bc9014e6SJustin Gibbs mutex_enter(&db->db_mtx); 449bc9014e6SJustin Gibbs if (db->db_state != DB_EVICTING && 450e914ace2STim Schumacher zfs_refcount_is_zero(&db->db_holds)) { 451bc9014e6SJustin Gibbs db_marker.db_level = db->db_level; 452bc9014e6SJustin Gibbs db_marker.db_blkid = db->db_blkid; 453bc9014e6SJustin Gibbs db_marker.db_state = DB_SEARCH; 454bc9014e6SJustin Gibbs avl_insert_here(&dn->dn_dbufs, &db_marker, db, 455bc9014e6SJustin Gibbs AVL_BEFORE); 456bc9014e6SJustin Gibbs 457c2919acbSMatthew Ahrens /* 458c2919acbSMatthew Ahrens * We need to use the "marker" dbuf rather than 459c2919acbSMatthew Ahrens * simply getting the next dbuf, because 460c2919acbSMatthew Ahrens * dbuf_destroy() may actually remove multiple dbufs. 461c2919acbSMatthew Ahrens * It can call itself recursively on the parent dbuf, 462c2919acbSMatthew Ahrens * which may also be removed from dn_dbufs. The code 463c2919acbSMatthew Ahrens * flow would look like: 464c2919acbSMatthew Ahrens * 465c2919acbSMatthew Ahrens * dbuf_destroy(): 466c2919acbSMatthew Ahrens * dnode_rele_and_unlock(parent_dbuf, evicting=TRUE): 467c2919acbSMatthew Ahrens * if (!cacheable || pending_evict) 468c2919acbSMatthew Ahrens * dbuf_destroy() 469c2919acbSMatthew Ahrens */ 470dcbf3bd6SGeorge Wilson dbuf_destroy(db); 471bc9014e6SJustin Gibbs 472bc9014e6SJustin Gibbs db_next = AVL_NEXT(&dn->dn_dbufs, &db_marker); 473bc9014e6SJustin Gibbs avl_remove(&dn->dn_dbufs, &db_marker); 474bc9014e6SJustin Gibbs } else { 475d2058105SJustin T. Gibbs db->db_pending_evict = TRUE; 476bc9014e6SJustin Gibbs mutex_exit(&db->db_mtx); 477bc9014e6SJustin Gibbs db_next = AVL_NEXT(&dn->dn_dbufs, db); 478ea8dc4b6Seschrock } 479bc9014e6SJustin Gibbs } 480bc9014e6SJustin Gibbs mutex_exit(&dn->dn_dbufs_mtx); 481c543ec06Sahrens 482cd485b49SJustin T. Gibbs dnode_evict_bonus(dn); 483cd485b49SJustin T. Gibbs } 484cd485b49SJustin T. Gibbs 485cd485b49SJustin T. Gibbs void 486cd485b49SJustin T. Gibbs dnode_evict_bonus(dnode_t *dn) 487cd485b49SJustin T. Gibbs { 488ea8dc4b6Seschrock rw_enter(&dn->dn_struct_rwlock, RW_WRITER); 489d2058105SJustin T. Gibbs if (dn->dn_bonus != NULL) { 490e914ace2STim Schumacher if (zfs_refcount_is_zero(&dn->dn_bonus->db_holds)) { 491d2058105SJustin T. Gibbs mutex_enter(&dn->dn_bonus->db_mtx); 492dcbf3bd6SGeorge Wilson dbuf_destroy(dn->dn_bonus); 493d2058105SJustin T. Gibbs dn->dn_bonus = NULL; 494d2058105SJustin T. Gibbs } else { 495d2058105SJustin T. Gibbs dn->dn_bonus->db_pending_evict = TRUE; 496d2058105SJustin T. Gibbs } 497ea8dc4b6Seschrock } 498ea8dc4b6Seschrock rw_exit(&dn->dn_struct_rwlock); 499ea8dc4b6Seschrock } 500ea8dc4b6Seschrock 501c717a561Smaybee static void 502c717a561Smaybee dnode_undirty_dbufs(list_t *list) 503fa9e4066Sahrens { 504c717a561Smaybee dbuf_dirty_record_t *dr; 505fa9e4066Sahrens 506c717a561Smaybee while (dr = list_head(list)) { 507c717a561Smaybee dmu_buf_impl_t *db = dr->dr_dbuf; 508c717a561Smaybee uint64_t txg = dr->dr_txg; 509fa9e4066Sahrens 510b24ab676SJeff Bonwick if (db->db_level != 0) 511b24ab676SJeff Bonwick dnode_undirty_dbufs(&dr->dt.di.dr_children); 512b24ab676SJeff Bonwick 513fa9e4066Sahrens mutex_enter(&db->db_mtx); 514fa9e4066Sahrens /* XXX - use dbuf_undirty()? */ 515c717a561Smaybee list_remove(list, dr); 516c717a561Smaybee ASSERT(db->db_last_dirty == dr); 517c717a561Smaybee db->db_last_dirty = NULL; 518c717a561Smaybee db->db_dirtycnt -= 1; 519fa9e4066Sahrens if (db->db_level == 0) { 5200a586ceaSMark Shellenbaum ASSERT(db->db_blkid == DMU_BONUS_BLKID || 521c717a561Smaybee dr->dt.dl.dr_data == db->db_buf); 522c717a561Smaybee dbuf_unoverride(dr); 523d2b3cbbdSJorgen Lundman } else { 524d2b3cbbdSJorgen Lundman mutex_destroy(&dr->dt.di.dr_mtx); 525d2b3cbbdSJorgen Lundman list_destroy(&dr->dt.di.dr_children); 526fa9e4066Sahrens } 527c717a561Smaybee kmem_free(dr, sizeof (dbuf_dirty_record_t)); 528c2919acbSMatthew Ahrens dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg, B_FALSE); 529fa9e4066Sahrens } 530c717a561Smaybee } 531fa9e4066Sahrens 532c717a561Smaybee static void 533c717a561Smaybee dnode_sync_free(dnode_t *dn, dmu_tx_t *tx) 534c717a561Smaybee { 535c717a561Smaybee int txgoff = tx->tx_txg & TXG_MASK; 536c717a561Smaybee 537c717a561Smaybee ASSERT(dmu_tx_is_syncing(tx)); 538c717a561Smaybee 539cdb0ab79Smaybee /* 540cdb0ab79Smaybee * Our contents should have been freed in dnode_sync() by the 541cdb0ab79Smaybee * free range record inserted by the caller of dnode_free(). 542cdb0ab79Smaybee */ 543fb09f5aaSMadhav Suresh ASSERT0(DN_USED_BYTES(dn->dn_phys)); 544cdb0ab79Smaybee ASSERT(BP_IS_HOLE(dn->dn_phys->dn_blkptr)); 545cdb0ab79Smaybee 546c717a561Smaybee dnode_undirty_dbufs(&dn->dn_dirty_records[txgoff]); 5471934e92fSmaybee dnode_evict_dbufs(dn); 548ea8dc4b6Seschrock 549ea8dc4b6Seschrock /* 550ea8dc4b6Seschrock * XXX - It would be nice to assert this, but we may still 551ea8dc4b6Seschrock * have residual holds from async evictions from the arc... 552ea8dc4b6Seschrock * 55355434c77Sek * zfs_obj_to_path() also depends on this being 55455434c77Sek * commented out. 55555434c77Sek * 556e914ace2STim Schumacher * ASSERT3U(zfs_refcount_count(&dn->dn_holds), ==, 1); 557ea8dc4b6Seschrock */ 558fa9e4066Sahrens 559fa9e4066Sahrens /* Undirty next bits */ 560fa9e4066Sahrens dn->dn_next_nlevels[txgoff] = 0; 561fa9e4066Sahrens dn->dn_next_indblkshift[txgoff] = 0; 562c543ec06Sahrens dn->dn_next_blksz[txgoff] = 0; 563*eb633035STom Caputi dn->dn_next_maxblkid[txgoff] = 0; 564fa9e4066Sahrens 565fa9e4066Sahrens /* ASSERT(blkptrs are zero); */ 566fa9e4066Sahrens ASSERT(dn->dn_phys->dn_type != DMU_OT_NONE); 567fa9e4066Sahrens ASSERT(dn->dn_type != DMU_OT_NONE); 568fa9e4066Sahrens 569fa9e4066Sahrens ASSERT(dn->dn_free_txg > 0); 570fa9e4066Sahrens if (dn->dn_allocated_txg != dn->dn_free_txg) 57143466aaeSMax Grossman dmu_buf_will_dirty(&dn->dn_dbuf->db, tx); 57254811da5SToomas Soome bzero(dn->dn_phys, sizeof (dnode_phys_t) * dn->dn_num_slots); 57354811da5SToomas Soome dnode_free_interior_slots(dn); 574fa9e4066Sahrens 575fa9e4066Sahrens mutex_enter(&dn->dn_mtx); 576fa9e4066Sahrens dn->dn_type = DMU_OT_NONE; 577fa9e4066Sahrens dn->dn_maxblkid = 0; 578fa9e4066Sahrens dn->dn_allocated_txg = 0; 579758f6e0bSgw dn->dn_free_txg = 0; 5800a586ceaSMark Shellenbaum dn->dn_have_spill = B_FALSE; 58154811da5SToomas Soome dn->dn_num_slots = 1; 582fa9e4066Sahrens mutex_exit(&dn->dn_mtx); 583fa9e4066Sahrens 584ea8dc4b6Seschrock ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT); 585fa9e4066Sahrens 586fa9e4066Sahrens dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg); 587fa9e4066Sahrens /* 588fa9e4066Sahrens * Now that we've released our hold, the dnode may 589*eb633035STom Caputi * be evicted, so we mustn't access it. 590fa9e4066Sahrens */ 591fa9e4066Sahrens } 592fa9e4066Sahrens 593fa9e4066Sahrens /* 594c717a561Smaybee * Write out the dnode's dirty buffers. 595fa9e4066Sahrens */ 596c717a561Smaybee void 597c717a561Smaybee dnode_sync(dnode_t *dn, dmu_tx_t *tx) 598fa9e4066Sahrens { 599*eb633035STom Caputi objset_t *os = dn->dn_objset; 600fa9e4066Sahrens dnode_phys_t *dnp = dn->dn_phys; 601c717a561Smaybee int txgoff = tx->tx_txg & TXG_MASK; 602c717a561Smaybee list_t *list = &dn->dn_dirty_records[txgoff]; 60314843421SMatthew Ahrens static const dnode_phys_t zerodn = { 0 }; 6040a586ceaSMark Shellenbaum boolean_t kill_spill = B_FALSE; 605fa9e4066Sahrens 606fa9e4066Sahrens ASSERT(dmu_tx_is_syncing(tx)); 607fa9e4066Sahrens ASSERT(dnp->dn_type != DMU_OT_NONE || dn->dn_allocated_txg); 60814843421SMatthew Ahrens ASSERT(dnp->dn_type != DMU_OT_NONE || 60954811da5SToomas Soome bcmp(dnp, &zerodn, DNODE_MIN_SIZE) == 0); 6109c9dc39aSek DNODE_VERIFY(dn); 611c543ec06Sahrens 612c717a561Smaybee ASSERT(dn->dn_dbuf == NULL || arc_released(dn->dn_dbuf->db_buf)); 613fa9e4066Sahrens 614*eb633035STom Caputi /* 615*eb633035STom Caputi * Do user accounting if it is enabled and this is not 616*eb633035STom Caputi * an encrypted receive. 617*eb633035STom Caputi */ 618*eb633035STom Caputi if (dmu_objset_userused_enabled(os) && 619*eb633035STom Caputi !DMU_OBJECT_IS_SPECIAL(dn->dn_object) && 620*eb633035STom Caputi (!os->os_encrypted || !dmu_objset_is_receiving(os))) { 6210a586ceaSMark Shellenbaum mutex_enter(&dn->dn_mtx); 6220a586ceaSMark Shellenbaum dn->dn_oldused = DN_USED_BYTES(dn->dn_phys); 6230a586ceaSMark Shellenbaum dn->dn_oldflags = dn->dn_phys->dn_flags; 62414843421SMatthew Ahrens dn->dn_phys->dn_flags |= DNODE_FLAG_USERUSED_ACCOUNTED; 6250a586ceaSMark Shellenbaum mutex_exit(&dn->dn_mtx); 62606e0070dSMark Shellenbaum dmu_objset_userquota_get_ids(dn, B_FALSE, tx); 62714843421SMatthew Ahrens } else { 628*eb633035STom Caputi /* Once we account for it, we should always account for it */ 62914843421SMatthew Ahrens ASSERT(!(dn->dn_phys->dn_flags & 63014843421SMatthew Ahrens DNODE_FLAG_USERUSED_ACCOUNTED)); 63114843421SMatthew Ahrens } 63214843421SMatthew Ahrens 633fa9e4066Sahrens mutex_enter(&dn->dn_mtx); 634fa9e4066Sahrens if (dn->dn_allocated_txg == tx->tx_txg) { 635fa9e4066Sahrens /* The dnode is newly allocated or reallocated */ 636fa9e4066Sahrens if (dnp->dn_type == DMU_OT_NONE) { 637fa9e4066Sahrens /* this is a first alloc, not a realloc */ 638fa9e4066Sahrens dnp->dn_nlevels = 1; 639da03de99SMark Maybee dnp->dn_nblkptr = dn->dn_nblkptr; 640fa9e4066Sahrens } 641fa9e4066Sahrens 642fa9e4066Sahrens dnp->dn_type = dn->dn_type; 643fa9e4066Sahrens dnp->dn_bonustype = dn->dn_bonustype; 644fa9e4066Sahrens dnp->dn_bonuslen = dn->dn_bonuslen; 645fa9e4066Sahrens } 64654811da5SToomas Soome 64754811da5SToomas Soome dnp->dn_extra_slots = dn->dn_num_slots - 1; 64854811da5SToomas Soome 649c717a561Smaybee ASSERT(dnp->dn_nlevels > 1 || 650f676ed34Sahrens BP_IS_HOLE(&dnp->dn_blkptr[0]) || 6515d7b4d43SMatthew Ahrens BP_IS_EMBEDDED(&dnp->dn_blkptr[0]) || 652f676ed34Sahrens BP_GET_LSIZE(&dnp->dn_blkptr[0]) == 653f676ed34Sahrens dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT); 6545d7b4d43SMatthew Ahrens ASSERT(dnp->dn_nlevels < 2 || 6555d7b4d43SMatthew Ahrens BP_IS_HOLE(&dnp->dn_blkptr[0]) || 6565d7b4d43SMatthew Ahrens BP_GET_LSIZE(&dnp->dn_blkptr[0]) == 1 << dnp->dn_indblkshift); 657f676ed34Sahrens 6582acef22dSMatthew Ahrens if (dn->dn_next_type[txgoff] != 0) { 6592acef22dSMatthew Ahrens dnp->dn_type = dn->dn_type; 6602acef22dSMatthew Ahrens dn->dn_next_type[txgoff] = 0; 6612acef22dSMatthew Ahrens } 6622acef22dSMatthew Ahrens 6632acef22dSMatthew Ahrens if (dn->dn_next_blksz[txgoff] != 0) { 664c543ec06Sahrens ASSERT(P2PHASE(dn->dn_next_blksz[txgoff], 665fa9e4066Sahrens SPA_MINBLOCKSIZE) == 0); 666f676ed34Sahrens ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) || 667cdb0ab79Smaybee dn->dn_maxblkid == 0 || list_head(list) != NULL || 668347a31bcSahrens dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT == 669bf16b11eSMatthew Ahrens dnp->dn_datablkszsec || 67086714001SSerapheim Dimitropoulos !range_tree_is_empty(dn->dn_free_ranges[txgoff])); 671fa9e4066Sahrens dnp->dn_datablkszsec = 672c543ec06Sahrens dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT; 673c543ec06Sahrens dn->dn_next_blksz[txgoff] = 0; 674fa9e4066Sahrens } 675fa9e4066Sahrens 6762acef22dSMatthew Ahrens if (dn->dn_next_bonuslen[txgoff] != 0) { 6771934e92fSmaybee if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN) 6781934e92fSmaybee dnp->dn_bonuslen = 0; 6791934e92fSmaybee else 6801934e92fSmaybee dnp->dn_bonuslen = dn->dn_next_bonuslen[txgoff]; 68154811da5SToomas Soome ASSERT(dnp->dn_bonuslen <= 68254811da5SToomas Soome DN_SLOTS_TO_BONUSLEN(dnp->dn_extra_slots + 1)); 6831934e92fSmaybee dn->dn_next_bonuslen[txgoff] = 0; 6841934e92fSmaybee } 6851934e92fSmaybee 6862acef22dSMatthew Ahrens if (dn->dn_next_bonustype[txgoff] != 0) { 687ad135b5dSChristopher Siden ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff])); 6880a586ceaSMark Shellenbaum dnp->dn_bonustype = dn->dn_next_bonustype[txgoff]; 6890a586ceaSMark Shellenbaum dn->dn_next_bonustype[txgoff] = 0; 6900a586ceaSMark Shellenbaum } 6910a586ceaSMark Shellenbaum 69243466aaeSMax Grossman boolean_t freeing_dnode = dn->dn_free_txg > 0 && 69343466aaeSMax Grossman dn->dn_free_txg <= tx->tx_txg; 69443466aaeSMax Grossman 6950a586ceaSMark Shellenbaum /* 696e6518318SMatthew Ahrens * Remove the spill block if we have been explicitly asked to 697e6518318SMatthew Ahrens * remove it, or if the object is being removed. 6980a586ceaSMark Shellenbaum */ 699e6518318SMatthew Ahrens if (dn->dn_rm_spillblk[txgoff] || freeing_dnode) { 700e6518318SMatthew Ahrens if (dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) 7010a586ceaSMark Shellenbaum kill_spill = B_TRUE; 7020a586ceaSMark Shellenbaum dn->dn_rm_spillblk[txgoff] = 0; 7030a586ceaSMark Shellenbaum } 7040a586ceaSMark Shellenbaum 7052acef22dSMatthew Ahrens if (dn->dn_next_indblkshift[txgoff] != 0) { 706fa9e4066Sahrens ASSERT(dnp->dn_nlevels == 1); 707fa9e4066Sahrens dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff]; 708fa9e4066Sahrens dn->dn_next_indblkshift[txgoff] = 0; 709fa9e4066Sahrens } 710fa9e4066Sahrens 711fa9e4066Sahrens /* 712fa9e4066Sahrens * Just take the live (open-context) values for checksum and compress. 713fa9e4066Sahrens * Strictly speaking it's a future leak, but nothing bad happens if we 714fa9e4066Sahrens * start using the new checksum or compress algorithm a little early. 715fa9e4066Sahrens */ 716fa9e4066Sahrens dnp->dn_checksum = dn->dn_checksum; 717fa9e4066Sahrens dnp->dn_compress = dn->dn_compress; 718fa9e4066Sahrens 719fa9e4066Sahrens mutex_exit(&dn->dn_mtx); 720fa9e4066Sahrens 7210a586ceaSMark Shellenbaum if (kill_spill) { 72254811da5SToomas Soome free_blocks(dn, DN_SPILL_BLKPTR(dn->dn_phys), 1, tx); 7230a586ceaSMark Shellenbaum mutex_enter(&dn->dn_mtx); 7240a586ceaSMark Shellenbaum dnp->dn_flags &= ~DNODE_FLAG_SPILL_BLKPTR; 7250a586ceaSMark Shellenbaum mutex_exit(&dn->dn_mtx); 7260a586ceaSMark Shellenbaum } 7270a586ceaSMark Shellenbaum 728fa9e4066Sahrens /* process all the "freed" ranges in the file */ 729bf16b11eSMatthew Ahrens if (dn->dn_free_ranges[txgoff] != NULL) { 730bf16b11eSMatthew Ahrens dnode_sync_free_range_arg_t dsfra; 731bf16b11eSMatthew Ahrens dsfra.dsfra_dnode = dn; 732bf16b11eSMatthew Ahrens dsfra.dsfra_tx = tx; 733738e2a3cSPaul Dagnelie dsfra.dsfra_free_indirects = freeing_dnode; 734738e2a3cSPaul Dagnelie if (freeing_dnode) { 735738e2a3cSPaul Dagnelie ASSERT(range_tree_contains(dn->dn_free_ranges[txgoff], 736738e2a3cSPaul Dagnelie 0, dn->dn_maxblkid + 1)); 737738e2a3cSPaul Dagnelie } 738cdb0ab79Smaybee mutex_enter(&dn->dn_mtx); 739bf16b11eSMatthew Ahrens range_tree_vacate(dn->dn_free_ranges[txgoff], 740bf16b11eSMatthew Ahrens dnode_sync_free_range, &dsfra); 741bf16b11eSMatthew Ahrens range_tree_destroy(dn->dn_free_ranges[txgoff]); 742bf16b11eSMatthew Ahrens dn->dn_free_ranges[txgoff] = NULL; 743cdb0ab79Smaybee mutex_exit(&dn->dn_mtx); 744fa9e4066Sahrens } 7451934e92fSmaybee 74643466aaeSMax Grossman if (freeing_dnode) { 747af346df5SNed Bass dn->dn_objset->os_freed_dnodes++; 748c717a561Smaybee dnode_sync_free(dn, tx); 749c717a561Smaybee return; 750fa9e4066Sahrens } 751fa9e4066Sahrens 75254811da5SToomas Soome if (dn->dn_num_slots > DNODE_MIN_SLOTS) { 75354811da5SToomas Soome dsl_dataset_t *ds = dn->dn_objset->os_dsl_dataset; 75454811da5SToomas Soome mutex_enter(&ds->ds_lock); 75554811da5SToomas Soome ds->ds_feature_activation_needed[SPA_FEATURE_LARGE_DNODE] = 75654811da5SToomas Soome B_TRUE; 75754811da5SToomas Soome mutex_exit(&ds->ds_lock); 75854811da5SToomas Soome } 75954811da5SToomas Soome 760e503a685SGeorge Wilson if (dn->dn_next_nlevels[txgoff]) { 761e503a685SGeorge Wilson dnode_increase_indirection(dn, tx); 762e503a685SGeorge Wilson dn->dn_next_nlevels[txgoff] = 0; 763e503a685SGeorge Wilson } 764e503a685SGeorge Wilson 765*eb633035STom Caputi /* 766*eb633035STom Caputi * This must be done after dnode_sync_free_range() 767*eb633035STom Caputi * and dnode_increase_indirection(). See dnode_new_blkid() 768*eb633035STom Caputi * for an explanation of the high bit being set. 769*eb633035STom Caputi */ 770*eb633035STom Caputi if (dn->dn_next_maxblkid[txgoff]) { 771*eb633035STom Caputi mutex_enter(&dn->dn_mtx); 772*eb633035STom Caputi dnp->dn_maxblkid = 773*eb633035STom Caputi dn->dn_next_maxblkid[txgoff] & ~DMU_NEXT_MAXBLKID_SET; 774*eb633035STom Caputi dn->dn_next_maxblkid[txgoff] = 0; 775*eb633035STom Caputi mutex_exit(&dn->dn_mtx); 776*eb633035STom Caputi } 777*eb633035STom Caputi 778da03de99SMark Maybee if (dn->dn_next_nblkptr[txgoff]) { 779da03de99SMark Maybee /* this should only happen on a realloc */ 780da03de99SMark Maybee ASSERT(dn->dn_allocated_txg == tx->tx_txg); 781da03de99SMark Maybee if (dn->dn_next_nblkptr[txgoff] > dnp->dn_nblkptr) { 782da03de99SMark Maybee /* zero the new blkptrs we are gaining */ 783da03de99SMark Maybee bzero(dnp->dn_blkptr + dnp->dn_nblkptr, 784da03de99SMark Maybee sizeof (blkptr_t) * 785da03de99SMark Maybee (dn->dn_next_nblkptr[txgoff] - dnp->dn_nblkptr)); 786da03de99SMark Maybee #ifdef ZFS_DEBUG 787da03de99SMark Maybee } else { 788da03de99SMark Maybee int i; 789da03de99SMark Maybee ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr); 790da03de99SMark Maybee /* the blkptrs we are losing better be unallocated */ 791da03de99SMark Maybee for (i = dn->dn_next_nblkptr[txgoff]; 792da03de99SMark Maybee i < dnp->dn_nblkptr; i++) 793da03de99SMark Maybee ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i])); 794da03de99SMark Maybee #endif 795da03de99SMark Maybee } 796da03de99SMark Maybee mutex_enter(&dn->dn_mtx); 797da03de99SMark Maybee dnp->dn_nblkptr = dn->dn_next_nblkptr[txgoff]; 798da03de99SMark Maybee dn->dn_next_nblkptr[txgoff] = 0; 799da03de99SMark Maybee mutex_exit(&dn->dn_mtx); 800da03de99SMark Maybee } 801da03de99SMark Maybee 80246e1baa6SMatthew Ahrens dbuf_sync_list(list, dn->dn_phys->dn_nlevels - 1, tx); 803fa9e4066Sahrens 80414843421SMatthew Ahrens if (!DMU_OBJECT_IS_SPECIAL(dn->dn_object)) { 805c717a561Smaybee ASSERT3P(list_head(list), ==, NULL); 806c717a561Smaybee dnode_rele(dn, (void *)(uintptr_t)tx->tx_txg); 807fa9e4066Sahrens } 808c717a561Smaybee 809c717a561Smaybee /* 810c717a561Smaybee * Although we have dropped our reference to the dnode, it 811c717a561Smaybee * can't be evicted until its written, and we haven't yet 812c717a561Smaybee * initiated the IO for the dnode's dbuf. 813c717a561Smaybee */ 814fa9e4066Sahrens } 815