Print this page
6841 Undirty freed spill blocks
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


 891          */
 892         arc_release(dr->dt.dl.dr_data, db);
 893 }
 894 
 895 /*
 896  * Evict (if its unreferenced) or clear (if its referenced) any level-0
 897  * data blocks in the free range, so that any future readers will find
 898  * empty blocks.
 899  *
 900  * This is a no-op if the dataset is in the middle of an incremental
 901  * receive; see comment below for details.
 902  */
 903 void
 904 dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
 905     dmu_tx_t *tx)
 906 {
 907         dmu_buf_impl_t db_search;
 908         dmu_buf_impl_t *db, *db_next;
 909         uint64_t txg = tx->tx_txg;
 910         avl_index_t where;


 911 
 912         if (end_blkid > dn->dn_maxblkid && (end_blkid != DMU_SPILL_BLKID))
 913                 end_blkid = dn->dn_maxblkid;
 914         dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid);
 915 
 916         db_search.db_level = 0;
 917         db_search.db_blkid = start_blkid;
 918         db_search.db_state = DB_SEARCH;
 919 
 920         mutex_enter(&dn->dn_dbufs_mtx);
 921         if (start_blkid >= dn->dn_unlisted_l0_blkid) {
 922                 /* There can't be any dbufs in this range; no need to search. */
 923 #ifdef DEBUG
 924                 db = avl_find(&dn->dn_dbufs, &db_search, &where);
 925                 ASSERT3P(db, ==, NULL);
 926                 db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
 927                 ASSERT(db == NULL || db->db_level > 0);
 928 #endif
 929                 mutex_exit(&dn->dn_dbufs_mtx);
 930                 return;
 931         } else if (dmu_objset_is_receiving(dn->dn_objset)) {
 932                 /*
 933                  * If we are receiving, we expect there to be no dbufs in
 934                  * the range to be freed, because receive modifies each
 935                  * block at most once, and in offset order.  If this is
 936                  * not the case, it can lead to performance problems,
 937                  * so note that we unexpectedly took the slow path.
 938                  */
 939                 atomic_inc_64(&zfs_free_range_recv_miss);
 940         }
 941 




 891          */
 892         arc_release(dr->dt.dl.dr_data, db);
 893 }
 894 
 895 /*
 896  * Evict (if its unreferenced) or clear (if its referenced) any level-0
 897  * data blocks in the free range, so that any future readers will find
 898  * empty blocks.
 899  *
 900  * This is a no-op if the dataset is in the middle of an incremental
 901  * receive; see comment below for details.
 902  */
 903 void
 904 dbuf_free_range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid,
 905     dmu_tx_t *tx)
 906 {
 907         dmu_buf_impl_t db_search;
 908         dmu_buf_impl_t *db, *db_next;
 909         uint64_t txg = tx->tx_txg;
 910         avl_index_t where;
 911         boolean_t freespill =
 912             (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID);
 913 
 914         if (end_blkid > dn->dn_maxblkid && !freespill)
 915                 end_blkid = dn->dn_maxblkid;
 916         dprintf_dnode(dn, "start=%llu end=%llu\n", start_blkid, end_blkid);
 917 
 918         db_search.db_level = 0;
 919         db_search.db_blkid = start_blkid;
 920         db_search.db_state = DB_SEARCH;
 921 
 922         mutex_enter(&dn->dn_dbufs_mtx);
 923         if (start_blkid >= dn->dn_unlisted_l0_blkid && !freespill) {
 924                 /* There can't be any dbufs in this range; no need to search. */
 925 #ifdef DEBUG
 926                 db = avl_find(&dn->dn_dbufs, &db_search, &where);
 927                 ASSERT3P(db, ==, NULL);
 928                 db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER);
 929                 ASSERT(db == NULL || db->db_level > 0);
 930 #endif
 931                 mutex_exit(&dn->dn_dbufs_mtx);
 932                 return;
 933         } else if (dmu_objset_is_receiving(dn->dn_objset)) {
 934                 /*
 935                  * If we are receiving, we expect there to be no dbufs in
 936                  * the range to be freed, because receive modifies each
 937                  * block at most once, and in offset order.  If this is
 938                  * not the case, it can lead to performance problems,
 939                  * so note that we unexpectedly took the slow path.
 940                  */
 941                 atomic_inc_64(&zfs_free_range_recv_miss);
 942         }
 943