diff options
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r-- | fs/btrfs/extent_map.c | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index f150188f621c..5b7dbcaacd11 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
@@ -19,8 +19,13 @@ struct kmem_cache *btrfs_cache_create(const char *name, size_t size, | |||
19 | static struct kmem_cache *extent_map_cache; | 19 | static struct kmem_cache *extent_map_cache; |
20 | static struct kmem_cache *extent_state_cache; | 20 | static struct kmem_cache *extent_state_cache; |
21 | static struct kmem_cache *extent_buffer_cache; | 21 | static struct kmem_cache *extent_buffer_cache; |
22 | |||
22 | static LIST_HEAD(extent_buffers); | 23 | static LIST_HEAD(extent_buffers); |
24 | static LIST_HEAD(buffers); | ||
25 | static LIST_HEAD(states); | ||
26 | |||
23 | static spinlock_t extent_buffers_lock; | 27 | static spinlock_t extent_buffers_lock; |
28 | static spinlock_t state_lock = SPIN_LOCK_UNLOCKED; | ||
24 | static int nr_extent_buffers; | 29 | static int nr_extent_buffers; |
25 | #define MAX_EXTENT_BUFFER_CACHE 128 | 30 | #define MAX_EXTENT_BUFFER_CACHE 128 |
26 | 31 | ||
@@ -48,6 +53,7 @@ void __init extent_map_init(void) | |||
48 | void __exit extent_map_exit(void) | 53 | void __exit extent_map_exit(void) |
49 | { | 54 | { |
50 | struct extent_buffer *eb; | 55 | struct extent_buffer *eb; |
56 | struct extent_state *state; | ||
51 | 57 | ||
52 | while (!list_empty(&extent_buffers)) { | 58 | while (!list_empty(&extent_buffers)) { |
53 | eb = list_entry(extent_buffers.next, | 59 | eb = list_entry(extent_buffers.next, |
@@ -55,6 +61,22 @@ void __exit extent_map_exit(void) | |||
55 | list_del(&eb->list); | 61 | list_del(&eb->list); |
56 | kmem_cache_free(extent_buffer_cache, eb); | 62 | kmem_cache_free(extent_buffer_cache, eb); |
57 | } | 63 | } |
64 | while (!list_empty(&states)) { | ||
65 | state = list_entry(states.next, struct extent_state, list); | ||
66 | printk("state leak: start %Lu end %Lu state %lu in tree %d refs %d\n", state->start, state->end, state->state, state->in_tree, atomic_read(&state->refs)); | ||
67 | list_del(&state->list); | ||
68 | kmem_cache_free(extent_state_cache, state); | ||
69 | |||
70 | } | ||
71 | while (!list_empty(&buffers)) { | ||
72 | eb = list_entry(buffers.next, | ||
73 | struct extent_buffer, leak_list); | ||
74 | printk("buffer leak start %Lu len %lu return %lX\n", eb->start, eb->len, eb->alloc_addr); | ||
75 | list_del(&eb->leak_list); | ||
76 | kmem_cache_free(extent_buffer_cache, eb); | ||
77 | } | ||
78 | |||
79 | |||
58 | if (extent_map_cache) | 80 | if (extent_map_cache) |
59 | kmem_cache_destroy(extent_map_cache); | 81 | kmem_cache_destroy(extent_map_cache); |
60 | if (extent_state_cache) | 82 | if (extent_state_cache) |
@@ -101,12 +123,19 @@ EXPORT_SYMBOL(free_extent_map); | |||
101 | struct extent_state *alloc_extent_state(gfp_t mask) | 123 | struct extent_state *alloc_extent_state(gfp_t mask) |
102 | { | 124 | { |
103 | struct extent_state *state; | 125 | struct extent_state *state; |
126 | unsigned long flags; | ||
127 | |||
104 | state = kmem_cache_alloc(extent_state_cache, mask); | 128 | state = kmem_cache_alloc(extent_state_cache, mask); |
105 | if (!state || IS_ERR(state)) | 129 | if (!state || IS_ERR(state)) |
106 | return state; | 130 | return state; |
107 | state->state = 0; | 131 | state->state = 0; |
108 | state->in_tree = 0; | 132 | state->in_tree = 0; |
109 | state->private = 0; | 133 | state->private = 0; |
134 | |||
135 | spin_lock_irqsave(&state_lock, flags); | ||
136 | list_add(&state->list, &states); | ||
137 | spin_unlock_irqrestore(&state_lock, flags); | ||
138 | |||
110 | atomic_set(&state->refs, 1); | 139 | atomic_set(&state->refs, 1); |
111 | init_waitqueue_head(&state->wq); | 140 | init_waitqueue_head(&state->wq); |
112 | return state; | 141 | return state; |
@@ -115,10 +144,14 @@ EXPORT_SYMBOL(alloc_extent_state); | |||
115 | 144 | ||
116 | void free_extent_state(struct extent_state *state) | 145 | void free_extent_state(struct extent_state *state) |
117 | { | 146 | { |
147 | unsigned long flags; | ||
118 | if (!state) | 148 | if (!state) |
119 | return; | 149 | return; |
120 | if (atomic_dec_and_test(&state->refs)) { | 150 | if (atomic_dec_and_test(&state->refs)) { |
121 | WARN_ON(state->in_tree); | 151 | WARN_ON(state->in_tree); |
152 | spin_lock_irqsave(&state_lock, flags); | ||
153 | list_del(&state->list); | ||
154 | spin_unlock_irqrestore(&state_lock, flags); | ||
122 | kmem_cache_free(extent_state_cache, state); | 155 | kmem_cache_free(extent_state_cache, state); |
123 | } | 156 | } |
124 | } | 157 | } |
@@ -361,10 +394,6 @@ static int insert_state(struct extent_map_tree *tree, | |||
361 | state->state |= bits; | 394 | state->state |= bits; |
362 | state->start = start; | 395 | state->start = start; |
363 | state->end = end; | 396 | state->end = end; |
364 | if ((end & 4095) == 0) { | ||
365 | printk("insert state %Lu %Lu strange end\n", start, end); | ||
366 | WARN_ON(1); | ||
367 | } | ||
368 | node = tree_insert(&tree->state, end, &state->rb_node); | 397 | node = tree_insert(&tree->state, end, &state->rb_node); |
369 | if (node) { | 398 | if (node) { |
370 | struct extent_state *found; | 399 | struct extent_state *found; |
@@ -399,11 +428,7 @@ static int split_state(struct extent_map_tree *tree, struct extent_state *orig, | |||
399 | prealloc->end = split - 1; | 428 | prealloc->end = split - 1; |
400 | prealloc->state = orig->state; | 429 | prealloc->state = orig->state; |
401 | orig->start = split; | 430 | orig->start = split; |
402 | if ((prealloc->end & 4095) == 0) { | 431 | |
403 | printk("insert state %Lu %Lu strange end\n", prealloc->start, | ||
404 | prealloc->end); | ||
405 | WARN_ON(1); | ||
406 | } | ||
407 | node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); | 432 | node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); |
408 | if (node) { | 433 | if (node) { |
409 | struct extent_state *found; | 434 | struct extent_state *found; |
@@ -957,6 +982,7 @@ int find_first_extent_bit(struct extent_map_tree *tree, u64 start, | |||
957 | *start_ret = state->start; | 982 | *start_ret = state->start; |
958 | *end_ret = state->end; | 983 | *end_ret = state->end; |
959 | ret = 0; | 984 | ret = 0; |
985 | break; | ||
960 | } | 986 | } |
961 | node = rb_next(node); | 987 | node = rb_next(node); |
962 | if (!node) | 988 | if (!node) |
@@ -1877,6 +1903,7 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock, | |||
1877 | static struct extent_buffer *__alloc_extent_buffer(gfp_t mask) | 1903 | static struct extent_buffer *__alloc_extent_buffer(gfp_t mask) |
1878 | { | 1904 | { |
1879 | struct extent_buffer *eb = NULL; | 1905 | struct extent_buffer *eb = NULL; |
1906 | |||
1880 | spin_lock(&extent_buffers_lock); | 1907 | spin_lock(&extent_buffers_lock); |
1881 | if (!list_empty(&extent_buffers)) { | 1908 | if (!list_empty(&extent_buffers)) { |
1882 | eb = list_entry(extent_buffers.next, struct extent_buffer, | 1909 | eb = list_entry(extent_buffers.next, struct extent_buffer, |
@@ -1886,15 +1913,26 @@ static struct extent_buffer *__alloc_extent_buffer(gfp_t mask) | |||
1886 | nr_extent_buffers--; | 1913 | nr_extent_buffers--; |
1887 | } | 1914 | } |
1888 | spin_unlock(&extent_buffers_lock); | 1915 | spin_unlock(&extent_buffers_lock); |
1916 | |||
1889 | if (eb) { | 1917 | if (eb) { |
1890 | memset(eb, 0, sizeof(*eb)); | 1918 | memset(eb, 0, sizeof(*eb)); |
1891 | return eb; | 1919 | } else { |
1920 | eb = kmem_cache_zalloc(extent_buffer_cache, mask); | ||
1892 | } | 1921 | } |
1893 | return kmem_cache_zalloc(extent_buffer_cache, mask); | 1922 | spin_lock(&extent_buffers_lock); |
1923 | list_add(&eb->leak_list, &buffers); | ||
1924 | spin_unlock(&extent_buffers_lock); | ||
1925 | |||
1926 | return eb; | ||
1894 | } | 1927 | } |
1895 | 1928 | ||
1896 | static void __free_extent_buffer(struct extent_buffer *eb) | 1929 | static void __free_extent_buffer(struct extent_buffer *eb) |
1897 | { | 1930 | { |
1931 | |||
1932 | spin_lock(&extent_buffers_lock); | ||
1933 | list_del_init(&eb->leak_list); | ||
1934 | spin_unlock(&extent_buffers_lock); | ||
1935 | |||
1898 | if (nr_extent_buffers >= MAX_EXTENT_BUFFER_CACHE) { | 1936 | if (nr_extent_buffers >= MAX_EXTENT_BUFFER_CACHE) { |
1899 | kmem_cache_free(extent_buffer_cache, eb); | 1937 | kmem_cache_free(extent_buffer_cache, eb); |
1900 | } else { | 1938 | } else { |
@@ -1933,6 +1971,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
1933 | if (!eb || IS_ERR(eb)) | 1971 | if (!eb || IS_ERR(eb)) |
1934 | return NULL; | 1972 | return NULL; |
1935 | 1973 | ||
1974 | eb->alloc_addr = __builtin_return_address(0); | ||
1936 | eb->start = start; | 1975 | eb->start = start; |
1937 | eb->len = len; | 1976 | eb->len = len; |
1938 | atomic_set(&eb->refs, 1); | 1977 | atomic_set(&eb->refs, 1); |
@@ -1947,6 +1986,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, | |||
1947 | eb->start &= ~((u64)PAGE_CACHE_SIZE - 1); | 1986 | eb->start &= ~((u64)PAGE_CACHE_SIZE - 1); |
1948 | goto fail; | 1987 | goto fail; |
1949 | } | 1988 | } |
1989 | set_page_extent_mapped(p); | ||
1950 | if (i == 0) | 1990 | if (i == 0) |
1951 | eb->first_page = p; | 1991 | eb->first_page = p; |
1952 | if (!PageUptodate(p)) | 1992 | if (!PageUptodate(p)) |
@@ -1978,6 +2018,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
1978 | if (!eb || IS_ERR(eb)) | 2018 | if (!eb || IS_ERR(eb)) |
1979 | return NULL; | 2019 | return NULL; |
1980 | 2020 | ||
2021 | eb->alloc_addr = __builtin_return_address(0); | ||
1981 | eb->start = start; | 2022 | eb->start = start; |
1982 | eb->len = len; | 2023 | eb->len = len; |
1983 | atomic_set(&eb->refs, 1); | 2024 | atomic_set(&eb->refs, 1); |
@@ -1992,6 +2033,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, | |||
1992 | eb->start &= ~((u64)PAGE_CACHE_SIZE - 1); | 2033 | eb->start &= ~((u64)PAGE_CACHE_SIZE - 1); |
1993 | goto fail; | 2034 | goto fail; |
1994 | } | 2035 | } |
2036 | set_page_extent_mapped(p); | ||
1995 | if (i == 0) | 2037 | if (i == 0) |
1996 | eb->first_page = p; | 2038 | eb->first_page = p; |
1997 | } | 2039 | } |