20
20
*/
21
21
/*
22
22
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23
- * Copyright (c) 2013 by Delphix. All rights reserved.
23
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
24
24
*/
25
25
26
26
#include <sys/zfs_context.h>
35
35
#include <sys/spa.h>
36
36
#include <sys/zio.h>
37
37
#include <sys/dmu_zfetch.h>
38
-
39
- static int free_range_compar (const void * node1 , const void * node2 );
38
+ #include <sys/range_tree.h>
40
39
41
40
static kmem_cache_t * dnode_cache ;
42
41
/*
@@ -92,9 +91,7 @@ dnode_cons(void *arg, void *unused, int kmflag)
92
91
93
92
for (i = 0 ; i < TXG_SIZE ; i ++ ) {
94
93
list_link_init (& dn -> dn_dirty_link [i ]);
95
- avl_create (& dn -> dn_ranges [i ], free_range_compar ,
96
- sizeof (free_range_t ),
97
- offsetof(struct free_range , fr_node ));
94
+ dn -> dn_free_ranges [i ] = NULL ;
98
95
list_create (& dn -> dn_dirty_records [i ],
99
96
sizeof (dbuf_dirty_record_t ),
100
97
offsetof(dbuf_dirty_record_t , dr_dirty_node ));
@@ -142,7 +139,7 @@ dnode_dest(void *arg, void *unused)
142
139
143
140
for (i = 0 ; i < TXG_SIZE ; i ++ ) {
144
141
ASSERT (!list_link_active (& dn -> dn_dirty_link [i ]));
145
- avl_destroy ( & dn -> dn_ranges [i ]);
142
+ ASSERT3P ( dn -> dn_free_ranges [i ], = = , NULL );
146
143
list_destroy (& dn -> dn_dirty_records [i ]);
147
144
ASSERT0 (dn -> dn_next_nblkptr [i ]);
148
145
ASSERT0 (dn -> dn_next_nlevels [i ]);
@@ -313,19 +310,6 @@ dnode_buf_byteswap(void *vbuf, size_t size)
313
310
}
314
311
}
315
312
316
- static int
317
- free_range_compar (const void * node1 , const void * node2 )
318
- {
319
- const free_range_t * rp1 = node1 ;
320
- const free_range_t * rp2 = node2 ;
321
-
322
- if (rp1 -> fr_blkid < rp2 -> fr_blkid )
323
- return (-1 );
324
- else if (rp1 -> fr_blkid > rp2 -> fr_blkid )
325
- return (1 );
326
- else return (0 );
327
- }
328
-
329
313
void
330
314
dnode_setbonuslen (dnode_t * dn , int newsize , dmu_tx_t * tx )
331
315
{
@@ -374,7 +358,7 @@ dnode_setdblksz(dnode_t *dn, int size)
374
358
1 <<(sizeof (dn -> dn_phys -> dn_datablkszsec ) * 8 ));
375
359
dn -> dn_datablksz = size ;
376
360
dn -> dn_datablkszsec = size >> SPA_MINBLOCKSHIFT ;
377
- dn -> dn_datablkshift = ISP2 (size ) ? highbit (size - 1 ) : 0 ;
361
+ dn -> dn_datablkshift = ISP2 (size ) ? highbit64 (size - 1 ) : 0 ;
378
362
}
379
363
380
364
static dnode_t *
@@ -530,7 +514,7 @@ dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
530
514
ASSERT0 (dn -> dn_next_blksz [i ]);
531
515
ASSERT (!list_link_active (& dn -> dn_dirty_link [i ]));
532
516
ASSERT3P (list_head (& dn -> dn_dirty_records [i ]), = = , NULL );
533
- ASSERT0 ( avl_numnodes ( & dn -> dn_ranges [i ]) );
517
+ ASSERT3P ( dn -> dn_free_ranges [i ], = = , NULL );
534
518
}
535
519
536
520
dn -> dn_type = ot ;
@@ -695,7 +679,8 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
695
679
list_move_tail (& ndn -> dn_dirty_records [i ],
696
680
& odn -> dn_dirty_records [i ]);
697
681
}
698
- bcopy (& odn -> dn_ranges [0 ], & ndn -> dn_ranges [0 ], sizeof (odn -> dn_ranges ));
682
+ bcopy (& odn -> dn_free_ranges [0 ], & ndn -> dn_free_ranges [0 ],
683
+ sizeof (odn -> dn_free_ranges ));
699
684
ndn -> dn_allocated_txg = odn -> dn_allocated_txg ;
700
685
ndn -> dn_free_txg = odn -> dn_free_txg ;
701
686
ndn -> dn_assigned_txg = odn -> dn_assigned_txg ;
@@ -758,8 +743,7 @@ dnode_move_impl(dnode_t *odn, dnode_t *ndn)
758
743
list_create (& odn -> dn_dirty_records [i ],
759
744
sizeof (dbuf_dirty_record_t ),
760
745
offsetof(dbuf_dirty_record_t , dr_dirty_node ));
761
- odn -> dn_ranges [i ].avl_root = NULL ;
762
- odn -> dn_ranges [i ].avl_numnodes = 0 ;
746
+ odn -> dn_free_ranges [i ] = NULL ;
763
747
odn -> dn_next_nlevels [i ] = 0 ;
764
748
odn -> dn_next_indblkshift [i ] = 0 ;
765
749
odn -> dn_next_bonustype [i ] = 0 ;
@@ -1462,59 +1446,6 @@ dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t have_read)
1462
1446
rw_downgrade (& dn -> dn_struct_rwlock );
1463
1447
}
1464
1448
1465
- void
1466
- dnode_clear_range (dnode_t * dn , uint64_t blkid , uint64_t nblks , dmu_tx_t * tx )
1467
- {
1468
- avl_tree_t * tree = & dn -> dn_ranges [tx -> tx_txg & TXG_MASK ];
1469
- avl_index_t where ;
1470
- free_range_t * rp ;
1471
- free_range_t rp_tofind ;
1472
- uint64_t endblk = blkid + nblks ;
1473
-
1474
- ASSERT (MUTEX_HELD (& dn -> dn_mtx ));
1475
- ASSERT (nblks <= UINT64_MAX - blkid ); /* no overflow */
1476
-
1477
- dprintf_dnode (dn , "blkid=%llu nblks=%llu txg=%llu\n" ,
1478
- blkid , nblks , tx -> tx_txg );
1479
- rp_tofind .fr_blkid = blkid ;
1480
- rp = avl_find (tree , & rp_tofind , & where );
1481
- if (rp == NULL )
1482
- rp = avl_nearest (tree , where , AVL_BEFORE );
1483
- if (rp == NULL )
1484
- rp = avl_nearest (tree , where , AVL_AFTER );
1485
-
1486
- while (rp && (rp -> fr_blkid <= blkid + nblks )) {
1487
- uint64_t fr_endblk = rp -> fr_blkid + rp -> fr_nblks ;
1488
- free_range_t * nrp = AVL_NEXT (tree , rp );
1489
-
1490
- if (blkid <= rp -> fr_blkid && endblk >= fr_endblk ) {
1491
- /* clear this entire range */
1492
- avl_remove (tree , rp );
1493
- kmem_free (rp , sizeof (free_range_t ));
1494
- } else if (blkid <= rp -> fr_blkid &&
1495
- endblk > rp -> fr_blkid && endblk < fr_endblk ) {
1496
- /* clear the beginning of this range */
1497
- rp -> fr_blkid = endblk ;
1498
- rp -> fr_nblks = fr_endblk - endblk ;
1499
- } else if (blkid > rp -> fr_blkid && blkid < fr_endblk &&
1500
- endblk >= fr_endblk ) {
1501
- /* clear the end of this range */
1502
- rp -> fr_nblks = blkid - rp -> fr_blkid ;
1503
- } else if (blkid > rp -> fr_blkid && endblk < fr_endblk ) {
1504
- /* clear a chunk out of this range */
1505
- free_range_t * new_rp =
1506
- kmem_alloc (sizeof (free_range_t ), KM_PUSHPAGE );
1507
-
1508
- new_rp -> fr_blkid = endblk ;
1509
- new_rp -> fr_nblks = fr_endblk - endblk ;
1510
- avl_insert_here (tree , new_rp , rp , AVL_AFTER );
1511
- rp -> fr_nblks = blkid - rp -> fr_blkid ;
1512
- }
1513
- /* there may be no overlap */
1514
- rp = nrp ;
1515
- }
1516
- }
1517
-
1518
1449
void
1519
1450
dnode_free_range (dnode_t * dn , uint64_t off , uint64_t len , dmu_tx_t * tx )
1520
1451
{
@@ -1665,22 +1596,17 @@ dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx)
1665
1596
* We will finish up this free operation in the syncing phase.
1666
1597
*/
1667
1598
mutex_enter (& dn -> dn_mtx );
1668
- dnode_clear_range (dn , blkid , nblks , tx );
1669
1599
{
1670
- free_range_t * rp , * found ;
1671
- avl_index_t where ;
1672
- avl_tree_t * tree = & dn -> dn_ranges [tx -> tx_txg & TXG_MASK ];
1673
-
1674
- /* Add new range to dn_ranges */
1675
- rp = kmem_alloc (sizeof (free_range_t ), KM_PUSHPAGE );
1676
- rp -> fr_blkid = blkid ;
1677
- rp -> fr_nblks = nblks ;
1678
- found = avl_find (tree , rp , & where );
1679
- ASSERT (found == NULL );
1680
- avl_insert (tree , rp , where );
1681
- dprintf_dnode (dn , "blkid=%llu nblks=%llu txg=%llu\n" ,
1682
- blkid , nblks , tx -> tx_txg );
1600
+ int txgoff = tx -> tx_txg & TXG_MASK ;
1601
+ if (dn -> dn_free_ranges [txgoff ] == NULL ) {
1602
+ dn -> dn_free_ranges [txgoff ] =
1603
+ range_tree_create (NULL , NULL , & dn -> dn_mtx );
1604
+ }
1605
+ range_tree_clear (dn -> dn_free_ranges [txgoff ], blkid , nblks );
1606
+ range_tree_add (dn -> dn_free_ranges [txgoff ], blkid , nblks );
1683
1607
}
1608
+ dprintf_dnode (dn , "blkid=%llu nblks=%llu txg=%llu\n" ,
1609
+ blkid , nblks , tx -> tx_txg );
1684
1610
mutex_exit (& dn -> dn_mtx );
1685
1611
1686
1612
dbuf_free_range (dn , blkid , blkid + nblks - 1 , tx );
@@ -1708,7 +1634,6 @@ dnode_spill_freed(dnode_t *dn)
1708
1634
uint64_t
1709
1635
dnode_block_freed (dnode_t * dn , uint64_t blkid )
1710
1636
{
1711
- free_range_t range_tofind ;
1712
1637
void * dp = spa_get_dsl (dn -> dn_objset -> os_spa );
1713
1638
int i ;
1714
1639
@@ -1728,20 +1653,10 @@ dnode_block_freed(dnode_t *dn, uint64_t blkid)
1728
1653
if (blkid == DMU_SPILL_BLKID )
1729
1654
return (dnode_spill_freed (dn ));
1730
1655
1731
- range_tofind .fr_blkid = blkid ;
1732
1656
mutex_enter (& dn -> dn_mtx );
1733
1657
for (i = 0 ; i < TXG_SIZE ; i ++ ) {
1734
- free_range_t * range_found ;
1735
- avl_index_t idx ;
1736
-
1737
- range_found = avl_find (& dn -> dn_ranges [i ], & range_tofind , & idx );
1738
- if (range_found ) {
1739
- ASSERT (range_found -> fr_nblks > 0 );
1740
- break ;
1741
- }
1742
- range_found = avl_nearest (& dn -> dn_ranges [i ], idx , AVL_BEFORE );
1743
- if (range_found &&
1744
- range_found -> fr_blkid + range_found -> fr_nblks > blkid )
1658
+ if (dn -> dn_free_ranges [i ] != NULL &&
1659
+ range_tree_contains (dn -> dn_free_ranges [i ], blkid , 1 ))
1745
1660
break ;
1746
1661
}
1747
1662
mutex_exit (& dn -> dn_mtx );
0 commit comments