fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
8df0bcf0df7622a075cc6e52f659d2fcfdd08cdcPaul Dagnelie * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee /* this dnode can't be paged out because it's dirty */
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee ASSERT(new_level > 1 && dn->dn_phys->dn_nlevels > 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens db = dbuf_hold_level(dn, dn->dn_phys->dn_nlevels, 0, FTAG);
f82bfe17f53efa8e4aca04a764d0352539201fb5gw dprintf("os=%p obj=%llu, increase to %d\n", dn->dn_objset,
8df0bcf0df7622a075cc6e52f659d2fcfdd08cdcPaul Dagnelie /* transfer dnode's block pointers to new indirect block */
8df0bcf0df7622a075cc6e52f659d2fcfdd08cdcPaul Dagnelie (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED|DB_RF_HAVESTRUCT);
8df0bcf0df7622a075cc6e52f659d2fcfdd08cdcPaul Dagnelie ASSERT3U(sizeof (blkptr_t) * nblkptr, <=, db->db.db_size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* set dbuf's parent pointers to new indirect buf */
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee for (i = 0; i < nblkptr; i++) {
e57a022b8f718889ffa92adbde47a8f08abcdb25Justin T. Gibbs dbuf_find(dn->dn_objset, dn->dn_object, old_toplvl, i);
744947dc83c634d985ed3ad79ac9c5e28d1865fdTom Erickson#endif /* DEBUG */
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee if (child->db_parent && child->db_parent != dn->dn_dbuf) {
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee bzero(dn->dn_phys->dn_blkptr, sizeof (blkptr_t) * nblkptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrensfree_blocks(dnode_t *dn, blkptr_t *bp, int num, dmu_tx_t *tx)
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee dprintf("ds=%p obj=%llx num=%d\n", ds, dn->dn_object, num);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bytesfreed += dsl_dataset_block_kill(ds, bp, tx, B_FALSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock ASSERT3U(bytesfreed, <=, DN_USED_BYTES(dn->dn_phys));
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * Save some useful information on the holes being
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * punched, including logical size, type, and indirection
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * level. Retaining birth time enables detection of when
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * holes are punched for reducing the number of free
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * records transmitted during a zfs send.
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman if (spa_feature_is_active(dn->dn_objset->os_spa,
fa9e4066f08beec538e775443c5be79dd423fcabahrensfree_verify(dmu_buf_impl_t *db, uint64_t start, uint64_t end, dmu_tx_t *tx)
744947dc83c634d985ed3ad79ac9c5e28d1865fdTom Erickson epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
744947dc83c634d985ed3ad79ac9c5e28d1865fdTom Erickson ASSERT3U(db->db.db_size, ==, 1 << dn->dn_phys->dn_indblkshift);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT3U(off+num, <=, db->db.db_size >> SPA_BLKPTRSHIFT);
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie (db->db_blkid << epbs) + i, TRUE, FALSE, FTAG, &child);
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee /* data_old better be zeroed */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (buf[j] != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens "child=%p i=%d off=%d num=%d\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens * db_data better be zeroed unless it's dirty in a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * future txg.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (buf[j] != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens "child=%p i=%d off=%d num=%d\n",
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossmanfree_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee * There is a small possibility that this block will not be cached:
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee * 1 - if level > 1 and there are no children with level <= 1
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * 2 - if this block was evicted since we read it from
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * dmu_tx_hold_free().
744947dc83c634d985ed3ad79ac9c5e28d1865fdTom Erickson epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
1a01181fdc809f40c64d5c6881ae3e4521a9d9c7George Wilson for (uint64_t id = start; id <= end; id++, bp++) {
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman /* If this whole block is free, free ourself too. */
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman for (i = 0, bp = db->db.db_data; i < 1 << epbs; i++, bp++) {
1a01181fdc809f40c64d5c6881ae3e4521a9d9c7George Wilson * We only found holes. Grab the rwlock to prevent
1a01181fdc809f40c64d5c6881ae3e4521a9d9c7George Wilson * anybody from reading the blocks we're about to
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * Partial block free; must be marked dirty so that it
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman * will be written out.
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Traverse the indicated range of the provided file
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and "free" all the blocks contained there.
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrensdnode_sync_free_range_impl(dnode_t *dn, uint64_t blkid, uint64_t nblks,
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman if (blkid + nblks > dn->dn_phys->dn_maxblkid) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* There are no indirect blocks in the object */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* this range was never made persistent */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT3U(blkid + nblks, <=, dn->dn_phys->dn_nblkptr);
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman (dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT);
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman dn->dn_phys->dn_maxblkid = blkid == 0 ? 0 : blkid - 1;
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrensdnode_sync_free_range(void *arg, uint64_t blkid, uint64_t nblks)
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrens dnode_sync_free_range_impl(dn, blkid, nblks, dsfra->dsfra_tx);
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Try to kick all the dnode's dbufs out of the cache...
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs for (db = avl_first(&dn->dn_dbufs); db != NULL; db = db_next) {
744947dc83c634d985ed3ad79ac9c5e28d1865fdTom Erickson#endif /* DEBUG */
d2058105c61ec61df3a2dd3f839fed8c3fe7bfd6Justin T. Gibbs if (refcount_is_zero(&dn->dn_bonus->db_holds)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXX - use dbuf_undirty()? */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee * Our contents should have been freed in dnode_sync() by the
cdb0ab79ea1af7b8fc339a04d4bf7426dc77ec4emaybee * free range record inserted by the caller of dnode_free().
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * XXX - It would be nice to assert this, but we may still
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * have residual holds from async evictions from the arc...
55434c770c89aa1b84474f2559a106803511aba0ek * zfs_obj_to_path() also depends on this being
55434c770c89aa1b84474f2559a106803511aba0ek * commented out.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * ASSERT3U(refcount_count(&dn->dn_holds), ==, 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Undirty next bits */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* ASSERT(blkptrs are zero); */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Now that we've released our hold, the dnode may
fa9e4066f08beec538e775443c5be79dd423fcabahrens * be evicted, so we musn't access it.
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee * Write out the dnode's dirty buffers.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(dnp->dn_type != DMU_OT_NONE || dn->dn_allocated_txg);
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee ASSERT(dn->dn_dbuf == NULL || arc_released(dn->dn_dbuf->db_buf));
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (dmu_objset_userused_enabled(dn->dn_objset) &&
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum dn->dn_oldused = DN_USED_BYTES(dn->dn_phys);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens dn->dn_phys->dn_flags |= DNODE_FLAG_USERUSED_ACCOUNTED;
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum dmu_objset_userquota_get_ids(dn, B_FALSE, tx);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens /* Once we account for it, we should always account for it. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* The dnode is newly allocated or reallocated */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* this is a first alloc, not a realloc */
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BP_GET_LSIZE(&dnp->dn_blkptr[0]) == 1 << dnp->dn_indblkshift);
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrens range_tree_space(dn->dn_free_ranges[txgoff]) != 0);
1934e92fc930c49429ad71a8ca97340f33227e78maybee if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff]));
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum dnp->dn_bonustype = dn->dn_next_bonustype[txgoff];
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman boolean_t freeing_dnode = dn->dn_free_txg > 0 &&
e6518318428d2be1962bf2d47fd83ebfe8cb2736Matthew Ahrens * Remove the spill block if we have been explicitly asked to
e6518318428d2be1962bf2d47fd83ebfe8cb2736Matthew Ahrens * remove it, or if the object is being removed.
e6518318428d2be1962bf2d47fd83ebfe8cb2736Matthew Ahrens if (dn->dn_rm_spillblk[txgoff] || freeing_dnode) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff];
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Just take the live (open-context) values for checksum and compress.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Strictly speaking it's a future leak, but nothing bad happens if we
fa9e4066f08beec538e775443c5be79dd423fcabahrens * start using the new checksum or compress algorithm a little early.
43466aae47bfcd2ad9bf501faec8e75c08095e4fMax Grossman free_blocks(dn, &dn->dn_phys->dn_spill, 1, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* process all the "freed" ranges in the file */
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrens range_tree_vacate(dn->dn_free_ranges[txgoff],
bf16b11e8deb633dd6c4296d46e92399d1582df4Matthew Ahrens range_tree_destroy(dn->dn_free_ranges[txgoff]);
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee /* this should only happen on a realloc */
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee if (dn->dn_next_nblkptr[txgoff] > dnp->dn_nblkptr) {
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee /* zero the new blkptrs we are gaining */
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee (dn->dn_next_nblkptr[txgoff] - dnp->dn_nblkptr));
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
da03de9920a5a87150a121e9851479c6b3364d8aMark Maybee /* the blkptrs we are losing better be unallocated */
46e1baa6cf6d5432f5fd231bb588df8f9570c858Matthew Ahrens dbuf_sync_list(list, dn->dn_phys->dn_nlevels - 1, tx);
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee * Although we have dropped our reference to the dnode, it
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee * can't be evicted until its written, and we haven't yet
c717a56157ae0e6fca6a1e3689ae1edc385716a3maybee * initiated the IO for the dnode's dbuf.