@@ -35,42 +35,45 @@ static inline bool extent_state_in_tree(const struct extent_state *state)
35
35
}
36
36
37
37
#ifdef CONFIG_BTRFS_DEBUG
38
- static LIST_HEAD (buffers );
39
38
static LIST_HEAD (states );
40
-
41
39
static DEFINE_SPINLOCK (leak_lock );
42
40
43
- static inline
44
- void btrfs_leak_debug_add (struct list_head * new , struct list_head * head )
41
+ static inline void btrfs_leak_debug_add (spinlock_t * lock ,
42
+ struct list_head * new ,
43
+ struct list_head * head )
45
44
{
46
45
unsigned long flags ;
47
46
48
- spin_lock_irqsave (& leak_lock , flags );
47
+ spin_lock_irqsave (lock , flags );
49
48
list_add (new , head );
50
- spin_unlock_irqrestore (& leak_lock , flags );
49
+ spin_unlock_irqrestore (lock , flags );
51
50
}
52
51
53
- static inline
54
- void btrfs_leak_debug_del ( struct list_head * entry )
52
+ static inline void btrfs_leak_debug_del ( spinlock_t * lock ,
53
+ struct list_head * entry )
55
54
{
56
55
unsigned long flags ;
57
56
58
- spin_lock_irqsave (& leak_lock , flags );
57
+ spin_lock_irqsave (lock , flags );
59
58
list_del (entry );
60
- spin_unlock_irqrestore (& leak_lock , flags );
59
+ spin_unlock_irqrestore (lock , flags );
61
60
}
62
61
63
- static inline void btrfs_extent_buffer_leak_debug_check (void )
62
+ void btrfs_extent_buffer_leak_debug_check (struct btrfs_fs_info * fs_info )
64
63
{
65
64
struct extent_buffer * eb ;
65
+ unsigned long flags ;
66
66
67
- while (!list_empty (& buffers )) {
68
- eb = list_entry (buffers .next , struct extent_buffer , leak_list );
67
+ spin_lock_irqsave (& fs_info -> eb_leak_lock , flags );
68
+ while (!list_empty (& fs_info -> allocated_ebs )) {
69
+ eb = list_first_entry (& fs_info -> allocated_ebs ,
70
+ struct extent_buffer , leak_list );
69
71
pr_err ("BTRFS: buffer leak start %llu len %lu refs %d bflags %lu\n" ,
70
72
eb -> start , eb -> len , atomic_read (& eb -> refs ), eb -> bflags );
71
73
list_del (& eb -> leak_list );
72
74
kmem_cache_free (extent_buffer_cache , eb );
73
75
}
76
+ spin_unlock_irqrestore (& fs_info -> eb_leak_lock , flags );
74
77
}
75
78
76
79
static inline void btrfs_extent_state_leak_debug_check (void )
@@ -107,9 +110,8 @@ static inline void __btrfs_debug_check_extent_io_range(const char *caller,
107
110
}
108
111
}
109
112
#else
110
- #define btrfs_leak_debug_add (new , head ) do {} while (0)
111
- #define btrfs_leak_debug_del (entry ) do {} while (0)
112
- #define btrfs_extent_buffer_leak_debug_check () do {} while (0)
113
+ #define btrfs_leak_debug_add (lock , new , head ) do {} while (0)
114
+ #define btrfs_leak_debug_del (lock , entry ) do {} while (0)
113
115
#define btrfs_extent_state_leak_debug_check () do {} while (0)
114
116
#define btrfs_debug_check_extent_io_range (c , s , e ) do {} while (0)
115
117
#endif
@@ -245,8 +247,6 @@ void __cold extent_state_cache_exit(void)
245
247
246
248
void __cold extent_io_exit (void )
247
249
{
248
- btrfs_extent_buffer_leak_debug_check ();
249
-
250
250
/*
251
251
* Make sure all delayed rcu free are flushed before we
252
252
* destroy caches.
@@ -324,7 +324,7 @@ static struct extent_state *alloc_extent_state(gfp_t mask)
324
324
state -> state = 0 ;
325
325
state -> failrec = NULL ;
326
326
RB_CLEAR_NODE (& state -> rb_node );
327
- btrfs_leak_debug_add (& state -> leak_list , & states );
327
+ btrfs_leak_debug_add (& leak_lock , & state -> leak_list , & states );
328
328
refcount_set (& state -> refs , 1 );
329
329
init_waitqueue_head (& state -> wq );
330
330
trace_alloc_extent_state (state , mask , _RET_IP_ );
@@ -337,7 +337,7 @@ void free_extent_state(struct extent_state *state)
337
337
return ;
338
338
if (refcount_dec_and_test (& state -> refs )) {
339
339
WARN_ON (extent_state_in_tree (state ));
340
- btrfs_leak_debug_del (& state -> leak_list );
340
+ btrfs_leak_debug_del (& leak_lock , & state -> leak_list );
341
341
trace_free_extent_state (state , _RET_IP_ );
342
342
kmem_cache_free (extent_state_cache , state );
343
343
}
@@ -4875,7 +4875,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
4875
4875
4876
4876
static void __free_extent_buffer (struct extent_buffer * eb )
4877
4877
{
4878
- btrfs_leak_debug_del (& eb -> leak_list );
4878
+ btrfs_leak_debug_del (& eb -> fs_info -> eb_leak_lock , & eb -> leak_list );
4879
4879
kmem_cache_free (extent_buffer_cache , eb );
4880
4880
}
4881
4881
@@ -4962,7 +4962,8 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start,
4962
4962
init_waitqueue_head (& eb -> write_lock_wq );
4963
4963
init_waitqueue_head (& eb -> read_lock_wq );
4964
4964
4965
- btrfs_leak_debug_add (& eb -> leak_list , & buffers );
4965
+ btrfs_leak_debug_add (& fs_info -> eb_leak_lock , & eb -> leak_list ,
4966
+ & fs_info -> allocated_ebs );
4966
4967
4967
4968
spin_lock_init (& eb -> refs_lock );
4968
4969
atomic_set (& eb -> refs , 1 );
0 commit comments