* Write out the dnode's dirty buffers. */
| 621 | * Write out the dnode's dirty buffers. |
| 622 | */ |
| 623 | void |
| 624 | dnode_sync(dnode_t *dn, dmu_tx_t *tx) |
| 625 | { |
| 626 | objset_t *os = dn->dn_objset; |
| 627 | dnode_phys_t *dnp = dn->dn_phys; |
| 628 | int txgoff = tx->tx_txg & TXG_MASK; |
| 629 | list_t *list = &dn->dn_dirty_records[txgoff]; |
| 630 | static const dnode_phys_t zerodn __maybe_unused = { 0 }; |
| 631 | boolean_t kill_spill = B_FALSE; |
| 632 | |
| 633 | ASSERT(dmu_tx_is_syncing(tx)); |
| 634 | ASSERT(dnp->dn_type != DMU_OT_NONE || dn->dn_allocated_txg); |
| 635 | ASSERT(dnp->dn_type != DMU_OT_NONE || |
| 636 | bcmp(dnp, &zerodn, DNODE_MIN_SIZE) == 0); |
| 637 | DNODE_VERIFY(dn); |
| 638 | |
| 639 | ASSERT(dn->dn_dbuf == NULL || arc_released(dn->dn_dbuf->db_buf)); |
| 640 | |
| 641 | /* |
| 642 | * Do user accounting if it is enabled and this is not |
| 643 | * an encrypted receive. |
| 644 | */ |
| 645 | if (dmu_objset_userused_enabled(os) && |
| 646 | !DMU_OBJECT_IS_SPECIAL(dn->dn_object) && |
| 647 | (!os->os_encrypted || !dmu_objset_is_receiving(os))) { |
| 648 | mutex_enter(&dn->dn_mtx); |
| 649 | dn->dn_oldused = DN_USED_BYTES(dn->dn_phys); |
| 650 | dn->dn_oldflags = dn->dn_phys->dn_flags; |
| 651 | dn->dn_phys->dn_flags |= DNODE_FLAG_USERUSED_ACCOUNTED; |
| 652 | if (dmu_objset_userobjused_enabled(dn->dn_objset)) |
| 653 | dn->dn_phys->dn_flags |= |
| 654 | DNODE_FLAG_USEROBJUSED_ACCOUNTED; |
| 655 | mutex_exit(&dn->dn_mtx); |
| 656 | dmu_objset_userquota_get_ids(dn, B_FALSE, tx); |
| 657 | } else { |
| 658 | /* Once we account for it, we should always account for it */ |
| 659 | ASSERT(!(dn->dn_phys->dn_flags & |
| 660 | DNODE_FLAG_USERUSED_ACCOUNTED)); |
| 661 | ASSERT(!(dn->dn_phys->dn_flags & |
| 662 | DNODE_FLAG_USEROBJUSED_ACCOUNTED)); |
| 663 | } |
| 664 | |
| 665 | mutex_enter(&dn->dn_mtx); |
| 666 | if (dn->dn_allocated_txg == tx->tx_txg) { |
| 667 | /* The dnode is newly allocated or reallocated */ |
| 668 | if (dnp->dn_type == DMU_OT_NONE) { |
| 669 | /* this is a first alloc, not a realloc */ |
| 670 | dnp->dn_nlevels = 1; |
| 671 | dnp->dn_nblkptr = dn->dn_nblkptr; |
| 672 | } |
| 673 | |
| 674 | dnp->dn_type = dn->dn_type; |
| 675 | dnp->dn_bonustype = dn->dn_bonustype; |
| 676 | dnp->dn_bonuslen = dn->dn_bonuslen; |
| 677 | } |
| 678 | |
| 679 | dnp->dn_extra_slots = dn->dn_num_slots - 1; |
| 680 |
no test coverage detected