| 661 | } |
| 662 | |
| 663 | void |
| 664 | dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, |
| 665 | dmu_object_type_t bonustype, int bonuslen, int dn_slots, |
| 666 | boolean_t keep_spill, dmu_tx_t *tx) |
| 667 | { |
| 668 | int nblkptr; |
| 669 | |
| 670 | ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE); |
| 671 | ASSERT3U(blocksize, <=, |
| 672 | spa_maxblocksize(dmu_objset_spa(dn->dn_objset))); |
| 673 | ASSERT0(blocksize % SPA_MINBLOCKSIZE); |
| 674 | ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx)); |
| 675 | ASSERT(tx->tx_txg != 0); |
| 676 | ASSERT((bonustype == DMU_OT_NONE && bonuslen == 0) || |
| 677 | (bonustype != DMU_OT_NONE && bonuslen != 0) || |
| 678 | (bonustype == DMU_OT_SA && bonuslen == 0)); |
| 679 | ASSERT(DMU_OT_IS_VALID(bonustype)); |
| 680 | ASSERT3U(bonuslen, <=, |
| 681 | DN_BONUS_SIZE(spa_maxdnodesize(dmu_objset_spa(dn->dn_objset)))); |
| 682 | ASSERT3U(bonuslen, <=, DN_BONUS_SIZE(dn_slots << DNODE_SHIFT)); |
| 683 | |
| 684 | dnode_free_interior_slots(dn); |
| 685 | DNODE_STAT_BUMP(dnode_reallocate); |
| 686 | |
| 687 | /* clean up any unreferenced dbufs */ |
| 688 | dnode_evict_dbufs(dn); |
| 689 | |
| 690 | dn->dn_id_flags = 0; |
| 691 | |
| 692 | rw_enter(&dn->dn_struct_rwlock, RW_WRITER); |
| 693 | dnode_setdirty(dn, tx); |
| 694 | if (dn->dn_datablksz != blocksize) { |
| 695 | /* change blocksize */ |
| 696 | ASSERT0(dn->dn_maxblkid); |
| 697 | ASSERT(BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) || |
| 698 | dnode_block_freed(dn, 0)); |
| 699 | |
| 700 | dnode_setdblksz(dn, blocksize); |
| 701 | dn->dn_next_blksz[tx->tx_txg & TXG_MASK] = blocksize; |
| 702 | } |
| 703 | if (dn->dn_bonuslen != bonuslen) |
| 704 | dn->dn_next_bonuslen[tx->tx_txg & TXG_MASK] = bonuslen; |
| 705 | |
| 706 | if (bonustype == DMU_OT_SA) /* Maximize bonus space for SA */ |
| 707 | nblkptr = 1; |
| 708 | else |
| 709 | nblkptr = MIN(DN_MAX_NBLKPTR, |
| 710 | 1 + ((DN_SLOTS_TO_BONUSLEN(dn_slots) - bonuslen) >> |
| 711 | SPA_BLKPTRSHIFT)); |
| 712 | if (dn->dn_bonustype != bonustype) |
| 713 | dn->dn_next_bonustype[tx->tx_txg & TXG_MASK] = bonustype; |
| 714 | if (dn->dn_nblkptr != nblkptr) |
| 715 | dn->dn_next_nblkptr[tx->tx_txg & TXG_MASK] = nblkptr; |
| 716 | if (dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR && !keep_spill) { |
| 717 | dbuf_rm_spill(dn, tx); |
| 718 | dnode_rm_spill(dn, tx); |
| 719 | } |
| 720 |
no test coverage detected