1568 ASSERT(db->db.db_data != NULL);
1569 if (db->db_blkid == DMU_BONUS_BLKID) {
1570 zio_buf_free(db->db.db_data, DN_MAX_BONUSLEN);
1571 arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
1572 }
1573 db->db.db_data = NULL;
1574 db->db_state = DB_UNCACHED;
1575 }
1576
1577 ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL);
1578 ASSERT(db->db_data_pending == NULL);
1579
1580 db->db_state = DB_EVICTING;
1581 db->db_blkptr = NULL;
1582
1583 DB_DNODE_ENTER(db);
1584 dn = DB_DNODE(db);
1585 dndb = dn->dn_dbuf;
1586 if (db->db_blkid != DMU_BONUS_BLKID && MUTEX_HELD(&dn->dn_dbufs_mtx)) {
1587 list_remove(&dn->dn_dbufs, db);
1588 (void) atomic_dec_32_nv(&dn->dn_dbufs_count);
1589 membar_producer();
1590 DB_DNODE_EXIT(db);
1591 /*
1592 * Decrementing the dbuf count means that the hold corresponding
1593 * to the removed dbuf is no longer discounted in dnode_move(),
1594 * so the dnode cannot be moved until after we release the hold.
1595 * The membar_producer() ensures visibility of the decremented
1596 * value in dnode_move(), since DB_DNODE_EXIT doesn't actually
1597 * release any lock.
1598 */
1599 dnode_rele(dn, db);
1600 db->db_dnode_handle = NULL;
1601 } else {
1602 DB_DNODE_EXIT(db);
1603 }
1604
1605 if (db->db_buf)
1606 dbuf_gone = arc_buf_evict(db->db_buf);
1607
1608 if (!dbuf_gone)
1791 return (0);
1792 }
1793
1794 static void
1795 dbuf_destroy(dmu_buf_impl_t *db)
1796 {
1797 ASSERT(refcount_is_zero(&db->db_holds));
1798
1799 if (db->db_blkid != DMU_BONUS_BLKID) {
1800 /*
1801 * If this dbuf is still on the dn_dbufs list,
1802 * remove it from that list.
1803 */
1804 if (db->db_dnode_handle != NULL) {
1805 dnode_t *dn;
1806
1807 DB_DNODE_ENTER(db);
1808 dn = DB_DNODE(db);
1809 mutex_enter(&dn->dn_dbufs_mtx);
1810 list_remove(&dn->dn_dbufs, db);
1811 (void) atomic_dec_32_nv(&dn->dn_dbufs_count);
1812 mutex_exit(&dn->dn_dbufs_mtx);
1813 DB_DNODE_EXIT(db);
1814 /*
1815 * Decrementing the dbuf count means that the hold
1816 * corresponding to the removed dbuf is no longer
1817 * discounted in dnode_move(), so the dnode cannot be
1818 * moved until after we release the hold.
1819 */
1820 dnode_rele(dn, db);
1821 db->db_dnode_handle = NULL;
1822 }
1823 dbuf_hash_remove(db);
1824 }
1825 db->db_parent = NULL;
1826 db->db_buf = NULL;
1827
1828 ASSERT(!list_link_active(&db->db_link));
1829 ASSERT(db->db.db_data == NULL);
1830 ASSERT(db->db_hash_next == NULL);
1831 ASSERT(db->db_blkptr == NULL);
2076 /*
2077 * We can't freeze indirects if there is a possibility that they
2078 * may be modified in the current syncing context.
2079 */
2080 if (db->db_buf && holds == (db->db_level == 0 ? db->db_dirtycnt : 0))
2081 arc_buf_freeze(db->db_buf);
2082
2083 if (holds == db->db_dirtycnt &&
2084 db->db_level == 0 && db->db_immediate_evict)
2085 dbuf_evict_user(db);
2086
2087 if (holds == 0) {
2088 if (db->db_blkid == DMU_BONUS_BLKID) {
2089 mutex_exit(&db->db_mtx);
2090
2091 /*
2092 * If the dnode moves here, we cannot cross this barrier
2093 * until the move completes.
2094 */
2095 DB_DNODE_ENTER(db);
2096 (void) atomic_dec_32_nv(&DB_DNODE(db)->dn_dbufs_count);
2097 DB_DNODE_EXIT(db);
2098 /*
2099 * The bonus buffer's dnode hold is no longer discounted
2100 * in dnode_move(). The dnode cannot move until after
2101 * the dnode_rele().
2102 */
2103 dnode_rele(DB_DNODE(db), db);
2104 } else if (db->db_buf == NULL) {
2105 /*
2106 * This is a special case: we never associated this
2107 * dbuf with any data allocated from the ARC.
2108 */
2109 ASSERT(db->db_state == DB_UNCACHED ||
2110 db->db_state == DB_NOFILL);
2111 dbuf_evict(db);
2112 } else if (arc_released(db->db_buf)) {
2113 arc_buf_t *buf = db->db_buf;
2114 /*
2115 * This dbuf has anonymous data associated with it.
2116 */
|
1568 ASSERT(db->db.db_data != NULL);
1569 if (db->db_blkid == DMU_BONUS_BLKID) {
1570 zio_buf_free(db->db.db_data, DN_MAX_BONUSLEN);
1571 arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
1572 }
1573 db->db.db_data = NULL;
1574 db->db_state = DB_UNCACHED;
1575 }
1576
1577 ASSERT(db->db_state == DB_UNCACHED || db->db_state == DB_NOFILL);
1578 ASSERT(db->db_data_pending == NULL);
1579
1580 db->db_state = DB_EVICTING;
1581 db->db_blkptr = NULL;
1582
1583 DB_DNODE_ENTER(db);
1584 dn = DB_DNODE(db);
1585 dndb = dn->dn_dbuf;
1586 if (db->db_blkid != DMU_BONUS_BLKID && MUTEX_HELD(&dn->dn_dbufs_mtx)) {
1587 list_remove(&dn->dn_dbufs, db);
1588 atomic_dec_32(&dn->dn_dbufs_count);
1589 membar_producer();
1590 DB_DNODE_EXIT(db);
1591 /*
1592 * Decrementing the dbuf count means that the hold corresponding
1593 * to the removed dbuf is no longer discounted in dnode_move(),
1594 * so the dnode cannot be moved until after we release the hold.
1595 * The membar_producer() ensures visibility of the decremented
1596 * value in dnode_move(), since DB_DNODE_EXIT doesn't actually
1597 * release any lock.
1598 */
1599 dnode_rele(dn, db);
1600 db->db_dnode_handle = NULL;
1601 } else {
1602 DB_DNODE_EXIT(db);
1603 }
1604
1605 if (db->db_buf)
1606 dbuf_gone = arc_buf_evict(db->db_buf);
1607
1608 if (!dbuf_gone)
1791 return (0);
1792 }
1793
1794 static void
1795 dbuf_destroy(dmu_buf_impl_t *db)
1796 {
1797 ASSERT(refcount_is_zero(&db->db_holds));
1798
1799 if (db->db_blkid != DMU_BONUS_BLKID) {
1800 /*
1801 * If this dbuf is still on the dn_dbufs list,
1802 * remove it from that list.
1803 */
1804 if (db->db_dnode_handle != NULL) {
1805 dnode_t *dn;
1806
1807 DB_DNODE_ENTER(db);
1808 dn = DB_DNODE(db);
1809 mutex_enter(&dn->dn_dbufs_mtx);
1810 list_remove(&dn->dn_dbufs, db);
1811 atomic_dec_32(&dn->dn_dbufs_count);
1812 mutex_exit(&dn->dn_dbufs_mtx);
1813 DB_DNODE_EXIT(db);
1814 /*
1815 * Decrementing the dbuf count means that the hold
1816 * corresponding to the removed dbuf is no longer
1817 * discounted in dnode_move(), so the dnode cannot be
1818 * moved until after we release the hold.
1819 */
1820 dnode_rele(dn, db);
1821 db->db_dnode_handle = NULL;
1822 }
1823 dbuf_hash_remove(db);
1824 }
1825 db->db_parent = NULL;
1826 db->db_buf = NULL;
1827
1828 ASSERT(!list_link_active(&db->db_link));
1829 ASSERT(db->db.db_data == NULL);
1830 ASSERT(db->db_hash_next == NULL);
1831 ASSERT(db->db_blkptr == NULL);
2076 /*
2077 * We can't freeze indirects if there is a possibility that they
2078 * may be modified in the current syncing context.
2079 */
2080 if (db->db_buf && holds == (db->db_level == 0 ? db->db_dirtycnt : 0))
2081 arc_buf_freeze(db->db_buf);
2082
2083 if (holds == db->db_dirtycnt &&
2084 db->db_level == 0 && db->db_immediate_evict)
2085 dbuf_evict_user(db);
2086
2087 if (holds == 0) {
2088 if (db->db_blkid == DMU_BONUS_BLKID) {
2089 mutex_exit(&db->db_mtx);
2090
2091 /*
2092 * If the dnode moves here, we cannot cross this barrier
2093 * until the move completes.
2094 */
2095 DB_DNODE_ENTER(db);
2096 atomic_dec_32(&DB_DNODE(db)->dn_dbufs_count);
2097 DB_DNODE_EXIT(db);
2098 /*
2099 * The bonus buffer's dnode hold is no longer discounted
2100 * in dnode_move(). The dnode cannot move until after
2101 * the dnode_rele().
2102 */
2103 dnode_rele(DB_DNODE(db), db);
2104 } else if (db->db_buf == NULL) {
2105 /*
2106 * This is a special case: we never associated this
2107 * dbuf with any data allocated from the ARC.
2108 */
2109 ASSERT(db->db_state == DB_UNCACHED ||
2110 db->db_state == DB_NOFILL);
2111 dbuf_evict(db);
2112 } else if (arc_released(db->db_buf)) {
2113 arc_buf_t *buf = db->db_buf;
2114 /*
2115 * This dbuf has anonymous data associated with it.
2116 */
|