Print this page
5047 don't use atomic_*_nv if you discard the return value


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                          */