22
22
#include "kernel-shared/transaction.h"
23
23
#include "kernel-shared/messages.h"
24
24
25
+ struct kmem_cache * btrfs_delayed_ref_head_cachep ;
26
+ struct kmem_cache * btrfs_delayed_tree_ref_cachep ;
27
+ struct kmem_cache * btrfs_delayed_data_ref_cachep ;
28
+ struct kmem_cache * btrfs_delayed_extent_op_cachep ;
25
29
/*
26
30
* delayed back reference update tracking. For subvolume trees
27
31
* we queue up extent allocations and backref maintenance for
@@ -51,6 +55,34 @@ static int comp_tree_refs(struct btrfs_delayed_tree_ref *ref1,
51
55
return 0 ;
52
56
}
53
57
58
+ /*
59
+ * compare two delayed data backrefs with same bytenr and type
60
+ */
61
+ static int comp_data_refs (struct btrfs_delayed_data_ref * ref1 ,
62
+ struct btrfs_delayed_data_ref * ref2 )
63
+ {
64
+ if (ref1 -> node .type == BTRFS_EXTENT_DATA_REF_KEY ) {
65
+ if (ref1 -> root < ref2 -> root )
66
+ return -1 ;
67
+ if (ref1 -> root > ref2 -> root )
68
+ return 1 ;
69
+ if (ref1 -> objectid < ref2 -> objectid )
70
+ return -1 ;
71
+ if (ref1 -> objectid > ref2 -> objectid )
72
+ return 1 ;
73
+ if (ref1 -> offset < ref2 -> offset )
74
+ return -1 ;
75
+ if (ref1 -> offset > ref2 -> offset )
76
+ return 1 ;
77
+ } else {
78
+ if (ref1 -> parent < ref2 -> parent )
79
+ return -1 ;
80
+ if (ref1 -> parent > ref2 -> parent )
81
+ return 1 ;
82
+ }
83
+ return 0 ;
84
+ }
85
+
54
86
static int comp_refs (struct btrfs_delayed_ref_node * ref1 ,
55
87
struct btrfs_delayed_ref_node * ref2 ,
56
88
bool check_seq )
@@ -66,8 +98,8 @@ static int comp_refs(struct btrfs_delayed_ref_node *ref1,
66
98
ret = comp_tree_refs (btrfs_delayed_node_to_tree_ref (ref1 ),
67
99
btrfs_delayed_node_to_tree_ref (ref2 ));
68
100
else
69
- BUG ();
70
-
101
+ ret = comp_data_refs ( btrfs_delayed_node_to_data_ref ( ref1 ),
102
+ btrfs_delayed_node_to_data_ref ( ref2 ));
71
103
if (ret )
72
104
return ret ;
73
105
if (check_seq ) {
@@ -299,14 +331,28 @@ btrfs_select_ref_head(struct btrfs_trans_handle *trans)
299
331
href_node );
300
332
}
301
333
302
- head -> processing = 1 ;
334
+ head -> processing = true ;
303
335
WARN_ON (delayed_refs -> num_heads_ready == 0 );
304
336
delayed_refs -> num_heads_ready -- ;
305
337
delayed_refs -> run_delayed_start = head -> bytenr +
306
338
head -> num_bytes ;
307
339
return head ;
308
340
}
309
341
342
+ void btrfs_delete_ref_head (struct btrfs_delayed_ref_root * delayed_refs ,
343
+ struct btrfs_delayed_ref_head * head )
344
+ {
345
+ lockdep_assert_held (& delayed_refs -> lock );
346
+ lockdep_assert_held (& head -> lock );
347
+
348
+ rb_erase (& head -> href_node , & delayed_refs -> href_root );
349
+ RB_CLEAR_NODE (& head -> href_node );
350
+ atomic_dec (& delayed_refs -> num_entries );
351
+ delayed_refs -> num_heads -- ;
352
+ if (!head -> processing )
353
+ delayed_refs -> num_heads_ready -- ;
354
+ }
355
+
310
356
/*
311
357
* Helper to insert the ref_node to the tail or merge with tail.
312
358
*
@@ -431,7 +477,7 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref,
431
477
bool is_system )
432
478
{
433
479
int count_mod = 1 ;
434
- int must_insert_reserved = 0 ;
480
+ bool must_insert_reserved = false ;
435
481
436
482
/* If reserved is provided, it must be a data extent. */
437
483
BUG_ON (!is_data && reserved );
@@ -456,11 +502,11 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref,
456
502
* BTRFS_ADD_DELAYED_REF because other special casing is not required.
457
503
*/
458
504
if (action == BTRFS_ADD_DELAYED_EXTENT )
459
- must_insert_reserved = 1 ;
505
+ must_insert_reserved = true ;
460
506
else
461
- must_insert_reserved = 0 ;
507
+ must_insert_reserved = false ;
462
508
463
- head_ref -> refs = 1 ;
509
+ refcount_set ( & head_ref -> refs , 1 ) ;
464
510
head_ref -> bytenr = bytenr ;
465
511
head_ref -> num_bytes = num_bytes ;
466
512
head_ref -> ref_mod = count_mod ;
@@ -470,7 +516,7 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref,
470
516
head_ref -> ref_tree = RB_ROOT ;
471
517
INIT_LIST_HEAD (& head_ref -> ref_add_list );
472
518
RB_CLEAR_NODE (& head_ref -> href_node );
473
- head_ref -> processing = 0 ;
519
+ head_ref -> processing = false ;
474
520
head_ref -> total_ref_mod = count_mod ;
475
521
}
476
522
@@ -546,7 +592,7 @@ static void init_delayed_ref_common(struct btrfs_fs_info *fs_info,
546
592
if (action == BTRFS_ADD_DELAYED_EXTENT )
547
593
action = BTRFS_ADD_DELAYED_REF ;
548
594
549
- ref -> refs = 1 ;
595
+ refcount_set ( & ref -> refs , 1 ) ;
550
596
ref -> bytenr = bytenr ;
551
597
ref -> num_bytes = num_bytes ;
552
598
ref -> ref_mod = 1 ;
@@ -642,3 +688,47 @@ void btrfs_destroy_delayed_refs(struct btrfs_trans_handle *trans)
642
688
ASSERT (cleanup_ref_head (trans , fs_info , head ) == 0 );
643
689
}
644
690
}
691
+
692
+ void __cold btrfs_delayed_ref_exit (void )
693
+ {
694
+ kmem_cache_destroy (btrfs_delayed_ref_head_cachep );
695
+ kmem_cache_destroy (btrfs_delayed_tree_ref_cachep );
696
+ kmem_cache_destroy (btrfs_delayed_data_ref_cachep );
697
+ kmem_cache_destroy (btrfs_delayed_extent_op_cachep );
698
+ }
699
+
700
+ int __init btrfs_delayed_ref_init (void )
701
+ {
702
+ btrfs_delayed_ref_head_cachep = kmem_cache_create (
703
+ "btrfs_delayed_ref_head" ,
704
+ sizeof (struct btrfs_delayed_ref_head ), 0 ,
705
+ SLAB_MEM_SPREAD , NULL );
706
+ if (!btrfs_delayed_ref_head_cachep )
707
+ goto fail ;
708
+
709
+ btrfs_delayed_tree_ref_cachep = kmem_cache_create (
710
+ "btrfs_delayed_tree_ref" ,
711
+ sizeof (struct btrfs_delayed_tree_ref ), 0 ,
712
+ SLAB_MEM_SPREAD , NULL );
713
+ if (!btrfs_delayed_tree_ref_cachep )
714
+ goto fail ;
715
+
716
+ btrfs_delayed_data_ref_cachep = kmem_cache_create (
717
+ "btrfs_delayed_data_ref" ,
718
+ sizeof (struct btrfs_delayed_data_ref ), 0 ,
719
+ SLAB_MEM_SPREAD , NULL );
720
+ if (!btrfs_delayed_data_ref_cachep )
721
+ goto fail ;
722
+
723
+ btrfs_delayed_extent_op_cachep = kmem_cache_create (
724
+ "btrfs_delayed_extent_op" ,
725
+ sizeof (struct btrfs_delayed_extent_op ), 0 ,
726
+ SLAB_MEM_SPREAD , NULL );
727
+ if (!btrfs_delayed_extent_op_cachep )
728
+ goto fail ;
729
+
730
+ return 0 ;
731
+ fail :
732
+ btrfs_delayed_ref_exit ();
733
+ return - ENOMEM ;
734
+ }
0 commit comments