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
|