1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0
2dc11dd5dSJosef Bacik /*
3dc11dd5dSJosef Bacik * Copyright (C) 2013 Fusion IO. All rights reserved.
4dc11dd5dSJosef Bacik */
5dc11dd5dSJosef Bacik
6dc11dd5dSJosef Bacik #include <linux/slab.h>
7dc11dd5dSJosef Bacik #include "btrfs-tests.h"
8dc11dd5dSJosef Bacik #include "../ctree.h"
9d0bd4560SJosef Bacik #include "../disk-io.h"
10dc11dd5dSJosef Bacik #include "../free-space-cache.h"
11aac0023cSJosef Bacik #include "../block-group.h"
12dc11dd5dSJosef Bacik
130ef6447aSFeifei Xu #define BITS_PER_BITMAP (PAGE_SIZE * 8UL)
14dc11dd5dSJosef Bacik
15dc11dd5dSJosef Bacik /*
1601327610SNicholas D Steeves * This test just does basic sanity checking, making sure we can add an extent
17dc11dd5dSJosef Bacik * entry and remove space from either end and the middle, and make sure we can
18dc11dd5dSJosef Bacik * remove space that covers adjacent extent entries.
19dc11dd5dSJosef Bacik */
test_extents(struct btrfs_block_group * cache)2032da5386SDavid Sterba static int test_extents(struct btrfs_block_group *cache)
21dc11dd5dSJosef Bacik {
22dc11dd5dSJosef Bacik int ret = 0;
23dc11dd5dSJosef Bacik
24315b76b4SDavid Sterba test_msg("running extent only tests");
25dc11dd5dSJosef Bacik
26dc11dd5dSJosef Bacik /* First just make sure we can remove an entire entry */
27ee22184bSByongho Lee ret = btrfs_add_free_space(cache, 0, SZ_4M);
28dc11dd5dSJosef Bacik if (ret) {
293c7251f2SDavid Sterba test_err("error adding initial extents %d", ret);
30dc11dd5dSJosef Bacik return ret;
31dc11dd5dSJosef Bacik }
32dc11dd5dSJosef Bacik
33ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_4M);
34dc11dd5dSJosef Bacik if (ret) {
353c7251f2SDavid Sterba test_err("error removing extent %d", ret);
36dc11dd5dSJosef Bacik return ret;
37dc11dd5dSJosef Bacik }
38dc11dd5dSJosef Bacik
39ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_4M)) {
403c7251f2SDavid Sterba test_err("full remove left some lingering space");
41dc11dd5dSJosef Bacik return -1;
42dc11dd5dSJosef Bacik }
43dc11dd5dSJosef Bacik
44dc11dd5dSJosef Bacik /* Ok edge and middle cases now */
45ee22184bSByongho Lee ret = btrfs_add_free_space(cache, 0, SZ_4M);
46dc11dd5dSJosef Bacik if (ret) {
473c7251f2SDavid Sterba test_err("error adding half extent %d", ret);
48dc11dd5dSJosef Bacik return ret;
49dc11dd5dSJosef Bacik }
50dc11dd5dSJosef Bacik
51ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 3 * SZ_1M, SZ_1M);
52dc11dd5dSJosef Bacik if (ret) {
533c7251f2SDavid Sterba test_err("error removing tail end %d", ret);
54dc11dd5dSJosef Bacik return ret;
55dc11dd5dSJosef Bacik }
56dc11dd5dSJosef Bacik
57ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_1M);
58dc11dd5dSJosef Bacik if (ret) {
593c7251f2SDavid Sterba test_err("error removing front end %d", ret);
60dc11dd5dSJosef Bacik return ret;
61dc11dd5dSJosef Bacik }
62dc11dd5dSJosef Bacik
63ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_2M, 4096);
64dc11dd5dSJosef Bacik if (ret) {
653c7251f2SDavid Sterba test_err("error removing middle piece %d", ret);
66dc11dd5dSJosef Bacik return ret;
67dc11dd5dSJosef Bacik }
68dc11dd5dSJosef Bacik
69ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_1M)) {
703c7251f2SDavid Sterba test_err("still have space at the front");
71dc11dd5dSJosef Bacik return -1;
72dc11dd5dSJosef Bacik }
73dc11dd5dSJosef Bacik
74ee22184bSByongho Lee if (test_check_exists(cache, SZ_2M, 4096)) {
753c7251f2SDavid Sterba test_err("still have space in the middle");
76dc11dd5dSJosef Bacik return -1;
77dc11dd5dSJosef Bacik }
78dc11dd5dSJosef Bacik
79ee22184bSByongho Lee if (test_check_exists(cache, 3 * SZ_1M, SZ_1M)) {
803c7251f2SDavid Sterba test_err("still have space at the end");
81dc11dd5dSJosef Bacik return -1;
82dc11dd5dSJosef Bacik }
83dc11dd5dSJosef Bacik
84dc11dd5dSJosef Bacik /* Cleanup */
85*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
86dc11dd5dSJosef Bacik
87dc11dd5dSJosef Bacik return 0;
88dc11dd5dSJosef Bacik }
89dc11dd5dSJosef Bacik
test_bitmaps(struct btrfs_block_group * cache,u32 sectorsize)9032da5386SDavid Sterba static int test_bitmaps(struct btrfs_block_group *cache, u32 sectorsize)
91dc11dd5dSJosef Bacik {
92dc11dd5dSJosef Bacik u64 next_bitmap_offset;
93dc11dd5dSJosef Bacik int ret;
94dc11dd5dSJosef Bacik
95315b76b4SDavid Sterba test_msg("running bitmap only tests");
96dc11dd5dSJosef Bacik
97ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_4M, 1);
98dc11dd5dSJosef Bacik if (ret) {
993c7251f2SDavid Sterba test_err("couldn't create a bitmap entry %d", ret);
100dc11dd5dSJosef Bacik return ret;
101dc11dd5dSJosef Bacik }
102dc11dd5dSJosef Bacik
103ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_4M);
104dc11dd5dSJosef Bacik if (ret) {
1053c7251f2SDavid Sterba test_err("error removing bitmap full range %d", ret);
106dc11dd5dSJosef Bacik return ret;
107dc11dd5dSJosef Bacik }
108dc11dd5dSJosef Bacik
109ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_4M)) {
1103c7251f2SDavid Sterba test_err("left some space in bitmap");
111dc11dd5dSJosef Bacik return -1;
112dc11dd5dSJosef Bacik }
113dc11dd5dSJosef Bacik
114ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_4M, 1);
115dc11dd5dSJosef Bacik if (ret) {
1163c7251f2SDavid Sterba test_err("couldn't add to our bitmap entry %d", ret);
117dc11dd5dSJosef Bacik return ret;
118dc11dd5dSJosef Bacik }
119dc11dd5dSJosef Bacik
120ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_1M, SZ_2M);
121dc11dd5dSJosef Bacik if (ret) {
1223c7251f2SDavid Sterba test_err("couldn't remove middle chunk %d", ret);
123dc11dd5dSJosef Bacik return ret;
124dc11dd5dSJosef Bacik }
125dc11dd5dSJosef Bacik
126dc11dd5dSJosef Bacik /*
127dc11dd5dSJosef Bacik * The first bitmap we have starts at offset 0 so the next one is just
128dc11dd5dSJosef Bacik * at the end of the first bitmap.
129dc11dd5dSJosef Bacik */
130b9ef22deSFeifei Xu next_bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize);
131dc11dd5dSJosef Bacik
132dc11dd5dSJosef Bacik /* Test a bit straddling two bitmaps */
133ee22184bSByongho Lee ret = test_add_free_space_entry(cache, next_bitmap_offset - SZ_2M,
134ee22184bSByongho Lee SZ_4M, 1);
135dc11dd5dSJosef Bacik if (ret) {
1363c7251f2SDavid Sterba test_err("couldn't add space that straddles two bitmaps %d",
137dc11dd5dSJosef Bacik ret);
138dc11dd5dSJosef Bacik return ret;
139dc11dd5dSJosef Bacik }
140dc11dd5dSJosef Bacik
141ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, next_bitmap_offset - SZ_1M, SZ_2M);
142dc11dd5dSJosef Bacik if (ret) {
1433c7251f2SDavid Sterba test_err("couldn't remove overlapping space %d", ret);
144dc11dd5dSJosef Bacik return ret;
145dc11dd5dSJosef Bacik }
146dc11dd5dSJosef Bacik
147ee22184bSByongho Lee if (test_check_exists(cache, next_bitmap_offset - SZ_1M, SZ_2M)) {
1483c7251f2SDavid Sterba test_err("left some space when removing overlapping");
149dc11dd5dSJosef Bacik return -1;
150dc11dd5dSJosef Bacik }
151dc11dd5dSJosef Bacik
152*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
153dc11dd5dSJosef Bacik
154dc11dd5dSJosef Bacik return 0;
155dc11dd5dSJosef Bacik }
156dc11dd5dSJosef Bacik
157dc11dd5dSJosef Bacik /* This is the high grade jackassery */
test_bitmaps_and_extents(struct btrfs_block_group * cache,u32 sectorsize)15832da5386SDavid Sterba static int test_bitmaps_and_extents(struct btrfs_block_group *cache,
159b9ef22deSFeifei Xu u32 sectorsize)
160dc11dd5dSJosef Bacik {
161b9ef22deSFeifei Xu u64 bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize);
162dc11dd5dSJosef Bacik int ret;
163dc11dd5dSJosef Bacik
164315b76b4SDavid Sterba test_msg("running bitmap and extent tests");
165dc11dd5dSJosef Bacik
166dc11dd5dSJosef Bacik /*
167dc11dd5dSJosef Bacik * First let's do something simple, an extent at the same offset as the
168dc11dd5dSJosef Bacik * bitmap, but the free space completely in the extent and then
169dc11dd5dSJosef Bacik * completely in the bitmap.
170dc11dd5dSJosef Bacik */
171ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_4M, SZ_1M, 1);
172dc11dd5dSJosef Bacik if (ret) {
1733c7251f2SDavid Sterba test_err("couldn't create bitmap entry %d", ret);
174dc11dd5dSJosef Bacik return ret;
175dc11dd5dSJosef Bacik }
176dc11dd5dSJosef Bacik
177ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_1M, 0);
178dc11dd5dSJosef Bacik if (ret) {
1793c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret);
180dc11dd5dSJosef Bacik return ret;
181dc11dd5dSJosef Bacik }
182dc11dd5dSJosef Bacik
183ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_1M);
184dc11dd5dSJosef Bacik if (ret) {
1853c7251f2SDavid Sterba test_err("couldn't remove extent entry %d", ret);
186dc11dd5dSJosef Bacik return ret;
187dc11dd5dSJosef Bacik }
188dc11dd5dSJosef Bacik
189ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_1M)) {
1903c7251f2SDavid Sterba test_err("left remnants after our remove");
191dc11dd5dSJosef Bacik return -1;
192dc11dd5dSJosef Bacik }
193dc11dd5dSJosef Bacik
194dc11dd5dSJosef Bacik /* Now to add back the extent entry and remove from the bitmap */
195ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_1M, 0);
196dc11dd5dSJosef Bacik if (ret) {
1973c7251f2SDavid Sterba test_err("couldn't re-add extent entry %d", ret);
198dc11dd5dSJosef Bacik return ret;
199dc11dd5dSJosef Bacik }
200dc11dd5dSJosef Bacik
201ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_4M, SZ_1M);
202dc11dd5dSJosef Bacik if (ret) {
2033c7251f2SDavid Sterba test_err("couldn't remove from bitmap %d", ret);
204dc11dd5dSJosef Bacik return ret;
205dc11dd5dSJosef Bacik }
206dc11dd5dSJosef Bacik
207ee22184bSByongho Lee if (test_check_exists(cache, SZ_4M, SZ_1M)) {
2083c7251f2SDavid Sterba test_err("left remnants in the bitmap");
209dc11dd5dSJosef Bacik return -1;
210dc11dd5dSJosef Bacik }
211dc11dd5dSJosef Bacik
212dc11dd5dSJosef Bacik /*
213dc11dd5dSJosef Bacik * Ok so a little more evil, extent entry and bitmap at the same offset,
214dc11dd5dSJosef Bacik * removing an overlapping chunk.
215dc11dd5dSJosef Bacik */
216ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_1M, SZ_4M, 1);
217dc11dd5dSJosef Bacik if (ret) {
2183c7251f2SDavid Sterba test_err("couldn't add to a bitmap %d", ret);
219dc11dd5dSJosef Bacik return ret;
220dc11dd5dSJosef Bacik }
221dc11dd5dSJosef Bacik
222ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_512K, 3 * SZ_1M);
223dc11dd5dSJosef Bacik if (ret) {
2243c7251f2SDavid Sterba test_err("couldn't remove overlapping space %d", ret);
225dc11dd5dSJosef Bacik return ret;
226dc11dd5dSJosef Bacik }
227dc11dd5dSJosef Bacik
228ee22184bSByongho Lee if (test_check_exists(cache, SZ_512K, 3 * SZ_1M)) {
2293c7251f2SDavid Sterba test_err("left over pieces after removing overlapping");
230dc11dd5dSJosef Bacik return -1;
231dc11dd5dSJosef Bacik }
232dc11dd5dSJosef Bacik
233*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
234dc11dd5dSJosef Bacik
235dc11dd5dSJosef Bacik /* Now with the extent entry offset into the bitmap */
236ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_4M, SZ_4M, 1);
237dc11dd5dSJosef Bacik if (ret) {
2383c7251f2SDavid Sterba test_err("couldn't add space to the bitmap %d", ret);
239dc11dd5dSJosef Bacik return ret;
240dc11dd5dSJosef Bacik }
241dc11dd5dSJosef Bacik
242ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_2M, SZ_2M, 0);
243dc11dd5dSJosef Bacik if (ret) {
2443c7251f2SDavid Sterba test_err("couldn't add extent to the cache %d", ret);
245dc11dd5dSJosef Bacik return ret;
246dc11dd5dSJosef Bacik }
247dc11dd5dSJosef Bacik
248ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 3 * SZ_1M, SZ_4M);
249dc11dd5dSJosef Bacik if (ret) {
2503c7251f2SDavid Sterba test_err("problem removing overlapping space %d", ret);
251dc11dd5dSJosef Bacik return ret;
252dc11dd5dSJosef Bacik }
253dc11dd5dSJosef Bacik
254ee22184bSByongho Lee if (test_check_exists(cache, 3 * SZ_1M, SZ_4M)) {
2553c7251f2SDavid Sterba test_err("left something behind when removing space");
256dc11dd5dSJosef Bacik return -1;
257dc11dd5dSJosef Bacik }
258dc11dd5dSJosef Bacik
259dc11dd5dSJosef Bacik /*
260dc11dd5dSJosef Bacik * This has blown up in the past, the extent entry starts before the
261dc11dd5dSJosef Bacik * bitmap entry, but we're trying to remove an offset that falls
262dc11dd5dSJosef Bacik * completely within the bitmap range and is in both the extent entry
263dc11dd5dSJosef Bacik * and the bitmap entry, looks like this
264dc11dd5dSJosef Bacik *
265dc11dd5dSJosef Bacik * [ extent ]
266dc11dd5dSJosef Bacik * [ bitmap ]
267dc11dd5dSJosef Bacik * [ del ]
268dc11dd5dSJosef Bacik */
269*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
270ee22184bSByongho Lee ret = test_add_free_space_entry(cache, bitmap_offset + SZ_4M, SZ_4M, 1);
271dc11dd5dSJosef Bacik if (ret) {
2723c7251f2SDavid Sterba test_err("couldn't add bitmap %d", ret);
273dc11dd5dSJosef Bacik return ret;
274dc11dd5dSJosef Bacik }
275dc11dd5dSJosef Bacik
276ee22184bSByongho Lee ret = test_add_free_space_entry(cache, bitmap_offset - SZ_1M,
277ee22184bSByongho Lee 5 * SZ_1M, 0);
278dc11dd5dSJosef Bacik if (ret) {
2793c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret);
280dc11dd5dSJosef Bacik return ret;
281dc11dd5dSJosef Bacik }
282dc11dd5dSJosef Bacik
283ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, bitmap_offset + SZ_1M, 5 * SZ_1M);
284dc11dd5dSJosef Bacik if (ret) {
2853c7251f2SDavid Sterba test_err("failed to free our space %d", ret);
286dc11dd5dSJosef Bacik return ret;
287dc11dd5dSJosef Bacik }
288dc11dd5dSJosef Bacik
289ee22184bSByongho Lee if (test_check_exists(cache, bitmap_offset + SZ_1M, 5 * SZ_1M)) {
2903c7251f2SDavid Sterba test_err("left stuff over");
291dc11dd5dSJosef Bacik return -1;
292dc11dd5dSJosef Bacik }
293dc11dd5dSJosef Bacik
294*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
295dc11dd5dSJosef Bacik
296dc11dd5dSJosef Bacik /*
297dc11dd5dSJosef Bacik * This blew up before, we have part of the free space in a bitmap and
298dc11dd5dSJosef Bacik * then the entirety of the rest of the space in an extent. This used
299dc11dd5dSJosef Bacik * to return -EAGAIN back from btrfs_remove_extent, make sure this
300dc11dd5dSJosef Bacik * doesn't happen.
301dc11dd5dSJosef Bacik */
302ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_1M, SZ_2M, 1);
303dc11dd5dSJosef Bacik if (ret) {
3043c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret);
305dc11dd5dSJosef Bacik return ret;
306dc11dd5dSJosef Bacik }
307dc11dd5dSJosef Bacik
308ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 3 * SZ_1M, SZ_1M, 0);
309dc11dd5dSJosef Bacik if (ret) {
3103c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret);
311dc11dd5dSJosef Bacik return ret;
312dc11dd5dSJosef Bacik }
313dc11dd5dSJosef Bacik
314ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, SZ_1M, 3 * SZ_1M);
315dc11dd5dSJosef Bacik if (ret) {
3163c7251f2SDavid Sterba test_err("error removing bitmap and extent overlapping %d", ret);
317dc11dd5dSJosef Bacik return ret;
318dc11dd5dSJosef Bacik }
319dc11dd5dSJosef Bacik
320*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
321dc11dd5dSJosef Bacik return 0;
322dc11dd5dSJosef Bacik }
323dc11dd5dSJosef Bacik
32420005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */
test_use_bitmap(struct btrfs_free_space_ctl * ctl,struct btrfs_free_space * info)32520005523SFilipe Manana static bool test_use_bitmap(struct btrfs_free_space_ctl *ctl,
32620005523SFilipe Manana struct btrfs_free_space *info)
32720005523SFilipe Manana {
32820005523SFilipe Manana return ctl->free_extents > 0;
32920005523SFilipe Manana }
33020005523SFilipe Manana
33120005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */
33220005523SFilipe Manana static int
check_num_extents_and_bitmaps(const struct btrfs_block_group * cache,const int num_extents,const int num_bitmaps)33332da5386SDavid Sterba check_num_extents_and_bitmaps(const struct btrfs_block_group *cache,
33420005523SFilipe Manana const int num_extents,
33520005523SFilipe Manana const int num_bitmaps)
33620005523SFilipe Manana {
33720005523SFilipe Manana if (cache->free_space_ctl->free_extents != num_extents) {
3383c7251f2SDavid Sterba test_err(
3393c7251f2SDavid Sterba "incorrect # of extent entries in the cache: %d, expected %d",
34020005523SFilipe Manana cache->free_space_ctl->free_extents, num_extents);
34120005523SFilipe Manana return -EINVAL;
34220005523SFilipe Manana }
34320005523SFilipe Manana if (cache->free_space_ctl->total_bitmaps != num_bitmaps) {
3443c7251f2SDavid Sterba test_err(
3453c7251f2SDavid Sterba "incorrect # of extent entries in the cache: %d, expected %d",
34620005523SFilipe Manana cache->free_space_ctl->total_bitmaps, num_bitmaps);
34720005523SFilipe Manana return -EINVAL;
34820005523SFilipe Manana }
34920005523SFilipe Manana return 0;
35020005523SFilipe Manana }
35120005523SFilipe Manana
35220005523SFilipe Manana /* Used by test_steal_space_from_bitmap_to_extent(). */
check_cache_empty(struct btrfs_block_group * cache)35332da5386SDavid Sterba static int check_cache_empty(struct btrfs_block_group *cache)
35420005523SFilipe Manana {
35520005523SFilipe Manana u64 offset;
35620005523SFilipe Manana u64 max_extent_size;
35720005523SFilipe Manana
35820005523SFilipe Manana /*
35920005523SFilipe Manana * Now lets confirm that there's absolutely no free space left to
36020005523SFilipe Manana * allocate.
36120005523SFilipe Manana */
36220005523SFilipe Manana if (cache->free_space_ctl->free_space != 0) {
3633c7251f2SDavid Sterba test_err("cache free space is not 0");
36420005523SFilipe Manana return -EINVAL;
36520005523SFilipe Manana }
36620005523SFilipe Manana
36720005523SFilipe Manana /* And any allocation request, no matter how small, should fail now. */
36820005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache, 0, 4096, 0,
36920005523SFilipe Manana &max_extent_size);
37020005523SFilipe Manana if (offset != 0) {
3713c7251f2SDavid Sterba test_err("space allocation did not fail, returned offset: %llu",
37220005523SFilipe Manana offset);
37320005523SFilipe Manana return -EINVAL;
37420005523SFilipe Manana }
37520005523SFilipe Manana
37620005523SFilipe Manana /* And no extent nor bitmap entries in the cache anymore. */
37720005523SFilipe Manana return check_num_extents_and_bitmaps(cache, 0, 0);
37820005523SFilipe Manana }
37920005523SFilipe Manana
38020005523SFilipe Manana /*
38120005523SFilipe Manana * Before we were able to steal free space from a bitmap entry to an extent
38220005523SFilipe Manana * entry, we could end up with 2 entries representing a contiguous free space.
38320005523SFilipe Manana * One would be an extent entry and the other a bitmap entry. Since in order
38420005523SFilipe Manana * to allocate space to a caller we use only 1 entry, we couldn't return that
38520005523SFilipe Manana * whole range to the caller if it was requested. This forced the caller to
38620005523SFilipe Manana * either assume ENOSPC or perform several smaller space allocations, which
38720005523SFilipe Manana * wasn't optimal as they could be spread all over the block group while under
38820005523SFilipe Manana * concurrency (extra overhead and fragmentation).
38920005523SFilipe Manana *
39001327610SNicholas D Steeves * This stealing approach is beneficial, since we always prefer to allocate
39101327610SNicholas D Steeves * from extent entries, both for clustered and non-clustered allocation
39201327610SNicholas D Steeves * requests.
39320005523SFilipe Manana */
39420005523SFilipe Manana static int
test_steal_space_from_bitmap_to_extent(struct btrfs_block_group * cache,u32 sectorsize)39532da5386SDavid Sterba test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache,
396b9ef22deSFeifei Xu u32 sectorsize)
39720005523SFilipe Manana {
39820005523SFilipe Manana int ret;
39920005523SFilipe Manana u64 offset;
40020005523SFilipe Manana u64 max_extent_size;
40120e5506bSDavid Sterba const struct btrfs_free_space_op test_free_space_ops = {
40228f0779aSDavid Sterba .use_bitmap = test_use_bitmap,
40328f0779aSDavid Sterba };
40420e5506bSDavid Sterba const struct btrfs_free_space_op *orig_free_space_ops;
40520005523SFilipe Manana
406e4fa7469SDavid Sterba test_msg("running space stealing from bitmap to extent tests");
40720005523SFilipe Manana
40820005523SFilipe Manana /*
40920005523SFilipe Manana * For this test, we want to ensure we end up with an extent entry
41020005523SFilipe Manana * immediately adjacent to a bitmap entry, where the bitmap starts
41120005523SFilipe Manana * at an offset where the extent entry ends. We keep adding and
41220005523SFilipe Manana * removing free space to reach into this state, but to get there
41320005523SFilipe Manana * we need to reach a point where marking new free space doesn't
41420005523SFilipe Manana * result in adding new extent entries or merging the new space
41520005523SFilipe Manana * with existing extent entries - the space ends up being marked
41620005523SFilipe Manana * in an existing bitmap that covers the new free space range.
41720005523SFilipe Manana *
41820005523SFilipe Manana * To get there, we need to reach the threshold defined set at
41920005523SFilipe Manana * cache->free_space_ctl->extents_thresh, which currently is
42020005523SFilipe Manana * 256 extents on a x86_64 system at least, and a few other
42120005523SFilipe Manana * conditions (check free_space_cache.c). Instead of making the
42220005523SFilipe Manana * test much longer and complicated, use a "use_bitmap" operation
42320005523SFilipe Manana * that forces use of bitmaps as soon as we have at least 1
42420005523SFilipe Manana * extent entry.
42520005523SFilipe Manana */
42628f0779aSDavid Sterba orig_free_space_ops = cache->free_space_ctl->op;
42728f0779aSDavid Sterba cache->free_space_ctl->op = &test_free_space_ops;
42820005523SFilipe Manana
42920005523SFilipe Manana /*
43020005523SFilipe Manana * Extent entry covering free space range [128Mb - 256Kb, 128Mb - 128Kb[
43120005523SFilipe Manana */
432ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M - SZ_256K, SZ_128K, 0);
43320005523SFilipe Manana if (ret) {
4343c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret);
43520005523SFilipe Manana return ret;
43620005523SFilipe Manana }
43720005523SFilipe Manana
43820005523SFilipe Manana /* Bitmap entry covering free space range [128Mb + 512Kb, 256Mb[ */
439ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M + SZ_512K,
440ee22184bSByongho Lee SZ_128M - SZ_512K, 1);
44120005523SFilipe Manana if (ret) {
4423c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret);
44320005523SFilipe Manana return ret;
44420005523SFilipe Manana }
44520005523SFilipe Manana
44620005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
44720005523SFilipe Manana if (ret)
44820005523SFilipe Manana return ret;
44920005523SFilipe Manana
45020005523SFilipe Manana /*
45120005523SFilipe Manana * Now make only the first 256Kb of the bitmap marked as free, so that
45220005523SFilipe Manana * we end up with only the following ranges marked as free space:
45320005523SFilipe Manana *
45420005523SFilipe Manana * [128Mb - 256Kb, 128Mb - 128Kb[
45520005523SFilipe Manana * [128Mb + 512Kb, 128Mb + 768Kb[
45620005523SFilipe Manana */
45720005523SFilipe Manana ret = btrfs_remove_free_space(cache,
458ee22184bSByongho Lee SZ_128M + 768 * SZ_1K,
459ee22184bSByongho Lee SZ_128M - 768 * SZ_1K);
46020005523SFilipe Manana if (ret) {
4613c7251f2SDavid Sterba test_err("failed to free part of bitmap space %d", ret);
46220005523SFilipe Manana return ret;
46320005523SFilipe Manana }
46420005523SFilipe Manana
46520005523SFilipe Manana /* Confirm that only those 2 ranges are marked as free. */
466ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_256K, SZ_128K)) {
4673c7251f2SDavid Sterba test_err("free space range missing");
46820005523SFilipe Manana return -ENOENT;
46920005523SFilipe Manana }
470ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M + SZ_512K, SZ_256K)) {
4713c7251f2SDavid Sterba test_err("free space range missing");
47220005523SFilipe Manana return -ENOENT;
47320005523SFilipe Manana }
47420005523SFilipe Manana
47520005523SFilipe Manana /*
47620005523SFilipe Manana * Confirm that the bitmap range [128Mb + 768Kb, 256Mb[ isn't marked
47720005523SFilipe Manana * as free anymore.
47820005523SFilipe Manana */
479ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M + 768 * SZ_1K,
480ee22184bSByongho Lee SZ_128M - 768 * SZ_1K)) {
4813c7251f2SDavid Sterba test_err("bitmap region not removed from space cache");
48220005523SFilipe Manana return -EINVAL;
48320005523SFilipe Manana }
48420005523SFilipe Manana
48520005523SFilipe Manana /*
48620005523SFilipe Manana * Confirm that the region [128Mb + 256Kb, 128Mb + 512Kb[, which is
48720005523SFilipe Manana * covered by the bitmap, isn't marked as free.
48820005523SFilipe Manana */
489ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M + SZ_256K, SZ_256K)) {
4903c7251f2SDavid Sterba test_err("invalid bitmap region marked as free");
49120005523SFilipe Manana return -EINVAL;
49220005523SFilipe Manana }
49320005523SFilipe Manana
49420005523SFilipe Manana /*
49520005523SFilipe Manana * Confirm that the region [128Mb, 128Mb + 256Kb[, which is covered
49620005523SFilipe Manana * by the bitmap too, isn't marked as free either.
49720005523SFilipe Manana */
498ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M, SZ_256K)) {
4993c7251f2SDavid Sterba test_err("invalid bitmap region marked as free");
50020005523SFilipe Manana return -EINVAL;
50120005523SFilipe Manana }
50220005523SFilipe Manana
50320005523SFilipe Manana /*
50420005523SFilipe Manana * Now lets mark the region [128Mb, 128Mb + 512Kb[ as free too. But,
50520005523SFilipe Manana * lets make sure the free space cache marks it as free in the bitmap,
50620005523SFilipe Manana * and doesn't insert a new extent entry to represent this region.
50720005523SFilipe Manana */
508ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M, SZ_512K);
50920005523SFilipe Manana if (ret) {
5103c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
51120005523SFilipe Manana return ret;
51220005523SFilipe Manana }
51320005523SFilipe Manana /* Confirm the region is marked as free. */
514ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M, SZ_512K)) {
5153c7251f2SDavid Sterba test_err("bitmap region not marked as free");
51620005523SFilipe Manana return -ENOENT;
51720005523SFilipe Manana }
51820005523SFilipe Manana
51920005523SFilipe Manana /*
52020005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to
52120005523SFilipe Manana * the cache after adding that free space region.
52220005523SFilipe Manana */
52320005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
52420005523SFilipe Manana if (ret)
52520005523SFilipe Manana return ret;
52620005523SFilipe Manana
52720005523SFilipe Manana /*
52820005523SFilipe Manana * Now lets add a small free space region to the right of the previous
52920005523SFilipe Manana * one, which is not contiguous with it and is part of the bitmap too.
53020005523SFilipe Manana * The goal is to test that the bitmap entry space stealing doesn't
53120005523SFilipe Manana * steal this space region.
53220005523SFilipe Manana */
533b9ef22deSFeifei Xu ret = btrfs_add_free_space(cache, SZ_128M + SZ_16M, sectorsize);
53420005523SFilipe Manana if (ret) {
5353c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
53620005523SFilipe Manana return ret;
53720005523SFilipe Manana }
53820005523SFilipe Manana
53920005523SFilipe Manana /*
54020005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to
54120005523SFilipe Manana * the cache after adding that free space region.
54220005523SFilipe Manana */
54320005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
54420005523SFilipe Manana if (ret)
54520005523SFilipe Manana return ret;
54620005523SFilipe Manana
54720005523SFilipe Manana /*
54820005523SFilipe Manana * Now mark the region [128Mb - 128Kb, 128Mb[ as free too. This will
54920005523SFilipe Manana * expand the range covered by the existing extent entry that represents
55020005523SFilipe Manana * the free space [128Mb - 256Kb, 128Mb - 128Kb[.
55120005523SFilipe Manana */
552ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M - SZ_128K, SZ_128K);
55320005523SFilipe Manana if (ret) {
5543c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
55520005523SFilipe Manana return ret;
55620005523SFilipe Manana }
55720005523SFilipe Manana /* Confirm the region is marked as free. */
558ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_128K, SZ_128K)) {
5593c7251f2SDavid Sterba test_err("extent region not marked as free");
56020005523SFilipe Manana return -ENOENT;
56120005523SFilipe Manana }
56220005523SFilipe Manana
56320005523SFilipe Manana /*
56420005523SFilipe Manana * Confirm that our extent entry didn't stole all free space from the
56520005523SFilipe Manana * bitmap, because of the small 4Kb free space region.
56620005523SFilipe Manana */
56720005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
56820005523SFilipe Manana if (ret)
56920005523SFilipe Manana return ret;
57020005523SFilipe Manana
57120005523SFilipe Manana /*
57220005523SFilipe Manana * So now we have the range [128Mb - 256Kb, 128Mb + 768Kb[ as free
57320005523SFilipe Manana * space. Without stealing bitmap free space into extent entry space,
57420005523SFilipe Manana * we would have all this free space represented by 2 entries in the
57520005523SFilipe Manana * cache:
57620005523SFilipe Manana *
57720005523SFilipe Manana * extent entry covering range: [128Mb - 256Kb, 128Mb[
57820005523SFilipe Manana * bitmap entry covering range: [128Mb, 128Mb + 768Kb[
57920005523SFilipe Manana *
58020005523SFilipe Manana * Attempting to allocate the whole free space (1Mb) would fail, because
58120005523SFilipe Manana * we can't allocate from multiple entries.
58220005523SFilipe Manana * With the bitmap free space stealing, we get a single extent entry
58320005523SFilipe Manana * that represents the 1Mb free space, and therefore we're able to
58420005523SFilipe Manana * allocate the whole free space at once.
58520005523SFilipe Manana */
586ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_256K, SZ_1M)) {
5873c7251f2SDavid Sterba test_err("expected region not marked as free");
58820005523SFilipe Manana return -ENOENT;
58920005523SFilipe Manana }
59020005523SFilipe Manana
591b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != (SZ_1M + sectorsize)) {
5923c7251f2SDavid Sterba test_err("cache free space is not 1Mb + %u", sectorsize);
59320005523SFilipe Manana return -EINVAL;
59420005523SFilipe Manana }
59520005523SFilipe Manana
59620005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache,
597ee22184bSByongho Lee 0, SZ_1M, 0,
59820005523SFilipe Manana &max_extent_size);
599ee22184bSByongho Lee if (offset != (SZ_128M - SZ_256K)) {
6003c7251f2SDavid Sterba test_err(
6013c7251f2SDavid Sterba "failed to allocate 1Mb from space cache, returned offset is: %llu",
60220005523SFilipe Manana offset);
60320005523SFilipe Manana return -EINVAL;
60420005523SFilipe Manana }
60520005523SFilipe Manana
606b9ef22deSFeifei Xu /*
607b9ef22deSFeifei Xu * All that remains is a sectorsize free space region in a bitmap.
608b9ef22deSFeifei Xu * Confirm.
609b9ef22deSFeifei Xu */
61020005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 1, 1);
61120005523SFilipe Manana if (ret)
61220005523SFilipe Manana return ret;
61320005523SFilipe Manana
614b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != sectorsize) {
6153c7251f2SDavid Sterba test_err("cache free space is not %u", sectorsize);
61620005523SFilipe Manana return -EINVAL;
61720005523SFilipe Manana }
61820005523SFilipe Manana
61920005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache,
620b9ef22deSFeifei Xu 0, sectorsize, 0,
62120005523SFilipe Manana &max_extent_size);
622ee22184bSByongho Lee if (offset != (SZ_128M + SZ_16M)) {
6233c7251f2SDavid Sterba test_err("failed to allocate %u, returned offset : %llu",
624b9ef22deSFeifei Xu sectorsize, offset);
62520005523SFilipe Manana return -EINVAL;
62620005523SFilipe Manana }
62720005523SFilipe Manana
62820005523SFilipe Manana ret = check_cache_empty(cache);
62920005523SFilipe Manana if (ret)
63020005523SFilipe Manana return ret;
63120005523SFilipe Manana
632*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
63320005523SFilipe Manana
63420005523SFilipe Manana /*
63520005523SFilipe Manana * Now test a similar scenario, but where our extent entry is located
63620005523SFilipe Manana * to the right of the bitmap entry, so that we can check that stealing
63720005523SFilipe Manana * space from a bitmap to the front of an extent entry works.
63820005523SFilipe Manana */
63920005523SFilipe Manana
64020005523SFilipe Manana /*
64120005523SFilipe Manana * Extent entry covering free space range [128Mb + 128Kb, 128Mb + 256Kb[
64220005523SFilipe Manana */
643ee22184bSByongho Lee ret = test_add_free_space_entry(cache, SZ_128M + SZ_128K, SZ_128K, 0);
64420005523SFilipe Manana if (ret) {
6453c7251f2SDavid Sterba test_err("couldn't add extent entry %d", ret);
64620005523SFilipe Manana return ret;
64720005523SFilipe Manana }
64820005523SFilipe Manana
64920005523SFilipe Manana /* Bitmap entry covering free space range [0, 128Mb - 512Kb[ */
650ee22184bSByongho Lee ret = test_add_free_space_entry(cache, 0, SZ_128M - SZ_512K, 1);
65120005523SFilipe Manana if (ret) {
6523c7251f2SDavid Sterba test_err("couldn't add bitmap entry %d", ret);
65320005523SFilipe Manana return ret;
65420005523SFilipe Manana }
65520005523SFilipe Manana
65620005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
65720005523SFilipe Manana if (ret)
65820005523SFilipe Manana return ret;
65920005523SFilipe Manana
66020005523SFilipe Manana /*
66120005523SFilipe Manana * Now make only the last 256Kb of the bitmap marked as free, so that
66220005523SFilipe Manana * we end up with only the following ranges marked as free space:
66320005523SFilipe Manana *
66420005523SFilipe Manana * [128Mb + 128b, 128Mb + 256Kb[
66520005523SFilipe Manana * [128Mb - 768Kb, 128Mb - 512Kb[
66620005523SFilipe Manana */
667ee22184bSByongho Lee ret = btrfs_remove_free_space(cache, 0, SZ_128M - 768 * SZ_1K);
66820005523SFilipe Manana if (ret) {
6693c7251f2SDavid Sterba test_err("failed to free part of bitmap space %d", ret);
67020005523SFilipe Manana return ret;
67120005523SFilipe Manana }
67220005523SFilipe Manana
67320005523SFilipe Manana /* Confirm that only those 2 ranges are marked as free. */
674ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M + SZ_128K, SZ_128K)) {
6753c7251f2SDavid Sterba test_err("free space range missing");
67620005523SFilipe Manana return -ENOENT;
67720005523SFilipe Manana }
678ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - 768 * SZ_1K, SZ_256K)) {
6793c7251f2SDavid Sterba test_err("free space range missing");
68020005523SFilipe Manana return -ENOENT;
68120005523SFilipe Manana }
68220005523SFilipe Manana
68320005523SFilipe Manana /*
68420005523SFilipe Manana * Confirm that the bitmap range [0, 128Mb - 768Kb[ isn't marked
68520005523SFilipe Manana * as free anymore.
68620005523SFilipe Manana */
687ee22184bSByongho Lee if (test_check_exists(cache, 0, SZ_128M - 768 * SZ_1K)) {
6883c7251f2SDavid Sterba test_err("bitmap region not removed from space cache");
68920005523SFilipe Manana return -EINVAL;
69020005523SFilipe Manana }
69120005523SFilipe Manana
69220005523SFilipe Manana /*
69320005523SFilipe Manana * Confirm that the region [128Mb - 512Kb, 128Mb[, which is
69420005523SFilipe Manana * covered by the bitmap, isn't marked as free.
69520005523SFilipe Manana */
696ee22184bSByongho Lee if (test_check_exists(cache, SZ_128M - SZ_512K, SZ_512K)) {
6973c7251f2SDavid Sterba test_err("invalid bitmap region marked as free");
69820005523SFilipe Manana return -EINVAL;
69920005523SFilipe Manana }
70020005523SFilipe Manana
70120005523SFilipe Manana /*
70220005523SFilipe Manana * Now lets mark the region [128Mb - 512Kb, 128Mb[ as free too. But,
70320005523SFilipe Manana * lets make sure the free space cache marks it as free in the bitmap,
70420005523SFilipe Manana * and doesn't insert a new extent entry to represent this region.
70520005523SFilipe Manana */
706ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M - SZ_512K, SZ_512K);
70720005523SFilipe Manana if (ret) {
7083c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
70920005523SFilipe Manana return ret;
71020005523SFilipe Manana }
71120005523SFilipe Manana /* Confirm the region is marked as free. */
712ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - SZ_512K, SZ_512K)) {
7133c7251f2SDavid Sterba test_err("bitmap region not marked as free");
71420005523SFilipe Manana return -ENOENT;
71520005523SFilipe Manana }
71620005523SFilipe Manana
71720005523SFilipe Manana /*
71820005523SFilipe Manana * Confirm that no new extent entries or bitmap entries were added to
71920005523SFilipe Manana * the cache after adding that free space region.
72020005523SFilipe Manana */
72120005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
72220005523SFilipe Manana if (ret)
72320005523SFilipe Manana return ret;
72420005523SFilipe Manana
72520005523SFilipe Manana /*
72620005523SFilipe Manana * Now lets add a small free space region to the left of the previous
72720005523SFilipe Manana * one, which is not contiguous with it and is part of the bitmap too.
72820005523SFilipe Manana * The goal is to test that the bitmap entry space stealing doesn't
72920005523SFilipe Manana * steal this space region.
73020005523SFilipe Manana */
731b9ef22deSFeifei Xu ret = btrfs_add_free_space(cache, SZ_32M, 2 * sectorsize);
73220005523SFilipe Manana if (ret) {
7333c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
73420005523SFilipe Manana return ret;
73520005523SFilipe Manana }
73620005523SFilipe Manana
73720005523SFilipe Manana /*
73820005523SFilipe Manana * Now mark the region [128Mb, 128Mb + 128Kb[ as free too. This will
73920005523SFilipe Manana * expand the range covered by the existing extent entry that represents
74020005523SFilipe Manana * the free space [128Mb + 128Kb, 128Mb + 256Kb[.
74120005523SFilipe Manana */
742ee22184bSByongho Lee ret = btrfs_add_free_space(cache, SZ_128M, SZ_128K);
74320005523SFilipe Manana if (ret) {
7443c7251f2SDavid Sterba test_err("error adding free space: %d", ret);
74520005523SFilipe Manana return ret;
74620005523SFilipe Manana }
74720005523SFilipe Manana /* Confirm the region is marked as free. */
748ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M, SZ_128K)) {
7493c7251f2SDavid Sterba test_err("extent region not marked as free");
75020005523SFilipe Manana return -ENOENT;
75120005523SFilipe Manana }
75220005523SFilipe Manana
75320005523SFilipe Manana /*
75420005523SFilipe Manana * Confirm that our extent entry didn't stole all free space from the
755b9ef22deSFeifei Xu * bitmap, because of the small 2 * sectorsize free space region.
75620005523SFilipe Manana */
75720005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 2, 1);
75820005523SFilipe Manana if (ret)
75920005523SFilipe Manana return ret;
76020005523SFilipe Manana
76120005523SFilipe Manana /*
76220005523SFilipe Manana * So now we have the range [128Mb - 768Kb, 128Mb + 256Kb[ as free
76320005523SFilipe Manana * space. Without stealing bitmap free space into extent entry space,
76420005523SFilipe Manana * we would have all this free space represented by 2 entries in the
76520005523SFilipe Manana * cache:
76620005523SFilipe Manana *
76720005523SFilipe Manana * extent entry covering range: [128Mb, 128Mb + 256Kb[
76820005523SFilipe Manana * bitmap entry covering range: [128Mb - 768Kb, 128Mb[
76920005523SFilipe Manana *
77020005523SFilipe Manana * Attempting to allocate the whole free space (1Mb) would fail, because
77120005523SFilipe Manana * we can't allocate from multiple entries.
77220005523SFilipe Manana * With the bitmap free space stealing, we get a single extent entry
77320005523SFilipe Manana * that represents the 1Mb free space, and therefore we're able to
77420005523SFilipe Manana * allocate the whole free space at once.
77520005523SFilipe Manana */
776ee22184bSByongho Lee if (!test_check_exists(cache, SZ_128M - 768 * SZ_1K, SZ_1M)) {
7773c7251f2SDavid Sterba test_err("expected region not marked as free");
77820005523SFilipe Manana return -ENOENT;
77920005523SFilipe Manana }
78020005523SFilipe Manana
781b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != (SZ_1M + 2 * sectorsize)) {
7823c7251f2SDavid Sterba test_err("cache free space is not 1Mb + %u", 2 * sectorsize);
78320005523SFilipe Manana return -EINVAL;
78420005523SFilipe Manana }
78520005523SFilipe Manana
786ee22184bSByongho Lee offset = btrfs_find_space_for_alloc(cache, 0, SZ_1M, 0,
78720005523SFilipe Manana &max_extent_size);
788ee22184bSByongho Lee if (offset != (SZ_128M - 768 * SZ_1K)) {
7893c7251f2SDavid Sterba test_err(
7903c7251f2SDavid Sterba "failed to allocate 1Mb from space cache, returned offset is: %llu",
79120005523SFilipe Manana offset);
79220005523SFilipe Manana return -EINVAL;
79320005523SFilipe Manana }
79420005523SFilipe Manana
795b9ef22deSFeifei Xu /*
796b9ef22deSFeifei Xu * All that remains is 2 * sectorsize free space region
797b9ef22deSFeifei Xu * in a bitmap. Confirm.
798b9ef22deSFeifei Xu */
79920005523SFilipe Manana ret = check_num_extents_and_bitmaps(cache, 1, 1);
80020005523SFilipe Manana if (ret)
80120005523SFilipe Manana return ret;
80220005523SFilipe Manana
803b9ef22deSFeifei Xu if (cache->free_space_ctl->free_space != 2 * sectorsize) {
8043c7251f2SDavid Sterba test_err("cache free space is not %u", 2 * sectorsize);
80520005523SFilipe Manana return -EINVAL;
80620005523SFilipe Manana }
80720005523SFilipe Manana
80820005523SFilipe Manana offset = btrfs_find_space_for_alloc(cache,
809b9ef22deSFeifei Xu 0, 2 * sectorsize, 0,
81020005523SFilipe Manana &max_extent_size);
811ee22184bSByongho Lee if (offset != SZ_32M) {
8123c7251f2SDavid Sterba test_err("failed to allocate %u, offset: %llu",
8133c7251f2SDavid Sterba 2 * sectorsize, offset);
81420005523SFilipe Manana return -EINVAL;
81520005523SFilipe Manana }
81620005523SFilipe Manana
81720005523SFilipe Manana ret = check_cache_empty(cache);
81820005523SFilipe Manana if (ret)
81920005523SFilipe Manana return ret;
82020005523SFilipe Manana
82128f0779aSDavid Sterba cache->free_space_ctl->op = orig_free_space_ops;
822*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
82320005523SFilipe Manana
82420005523SFilipe Manana return 0;
82520005523SFilipe Manana }
82620005523SFilipe Manana
bytes_index_use_bitmap(struct btrfs_free_space_ctl * ctl,struct btrfs_free_space * info)827bbf27275SJosef Bacik static bool bytes_index_use_bitmap(struct btrfs_free_space_ctl *ctl,
828bbf27275SJosef Bacik struct btrfs_free_space *info)
829bbf27275SJosef Bacik {
830bbf27275SJosef Bacik return true;
831bbf27275SJosef Bacik }
832bbf27275SJosef Bacik
test_bytes_index(struct btrfs_block_group * cache,u32 sectorsize)833bbf27275SJosef Bacik static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
834bbf27275SJosef Bacik {
835bbf27275SJosef Bacik const struct btrfs_free_space_op test_free_space_ops = {
836bbf27275SJosef Bacik .use_bitmap = bytes_index_use_bitmap,
837bbf27275SJosef Bacik };
838bbf27275SJosef Bacik const struct btrfs_free_space_op *orig_free_space_ops;
839bbf27275SJosef Bacik struct btrfs_free_space_ctl *ctl = cache->free_space_ctl;
840bbf27275SJosef Bacik struct btrfs_free_space *entry;
841bbf27275SJosef Bacik struct rb_node *node;
842bbf27275SJosef Bacik u64 offset, max_extent_size, bytes;
843bbf27275SJosef Bacik int ret, i;
844bbf27275SJosef Bacik
845bbf27275SJosef Bacik test_msg("running bytes index tests");
846bbf27275SJosef Bacik
847bbf27275SJosef Bacik /* First just validate that it does everything in order. */
848bbf27275SJosef Bacik offset = 0;
849bbf27275SJosef Bacik for (i = 0; i < 10; i++) {
850bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M;
851bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, bytes, 0);
852bbf27275SJosef Bacik if (ret) {
853bbf27275SJosef Bacik test_err("couldn't add extent entry %d\n", ret);
854bbf27275SJosef Bacik return ret;
855bbf27275SJosef Bacik }
856bbf27275SJosef Bacik offset += bytes + sectorsize;
857bbf27275SJosef Bacik }
858bbf27275SJosef Bacik
859bbf27275SJosef Bacik for (node = rb_first_cached(&ctl->free_space_bytes), i = 9; node;
860bbf27275SJosef Bacik node = rb_next(node), i--) {
861bbf27275SJosef Bacik entry = rb_entry(node, struct btrfs_free_space, bytes_index);
862bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M;
863bbf27275SJosef Bacik if (entry->bytes != bytes) {
864bbf27275SJosef Bacik test_err("invalid bytes index order, found %llu expected %llu",
865bbf27275SJosef Bacik entry->bytes, bytes);
866bbf27275SJosef Bacik return -EINVAL;
867bbf27275SJosef Bacik }
868bbf27275SJosef Bacik }
869bbf27275SJosef Bacik
870bbf27275SJosef Bacik /* Now validate bitmaps do the correct thing. */
871*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
872bbf27275SJosef Bacik for (i = 0; i < 2; i++) {
873bbf27275SJosef Bacik offset = i * BITS_PER_BITMAP * sectorsize;
874bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M;
875bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, bytes, 1);
876bbf27275SJosef Bacik if (ret) {
877bbf27275SJosef Bacik test_err("couldn't add bitmap entry");
878bbf27275SJosef Bacik return ret;
879bbf27275SJosef Bacik }
880bbf27275SJosef Bacik }
881bbf27275SJosef Bacik
882bbf27275SJosef Bacik for (node = rb_first_cached(&ctl->free_space_bytes), i = 1; node;
883bbf27275SJosef Bacik node = rb_next(node), i--) {
884bbf27275SJosef Bacik entry = rb_entry(node, struct btrfs_free_space, bytes_index);
885bbf27275SJosef Bacik bytes = (i + 1) * SZ_1M;
886bbf27275SJosef Bacik if (entry->bytes != bytes) {
887bbf27275SJosef Bacik test_err("invalid bytes index order, found %llu expected %llu",
888bbf27275SJosef Bacik entry->bytes, bytes);
889bbf27275SJosef Bacik return -EINVAL;
890bbf27275SJosef Bacik }
891bbf27275SJosef Bacik }
892bbf27275SJosef Bacik
893bbf27275SJosef Bacik /* Now validate bitmaps with different ->max_extent_size. */
894*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
895bbf27275SJosef Bacik orig_free_space_ops = cache->free_space_ctl->op;
896bbf27275SJosef Bacik cache->free_space_ctl->op = &test_free_space_ops;
897bbf27275SJosef Bacik
898bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, 0, sectorsize, 1);
899bbf27275SJosef Bacik if (ret) {
900bbf27275SJosef Bacik test_err("couldn't add bitmap entry");
901bbf27275SJosef Bacik return ret;
902bbf27275SJosef Bacik }
903bbf27275SJosef Bacik
904bbf27275SJosef Bacik offset = BITS_PER_BITMAP * sectorsize;
905bbf27275SJosef Bacik ret = test_add_free_space_entry(cache, offset, sectorsize, 1);
906bbf27275SJosef Bacik if (ret) {
907bbf27275SJosef Bacik test_err("couldn't add bitmap_entry");
908bbf27275SJosef Bacik return ret;
909bbf27275SJosef Bacik }
910bbf27275SJosef Bacik
911bbf27275SJosef Bacik /*
912bbf27275SJosef Bacik * Now set a bunch of sectorsize extents in the first entry so it's
913bbf27275SJosef Bacik * ->bytes is large.
914bbf27275SJosef Bacik */
915bbf27275SJosef Bacik for (i = 2; i < 20; i += 2) {
916bbf27275SJosef Bacik offset = sectorsize * i;
917bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize);
918bbf27275SJosef Bacik if (ret) {
919bbf27275SJosef Bacik test_err("error populating sparse bitmap %d", ret);
920bbf27275SJosef Bacik return ret;
921bbf27275SJosef Bacik }
922bbf27275SJosef Bacik }
923bbf27275SJosef Bacik
924bbf27275SJosef Bacik /*
925bbf27275SJosef Bacik * Now set a contiguous extent in the second bitmap so its
926bbf27275SJosef Bacik * ->max_extent_size is larger than the first bitmaps.
927bbf27275SJosef Bacik */
928bbf27275SJosef Bacik offset = (BITS_PER_BITMAP * sectorsize) + sectorsize;
929bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize);
930bbf27275SJosef Bacik if (ret) {
931bbf27275SJosef Bacik test_err("error adding contiguous extent %d", ret);
932bbf27275SJosef Bacik return ret;
933bbf27275SJosef Bacik }
934bbf27275SJosef Bacik
935bbf27275SJosef Bacik /*
936bbf27275SJosef Bacik * Since we don't set ->max_extent_size unless we search everything
937bbf27275SJosef Bacik * should be indexed on bytes.
938bbf27275SJosef Bacik */
939bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes),
940bbf27275SJosef Bacik struct btrfs_free_space, bytes_index);
941bbf27275SJosef Bacik if (entry->bytes != (10 * sectorsize)) {
942bbf27275SJosef Bacik test_err("error, wrong entry in the first slot in bytes_index");
943bbf27275SJosef Bacik return -EINVAL;
944bbf27275SJosef Bacik }
945bbf27275SJosef Bacik
946bbf27275SJosef Bacik max_extent_size = 0;
947bbf27275SJosef Bacik offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 3,
948bbf27275SJosef Bacik 0, &max_extent_size);
949bbf27275SJosef Bacik if (offset != 0) {
950bbf27275SJosef Bacik test_err("found space to alloc even though we don't have enough space");
951bbf27275SJosef Bacik return -EINVAL;
952bbf27275SJosef Bacik }
953bbf27275SJosef Bacik
954bbf27275SJosef Bacik if (max_extent_size != (2 * sectorsize)) {
955bbf27275SJosef Bacik test_err("got the wrong max_extent size %llu expected %llu",
956bbf27275SJosef Bacik max_extent_size, (unsigned long long)(2 * sectorsize));
957bbf27275SJosef Bacik return -EINVAL;
958bbf27275SJosef Bacik }
959bbf27275SJosef Bacik
960bbf27275SJosef Bacik /*
961bbf27275SJosef Bacik * The search should have re-arranged the bytes index to use the
962bbf27275SJosef Bacik * ->max_extent_size, validate it's now what we expect it to be.
963bbf27275SJosef Bacik */
964bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes),
965bbf27275SJosef Bacik struct btrfs_free_space, bytes_index);
966bbf27275SJosef Bacik if (entry->bytes != (2 * sectorsize)) {
967bbf27275SJosef Bacik test_err("error, the bytes index wasn't recalculated properly");
968bbf27275SJosef Bacik return -EINVAL;
969bbf27275SJosef Bacik }
970bbf27275SJosef Bacik
971bbf27275SJosef Bacik /* Add another sectorsize to re-arrange the tree back to ->bytes. */
972bbf27275SJosef Bacik offset = (BITS_PER_BITMAP * sectorsize) - sectorsize;
973bbf27275SJosef Bacik ret = btrfs_add_free_space(cache, offset, sectorsize);
974bbf27275SJosef Bacik if (ret) {
975bbf27275SJosef Bacik test_err("error adding extent to the sparse entry %d", ret);
976bbf27275SJosef Bacik return ret;
977bbf27275SJosef Bacik }
978bbf27275SJosef Bacik
979bbf27275SJosef Bacik entry = rb_entry(rb_first_cached(&ctl->free_space_bytes),
980bbf27275SJosef Bacik struct btrfs_free_space, bytes_index);
981bbf27275SJosef Bacik if (entry->bytes != (11 * sectorsize)) {
982bbf27275SJosef Bacik test_err("error, wrong entry in the first slot in bytes_index");
983bbf27275SJosef Bacik return -EINVAL;
984bbf27275SJosef Bacik }
985bbf27275SJosef Bacik
986bbf27275SJosef Bacik /*
987bbf27275SJosef Bacik * Now make sure we find our correct entry after searching that will
988bbf27275SJosef Bacik * result in a re-arranging of the tree.
989bbf27275SJosef Bacik */
990bbf27275SJosef Bacik max_extent_size = 0;
991bbf27275SJosef Bacik offset = btrfs_find_space_for_alloc(cache, cache->start, sectorsize * 2,
992bbf27275SJosef Bacik 0, &max_extent_size);
993bbf27275SJosef Bacik if (offset != (BITS_PER_BITMAP * sectorsize)) {
994bbf27275SJosef Bacik test_err("error, found %llu instead of %llu for our alloc",
995bbf27275SJosef Bacik offset,
996bbf27275SJosef Bacik (unsigned long long)(BITS_PER_BITMAP * sectorsize));
997bbf27275SJosef Bacik return -EINVAL;
998bbf27275SJosef Bacik }
999bbf27275SJosef Bacik
1000bbf27275SJosef Bacik cache->free_space_ctl->op = orig_free_space_ops;
1001*fc80f7acSJosef Bacik btrfs_remove_free_space_cache(cache);
1002bbf27275SJosef Bacik return 0;
1003bbf27275SJosef Bacik }
1004bbf27275SJosef Bacik
btrfs_test_free_space_cache(u32 sectorsize,u32 nodesize)1005b9ef22deSFeifei Xu int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize)
1006dc11dd5dSJosef Bacik {
10077c0260eeSJeff Mahoney struct btrfs_fs_info *fs_info;
100832da5386SDavid Sterba struct btrfs_block_group *cache;
1009d0bd4560SJosef Bacik struct btrfs_root *root = NULL;
1010d0bd4560SJosef Bacik int ret = -ENOMEM;
1011dc11dd5dSJosef Bacik
1012315b76b4SDavid Sterba test_msg("running btrfs free space cache tests");
1013da17066cSJeff Mahoney fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
101437b2a7bcSDavid Sterba if (!fs_info) {
101537b2a7bcSDavid Sterba test_std_err(TEST_ALLOC_FS_INFO);
1016da17066cSJeff Mahoney return -ENOMEM;
101737b2a7bcSDavid Sterba }
1018dc11dd5dSJosef Bacik
101936b3dc05SFeifei Xu /*
102036b3dc05SFeifei Xu * For ppc64 (with 64k page size), bytes per bitmap might be
102136b3dc05SFeifei Xu * larger than 1G. To make bitmap test available in ppc64,
102236b3dc05SFeifei Xu * alloc dummy block group whose size cross bitmaps.
102336b3dc05SFeifei Xu */
1024da17066cSJeff Mahoney cache = btrfs_alloc_dummy_block_group(fs_info,
1025da17066cSJeff Mahoney BITS_PER_BITMAP * sectorsize + PAGE_SIZE);
1026dc11dd5dSJosef Bacik if (!cache) {
10273199366dSDavid Sterba test_std_err(TEST_ALLOC_BLOCK_GROUP);
1028da17066cSJeff Mahoney btrfs_free_dummy_fs_info(fs_info);
1029dc11dd5dSJosef Bacik return 0;
1030dc11dd5dSJosef Bacik }
1031dc11dd5dSJosef Bacik
1032da17066cSJeff Mahoney root = btrfs_alloc_dummy_root(fs_info);
103389b6c8d1SDan Carpenter if (IS_ERR(root)) {
103452ab7bcaSDavid Sterba test_std_err(TEST_ALLOC_ROOT);
103589b6c8d1SDan Carpenter ret = PTR_ERR(root);
1036d0bd4560SJosef Bacik goto out;
103789b6c8d1SDan Carpenter }
1038d0bd4560SJosef Bacik
1039abed4aaaSJosef Bacik root->root_key.objectid = BTRFS_EXTENT_TREE_OBJECTID;
1040abed4aaaSJosef Bacik root->root_key.type = BTRFS_ROOT_ITEM_KEY;
1041abed4aaaSJosef Bacik root->root_key.offset = 0;
1042abed4aaaSJosef Bacik btrfs_global_root_insert(root);
1043d0bd4560SJosef Bacik
1044dc11dd5dSJosef Bacik ret = test_extents(cache);
1045dc11dd5dSJosef Bacik if (ret)
1046dc11dd5dSJosef Bacik goto out;
1047b9ef22deSFeifei Xu ret = test_bitmaps(cache, sectorsize);
1048dc11dd5dSJosef Bacik if (ret)
1049dc11dd5dSJosef Bacik goto out;
1050b9ef22deSFeifei Xu ret = test_bitmaps_and_extents(cache, sectorsize);
1051dc11dd5dSJosef Bacik if (ret)
1052dc11dd5dSJosef Bacik goto out;
105320005523SFilipe Manana
1054b9ef22deSFeifei Xu ret = test_steal_space_from_bitmap_to_extent(cache, sectorsize);
1055bbf27275SJosef Bacik if (ret)
1056bbf27275SJosef Bacik goto out;
1057bbf27275SJosef Bacik ret = test_bytes_index(cache, sectorsize);
1058dc11dd5dSJosef Bacik out:
10597c55ee0cSOmar Sandoval btrfs_free_dummy_block_group(cache);
1060d0bd4560SJosef Bacik btrfs_free_dummy_root(root);
10617c0260eeSJeff Mahoney btrfs_free_dummy_fs_info(fs_info);
1062dc11dd5dSJosef Bacik return ret;
1063dc11dd5dSJosef Bacik }
1064