| 1653 | } |
| 1654 | |
| 1655 | void |
| 1656 | dnode_setdirty(dnode_t *dn, dmu_tx_t *tx) |
| 1657 | { |
| 1658 | objset_t *os = dn->dn_objset; |
| 1659 | uint64_t txg = tx->tx_txg; |
| 1660 | |
| 1661 | if (DMU_OBJECT_IS_SPECIAL(dn->dn_object)) { |
| 1662 | dsl_dataset_dirty(os->os_dsl_dataset, tx); |
| 1663 | return; |
| 1664 | } |
| 1665 | |
| 1666 | DNODE_VERIFY(dn); |
| 1667 | |
| 1668 | #ifdef ZFS_DEBUG |
| 1669 | mutex_enter(&dn->dn_mtx); |
| 1670 | ASSERT(dn->dn_phys->dn_type || dn->dn_allocated_txg); |
| 1671 | ASSERT(dn->dn_free_txg == 0 || dn->dn_free_txg >= txg); |
| 1672 | mutex_exit(&dn->dn_mtx); |
| 1673 | #endif |
| 1674 | |
| 1675 | /* |
| 1676 | * Determine old uid/gid when necessary |
| 1677 | */ |
| 1678 | dmu_objset_userquota_get_ids(dn, B_TRUE, tx); |
| 1679 | |
| 1680 | multilist_t *dirtylist = os->os_dirty_dnodes[txg & TXG_MASK]; |
| 1681 | multilist_sublist_t *mls = multilist_sublist_lock_obj(dirtylist, dn); |
| 1682 | |
| 1683 | /* |
| 1684 | * If we are already marked dirty, we're done. |
| 1685 | */ |
| 1686 | if (multilist_link_active(&dn->dn_dirty_link[txg & TXG_MASK])) { |
| 1687 | multilist_sublist_unlock(mls); |
| 1688 | return; |
| 1689 | } |
| 1690 | |
| 1691 | ASSERT(!zfs_refcount_is_zero(&dn->dn_holds) || |
| 1692 | !avl_is_empty(&dn->dn_dbufs)); |
| 1693 | ASSERT(dn->dn_datablksz != 0); |
| 1694 | ASSERT0(dn->dn_next_bonuslen[txg & TXG_MASK]); |
| 1695 | ASSERT0(dn->dn_next_blksz[txg & TXG_MASK]); |
| 1696 | ASSERT0(dn->dn_next_bonustype[txg & TXG_MASK]); |
| 1697 | |
| 1698 | dprintf_ds(os->os_dsl_dataset, "obj=%llu txg=%llu\n", |
| 1699 | dn->dn_object, txg); |
| 1700 | |
| 1701 | multilist_sublist_insert_head(mls, dn); |
| 1702 | |
| 1703 | multilist_sublist_unlock(mls); |
| 1704 | |
| 1705 | /* |
| 1706 | * The dnode maintains a hold on its containing dbuf as |
| 1707 | * long as there are holds on it. Each instantiated child |
| 1708 | * dbuf maintains a hold on the dnode. When the last child |
| 1709 | * drops its hold, the dnode will drop its hold on the |
| 1710 | * containing dbuf. We add a "dirty hold" here so that the |
| 1711 | * dnode will hang around after we finish processing its |
| 1712 | * children. |
no test coverage detected