4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012 by Delphix. All rights reserved.
25 */
26
27 #include <sys/zfs_context.h>
28 #include <sys/dbuf.h>
29 #include <sys/dnode.h>
30 #include <sys/dmu.h>
31 #include <sys/dmu_tx.h>
32 #include <sys/dmu_objset.h>
33 #include <sys/dsl_dataset.h>
34 #include <sys/spa.h>
35
36 static void
37 dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
38 {
39 dmu_buf_impl_t *db;
40 int txgoff = tx->tx_txg & TXG_MASK;
41 int nblkptr = dn->dn_phys->dn_nblkptr;
42 int old_toplvl = dn->dn_phys->dn_nlevels - 1;
43 int new_level = dn->dn_next_nlevels[txgoff];
44 int i;
557
558 mutex_enter(&dn->dn_mtx);
559 if (dn->dn_allocated_txg == tx->tx_txg) {
560 /* The dnode is newly allocated or reallocated */
561 if (dnp->dn_type == DMU_OT_NONE) {
562 /* this is a first alloc, not a realloc */
563 dnp->dn_nlevels = 1;
564 dnp->dn_nblkptr = dn->dn_nblkptr;
565 }
566
567 dnp->dn_type = dn->dn_type;
568 dnp->dn_bonustype = dn->dn_bonustype;
569 dnp->dn_bonuslen = dn->dn_bonuslen;
570 }
571
572 ASSERT(dnp->dn_nlevels > 1 ||
573 BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
574 BP_GET_LSIZE(&dnp->dn_blkptr[0]) ==
575 dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
576
577 if (dn->dn_next_blksz[txgoff]) {
578 ASSERT(P2PHASE(dn->dn_next_blksz[txgoff],
579 SPA_MINBLOCKSIZE) == 0);
580 ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
581 dn->dn_maxblkid == 0 || list_head(list) != NULL ||
582 avl_last(&dn->dn_ranges[txgoff]) ||
583 dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT ==
584 dnp->dn_datablkszsec);
585 dnp->dn_datablkszsec =
586 dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT;
587 dn->dn_next_blksz[txgoff] = 0;
588 }
589
590 if (dn->dn_next_bonuslen[txgoff]) {
591 if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN)
592 dnp->dn_bonuslen = 0;
593 else
594 dnp->dn_bonuslen = dn->dn_next_bonuslen[txgoff];
595 ASSERT(dnp->dn_bonuslen <= DN_MAX_BONUSLEN);
596 dn->dn_next_bonuslen[txgoff] = 0;
597 }
598
599 if (dn->dn_next_bonustype[txgoff]) {
600 ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff]));
601 dnp->dn_bonustype = dn->dn_next_bonustype[txgoff];
602 dn->dn_next_bonustype[txgoff] = 0;
603 }
604
605 /*
606 * We will either remove a spill block when a file is being removed
607 * or we have been asked to remove it.
608 */
609 if (dn->dn_rm_spillblk[txgoff] ||
610 ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) &&
611 dn->dn_free_txg > 0 && dn->dn_free_txg <= tx->tx_txg)) {
612 if ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR))
613 kill_spill = B_TRUE;
614 dn->dn_rm_spillblk[txgoff] = 0;
615 }
616
617 if (dn->dn_next_indblkshift[txgoff]) {
618 ASSERT(dnp->dn_nlevels == 1);
619 dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff];
620 dn->dn_next_indblkshift[txgoff] = 0;
621 }
622
623 /*
624 * Just take the live (open-context) values for checksum and compress.
625 * Strictly speaking it's a future leak, but nothing bad happens if we
626 * start using the new checksum or compress algorithm a little early.
627 */
628 dnp->dn_checksum = dn->dn_checksum;
629 dnp->dn_compress = dn->dn_compress;
630
631 mutex_exit(&dn->dn_mtx);
632
633 if (kill_spill) {
634 (void) free_blocks(dn, &dn->dn_phys->dn_spill, 1, tx);
635 mutex_enter(&dn->dn_mtx);
636 dnp->dn_flags &= ~DNODE_FLAG_SPILL_BLKPTR;
637 mutex_exit(&dn->dn_mtx);
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013 by Delphix. All rights reserved.
25 */
26
27 #include <sys/zfs_context.h>
28 #include <sys/dbuf.h>
29 #include <sys/dnode.h>
30 #include <sys/dmu.h>
31 #include <sys/dmu_tx.h>
32 #include <sys/dmu_objset.h>
33 #include <sys/dsl_dataset.h>
34 #include <sys/spa.h>
35
36 static void
37 dnode_increase_indirection(dnode_t *dn, dmu_tx_t *tx)
38 {
39 dmu_buf_impl_t *db;
40 int txgoff = tx->tx_txg & TXG_MASK;
41 int nblkptr = dn->dn_phys->dn_nblkptr;
42 int old_toplvl = dn->dn_phys->dn_nlevels - 1;
43 int new_level = dn->dn_next_nlevels[txgoff];
44 int i;
557
558 mutex_enter(&dn->dn_mtx);
559 if (dn->dn_allocated_txg == tx->tx_txg) {
560 /* The dnode is newly allocated or reallocated */
561 if (dnp->dn_type == DMU_OT_NONE) {
562 /* this is a first alloc, not a realloc */
563 dnp->dn_nlevels = 1;
564 dnp->dn_nblkptr = dn->dn_nblkptr;
565 }
566
567 dnp->dn_type = dn->dn_type;
568 dnp->dn_bonustype = dn->dn_bonustype;
569 dnp->dn_bonuslen = dn->dn_bonuslen;
570 }
571
572 ASSERT(dnp->dn_nlevels > 1 ||
573 BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
574 BP_GET_LSIZE(&dnp->dn_blkptr[0]) ==
575 dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
576
577 if (dn->dn_next_type[txgoff] != 0) {
578 dnp->dn_type = dn->dn_type;
579 dn->dn_next_type[txgoff] = 0;
580 }
581
582 if (dn->dn_next_blksz[txgoff] != 0) {
583 ASSERT(P2PHASE(dn->dn_next_blksz[txgoff],
584 SPA_MINBLOCKSIZE) == 0);
585 ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) ||
586 dn->dn_maxblkid == 0 || list_head(list) != NULL ||
587 avl_last(&dn->dn_ranges[txgoff]) ||
588 dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT ==
589 dnp->dn_datablkszsec);
590 dnp->dn_datablkszsec =
591 dn->dn_next_blksz[txgoff] >> SPA_MINBLOCKSHIFT;
592 dn->dn_next_blksz[txgoff] = 0;
593 }
594
595 if (dn->dn_next_bonuslen[txgoff] != 0) {
596 if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN)
597 dnp->dn_bonuslen = 0;
598 else
599 dnp->dn_bonuslen = dn->dn_next_bonuslen[txgoff];
600 ASSERT(dnp->dn_bonuslen <= DN_MAX_BONUSLEN);
601 dn->dn_next_bonuslen[txgoff] = 0;
602 }
603
604 if (dn->dn_next_bonustype[txgoff] != 0) {
605 ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff]));
606 dnp->dn_bonustype = dn->dn_next_bonustype[txgoff];
607 dn->dn_next_bonustype[txgoff] = 0;
608 }
609
610 /*
611 * We will either remove a spill block when a file is being removed
612 * or we have been asked to remove it.
613 */
614 if (dn->dn_rm_spillblk[txgoff] ||
615 ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) &&
616 dn->dn_free_txg > 0 && dn->dn_free_txg <= tx->tx_txg)) {
617 if ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR))
618 kill_spill = B_TRUE;
619 dn->dn_rm_spillblk[txgoff] = 0;
620 }
621
622 if (dn->dn_next_indblkshift[txgoff] != 0) {
623 ASSERT(dnp->dn_nlevels == 1);
624 dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff];
625 dn->dn_next_indblkshift[txgoff] = 0;
626 }
627
628 /*
629 * Just take the live (open-context) values for checksum and compress.
630 * Strictly speaking it's a future leak, but nothing bad happens if we
631 * start using the new checksum or compress algorithm a little early.
632 */
633 dnp->dn_checksum = dn->dn_checksum;
634 dnp->dn_compress = dn->dn_compress;
635
636 mutex_exit(&dn->dn_mtx);
637
638 if (kill_spill) {
639 (void) free_blocks(dn, &dn->dn_phys->dn_spill, 1, tx);
640 mutex_enter(&dn->dn_mtx);
641 dnp->dn_flags &= ~DNODE_FLAG_SPILL_BLKPTR;
642 mutex_exit(&dn->dn_mtx);
|