@@ -93,7 +93,9 @@ dbuf_cons(void *vdb, void *unused, int kmflag)
93
93
mutex_init (& db -> db_mtx , NULL , MUTEX_DEFAULT , NULL );
94
94
cv_init (& db -> db_changed , NULL , CV_DEFAULT , NULL );
95
95
refcount_create (& db -> db_holds );
96
- list_link_init (& db -> db_link );
96
+
97
+ db -> db_creation = gethrtime ();
98
+
97
99
return (0 );
98
100
}
99
101
@@ -386,7 +388,7 @@ dbuf_verify(dmu_buf_impl_t *db)
386
388
ASSERT3U (db -> db_level , < , dn -> dn_nlevels );
387
389
ASSERT (db -> db_blkid == DMU_BONUS_BLKID ||
388
390
db -> db_blkid == DMU_SPILL_BLKID ||
389
- !list_is_empty (& dn -> dn_dbufs ));
391
+ !avl_is_empty (& dn -> dn_dbufs ));
390
392
}
391
393
if (db -> db_blkid == DMU_BONUS_BLKID ) {
392
394
ASSERT (dn != NULL );
@@ -866,23 +868,34 @@ dbuf_unoverride(dbuf_dirty_record_t *dr)
866
868
* receive; see comment below for details.
867
869
*/
868
870
void
869
- dbuf_free_range (dnode_t * dn , uint64_t start , uint64_t end , dmu_tx_t * tx )
871
+ dbuf_free_range (dnode_t * dn , uint64_t start_blkid , uint64_t end_blkid ,
872
+ dmu_tx_t * tx )
870
873
{
871
- dmu_buf_impl_t * db , * db_next ;
874
+ dmu_buf_impl_t * db , * db_next , * db_search ;
872
875
uint64_t txg = tx -> tx_txg ;
876
+ avl_index_t where ;
873
877
boolean_t freespill =
874
- (start == DMU_SPILL_BLKID || end == DMU_SPILL_BLKID );
878
+ (start_blkid == DMU_SPILL_BLKID || end_blkid == DMU_SPILL_BLKID );
879
+
880
+ if (end_blkid > dn -> dn_maxblkid && !freespill )
881
+ end_blkid = dn -> dn_maxblkid ;
882
+ dprintf_dnode (dn , "start=%llu end=%llu\n" , start_blkid , end_blkid );
875
883
876
- if (end > dn -> dn_maxblkid && !freespill )
877
- end = dn -> dn_maxblkid ;
878
- dprintf_dnode (dn , "start=%llu end=%llu\n" , start , end );
884
+ db_seach = kmem_alloc (sizeof (dmu_buf_impl_t ), KM_SLEEP );
885
+ db_search -> db_level = 0 ;
886
+ db_search -> db_blkid = start_blkid ;
887
+ db_search -> db_creation = 0 ;
879
888
880
889
mutex_enter (& dn -> dn_dbufs_mtx );
881
- if (start >= dn -> dn_unlisted_l0_blkid * dn -> dn_datablksz &&
882
- !freespill ) {
890
+ if (start_blkid >= dn -> dn_unlisted_l0_blkid && !freespill ) {
883
891
/* There can't be any dbufs in this range; no need to search. */
884
- mutex_exit (& dn -> dn_dbufs_mtx );
885
- return ;
892
+ #ifdef DEBUG
893
+ db = avl_find (& dn -> dn_dbufs , db_search , & where );
894
+ ASSERT3P (db , = = , NULL );
895
+ db = avl_nearest (& dn -> dn_dbufs , where , AVL_AFTER );
896
+ ASSERT (db == NULL || db -> db_level > 0 );
897
+ #endif
898
+ goto out ;
886
899
} else if (dmu_objset_is_receiving (dn -> dn_objset )) {
887
900
/*
888
901
* If we are receiving, we expect there to be no dbufs in
@@ -894,19 +907,18 @@ dbuf_free_range(dnode_t *dn, uint64_t start, uint64_t end, dmu_tx_t *tx)
894
907
atomic_inc_64 (& zfs_free_range_recv_miss );
895
908
}
896
909
897
- for (db = list_head (& dn -> dn_dbufs ); db != NULL ; db = db_next ) {
898
- db_next = list_next (& dn -> dn_dbufs , db );
910
+ db = avl_find (& dn -> dn_dbufs , db_search , & where );
911
+ ASSERT3P (db , = = , NULL );
912
+ db = avl_nearest (& dn -> dn_dbufs , where , AVL_AFTER );
913
+
914
+ for (; db != NULL ; db = db_next ) {
915
+ db_next = AVL_NEXT (& dn -> dn_dbufs , db );
899
916
ASSERT (db -> db_blkid != DMU_BONUS_BLKID );
900
917
901
- /* Skip indirect blocks. */
902
- if (db -> db_level != 0 )
903
- continue ;
904
- /* Skip direct blocks outside the range. */
905
- if (!freespill && (db -> db_blkid < start || db -> db_blkid > end ))
906
- continue ;
907
- /* Skip all direct blocks, only free spill blocks. */
908
- if (freespill && (db -> db_blkid != DMU_SPILL_BLKID ))
909
- continue ;
918
+ if (db -> db_level != 0 || db -> db_blkid > end_blkid ) {
919
+ break ;
920
+ }
921
+ ASSERT3U (db -> db_blkid , >=, start_blkid );
910
922
911
923
/* found a level 0 buffer in the range */
912
924
mutex_enter (& db -> db_mtx );
@@ -968,6 +980,9 @@ dbuf_free_range(dnode_t *dn, uint64_t start, uint64_t end, dmu_tx_t *tx)
968
980
969
981
mutex_exit (& db -> db_mtx );
970
982
}
983
+
984
+ out :
985
+ kmem_free (db_search , sizeof (dmu_buf_impl_t ));
971
986
mutex_exit (& dn -> dn_dbufs_mtx );
972
987
}
973
988
@@ -1657,7 +1672,7 @@ dbuf_clear(dmu_buf_impl_t *db)
1657
1672
dn = DB_DNODE (db );
1658
1673
dndb = dn -> dn_dbuf ;
1659
1674
if (db -> db_blkid != DMU_BONUS_BLKID && MUTEX_HELD (& dn -> dn_dbufs_mtx )) {
1660
- list_remove (& dn -> dn_dbufs , db );
1675
+ avl_remove (& dn -> dn_dbufs , db );
1661
1676
atomic_dec_32 (& dn -> dn_dbufs_count );
1662
1677
membar_producer ();
1663
1678
DB_DNODE_EXIT (db );
@@ -1829,7 +1844,7 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid,
1829
1844
mutex_exit (& dn -> dn_dbufs_mtx );
1830
1845
return (odb );
1831
1846
}
1832
- list_insert_head (& dn -> dn_dbufs , db );
1847
+ avl_add (& dn -> dn_dbufs , db );
1833
1848
if (db -> db_level == 0 && db -> db_blkid >=
1834
1849
dn -> dn_unlisted_l0_blkid )
1835
1850
dn -> dn_unlisted_l0_blkid = db -> db_blkid + 1 ;
@@ -1888,7 +1903,7 @@ dbuf_destroy(dmu_buf_impl_t *db)
1888
1903
DB_DNODE_ENTER (db );
1889
1904
dn = DB_DNODE (db );
1890
1905
mutex_enter (& dn -> dn_dbufs_mtx );
1891
- list_remove (& dn -> dn_dbufs , db );
1906
+ avl_remove (& dn -> dn_dbufs , db );
1892
1907
atomic_dec_32 (& dn -> dn_dbufs_count );
1893
1908
mutex_exit (& dn -> dn_dbufs_mtx );
1894
1909
DB_DNODE_EXIT (db );
@@ -1906,7 +1921,6 @@ dbuf_destroy(dmu_buf_impl_t *db)
1906
1921
db -> db_parent = NULL ;
1907
1922
db -> db_buf = NULL ;
1908
1923
1909
- ASSERT (!list_link_active (& db -> db_link ));
1910
1924
ASSERT (db -> db .db_data == NULL );
1911
1925
ASSERT (db -> db_hash_next == NULL );
1912
1926
ASSERT (db -> db_blkptr == NULL );
0 commit comments