Linux 6.7-rc7
[linux-modified.git] / fs / btrfs / tests / extent-map-tests.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2017 Oracle.  All rights reserved.
4  */
5
6 #include <linux/types.h>
7 #include "btrfs-tests.h"
8 #include "../ctree.h"
9 #include "../btrfs_inode.h"
10 #include "../volumes.h"
11 #include "../disk-io.h"
12 #include "../block-group.h"
13
14 static void free_extent_map_tree(struct extent_map_tree *em_tree)
15 {
16         struct extent_map *em;
17         struct rb_node *node;
18
19         write_lock(&em_tree->lock);
20         while (!RB_EMPTY_ROOT(&em_tree->map.rb_root)) {
21                 node = rb_first_cached(&em_tree->map);
22                 em = rb_entry(node, struct extent_map, rb_node);
23                 remove_extent_mapping(em_tree, em);
24
25 #ifdef CONFIG_BTRFS_DEBUG
26                 if (refcount_read(&em->refs) != 1) {
27                         test_err(
28 "em leak: em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx) refs %d",
29                                  em->start, em->len, em->block_start,
30                                  em->block_len, refcount_read(&em->refs));
31
32                         refcount_set(&em->refs, 1);
33                 }
34 #endif
35                 free_extent_map(em);
36         }
37         write_unlock(&em_tree->lock);
38 }
39
40 /*
41  * Test scenario:
42  *
43  * Suppose that no extent map has been loaded into memory yet, there is a file
44  * extent [0, 16K), followed by another file extent [16K, 20K), two dio reads
45  * are entering btrfs_get_extent() concurrently, t1 is reading [8K, 16K), t2 is
46  * reading [0, 8K)
47  *
48  *     t1                            t2
49  *  btrfs_get_extent()              btrfs_get_extent()
50  *    -> lookup_extent_mapping()      ->lookup_extent_mapping()
51  *    -> add_extent_mapping(0, 16K)
52  *    -> return em
53  *                                    ->add_extent_mapping(0, 16K)
54  *                                    -> #handle -EEXIST
55  */
56 static int test_case_1(struct btrfs_fs_info *fs_info,
57                 struct extent_map_tree *em_tree)
58 {
59         struct extent_map *em;
60         u64 start = 0;
61         u64 len = SZ_8K;
62         int ret;
63
64         em = alloc_extent_map();
65         if (!em) {
66                 test_std_err(TEST_ALLOC_EXTENT_MAP);
67                 return -ENOMEM;
68         }
69
70         /* Add [0, 16K) */
71         em->start = 0;
72         em->len = SZ_16K;
73         em->block_start = 0;
74         em->block_len = SZ_16K;
75         write_lock(&em_tree->lock);
76         ret = add_extent_mapping(em_tree, em, 0);
77         write_unlock(&em_tree->lock);
78         if (ret < 0) {
79                 test_err("cannot add extent range [0, 16K)");
80                 goto out;
81         }
82         free_extent_map(em);
83
84         /* Add [16K, 20K) following [0, 16K)  */
85         em = alloc_extent_map();
86         if (!em) {
87                 test_std_err(TEST_ALLOC_EXTENT_MAP);
88                 ret = -ENOMEM;
89                 goto out;
90         }
91
92         em->start = SZ_16K;
93         em->len = SZ_4K;
94         em->block_start = SZ_32K; /* avoid merging */
95         em->block_len = SZ_4K;
96         write_lock(&em_tree->lock);
97         ret = add_extent_mapping(em_tree, em, 0);
98         write_unlock(&em_tree->lock);
99         if (ret < 0) {
100                 test_err("cannot add extent range [16K, 20K)");
101                 goto out;
102         }
103         free_extent_map(em);
104
105         em = alloc_extent_map();
106         if (!em) {
107                 test_std_err(TEST_ALLOC_EXTENT_MAP);
108                 ret = -ENOMEM;
109                 goto out;
110         }
111
112         /* Add [0, 8K), should return [0, 16K) instead. */
113         em->start = start;
114         em->len = len;
115         em->block_start = start;
116         em->block_len = len;
117         write_lock(&em_tree->lock);
118         ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len);
119         write_unlock(&em_tree->lock);
120         if (ret) {
121                 test_err("case1 [%llu %llu]: ret %d", start, start + len, ret);
122                 goto out;
123         }
124         if (em &&
125             (em->start != 0 || extent_map_end(em) != SZ_16K ||
126              em->block_start != 0 || em->block_len != SZ_16K)) {
127                 test_err(
128 "case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
129                          start, start + len, ret, em->start, em->len,
130                          em->block_start, em->block_len);
131                 ret = -EINVAL;
132         }
133         free_extent_map(em);
134 out:
135         free_extent_map_tree(em_tree);
136
137         return ret;
138 }
139
140 /*
141  * Test scenario:
142  *
143  * Reading the inline ending up with EEXIST, ie. read an inline
144  * extent and discard page cache and read it again.
145  */
146 static int test_case_2(struct btrfs_fs_info *fs_info,
147                 struct extent_map_tree *em_tree)
148 {
149         struct extent_map *em;
150         int ret;
151
152         em = alloc_extent_map();
153         if (!em) {
154                 test_std_err(TEST_ALLOC_EXTENT_MAP);
155                 return -ENOMEM;
156         }
157
158         /* Add [0, 1K) */
159         em->start = 0;
160         em->len = SZ_1K;
161         em->block_start = EXTENT_MAP_INLINE;
162         em->block_len = (u64)-1;
163         write_lock(&em_tree->lock);
164         ret = add_extent_mapping(em_tree, em, 0);
165         write_unlock(&em_tree->lock);
166         if (ret < 0) {
167                 test_err("cannot add extent range [0, 1K)");
168                 goto out;
169         }
170         free_extent_map(em);
171
172         /* Add [4K, 8K) following [0, 1K)  */
173         em = alloc_extent_map();
174         if (!em) {
175                 test_std_err(TEST_ALLOC_EXTENT_MAP);
176                 ret = -ENOMEM;
177                 goto out;
178         }
179
180         em->start = SZ_4K;
181         em->len = SZ_4K;
182         em->block_start = SZ_4K;
183         em->block_len = SZ_4K;
184         write_lock(&em_tree->lock);
185         ret = add_extent_mapping(em_tree, em, 0);
186         write_unlock(&em_tree->lock);
187         if (ret < 0) {
188                 test_err("cannot add extent range [4K, 8K)");
189                 goto out;
190         }
191         free_extent_map(em);
192
193         em = alloc_extent_map();
194         if (!em) {
195                 test_std_err(TEST_ALLOC_EXTENT_MAP);
196                 ret = -ENOMEM;
197                 goto out;
198         }
199
200         /* Add [0, 1K) */
201         em->start = 0;
202         em->len = SZ_1K;
203         em->block_start = EXTENT_MAP_INLINE;
204         em->block_len = (u64)-1;
205         write_lock(&em_tree->lock);
206         ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len);
207         write_unlock(&em_tree->lock);
208         if (ret) {
209                 test_err("case2 [0 1K]: ret %d", ret);
210                 goto out;
211         }
212         if (em &&
213             (em->start != 0 || extent_map_end(em) != SZ_1K ||
214              em->block_start != EXTENT_MAP_INLINE || em->block_len != (u64)-1)) {
215                 test_err(
216 "case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu",
217                          ret, em->start, em->len, em->block_start,
218                          em->block_len);
219                 ret = -EINVAL;
220         }
221         free_extent_map(em);
222 out:
223         free_extent_map_tree(em_tree);
224
225         return ret;
226 }
227
228 static int __test_case_3(struct btrfs_fs_info *fs_info,
229                 struct extent_map_tree *em_tree, u64 start)
230 {
231         struct extent_map *em;
232         u64 len = SZ_4K;
233         int ret;
234
235         em = alloc_extent_map();
236         if (!em) {
237                 test_std_err(TEST_ALLOC_EXTENT_MAP);
238                 return -ENOMEM;
239         }
240
241         /* Add [4K, 8K) */
242         em->start = SZ_4K;
243         em->len = SZ_4K;
244         em->block_start = SZ_4K;
245         em->block_len = SZ_4K;
246         write_lock(&em_tree->lock);
247         ret = add_extent_mapping(em_tree, em, 0);
248         write_unlock(&em_tree->lock);
249         if (ret < 0) {
250                 test_err("cannot add extent range [4K, 8K)");
251                 goto out;
252         }
253         free_extent_map(em);
254
255         em = alloc_extent_map();
256         if (!em) {
257                 test_std_err(TEST_ALLOC_EXTENT_MAP);
258                 ret = -ENOMEM;
259                 goto out;
260         }
261
262         /* Add [0, 16K) */
263         em->start = 0;
264         em->len = SZ_16K;
265         em->block_start = 0;
266         em->block_len = SZ_16K;
267         write_lock(&em_tree->lock);
268         ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len);
269         write_unlock(&em_tree->lock);
270         if (ret) {
271                 test_err("case3 [0x%llx 0x%llx): ret %d",
272                          start, start + len, ret);
273                 goto out;
274         }
275         /*
276          * Since bytes within em are contiguous, em->block_start is identical to
277          * em->start.
278          */
279         if (em &&
280             (start < em->start || start + len > extent_map_end(em) ||
281              em->start != em->block_start || em->len != em->block_len)) {
282                 test_err(
283 "case3 [0x%llx 0x%llx): ret %d em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)",
284                          start, start + len, ret, em->start, em->len,
285                          em->block_start, em->block_len);
286                 ret = -EINVAL;
287         }
288         free_extent_map(em);
289 out:
290         free_extent_map_tree(em_tree);
291
292         return ret;
293 }
294
295 /*
296  * Test scenario:
297  *
298  * Suppose that no extent map has been loaded into memory yet.
299  * There is a file extent [0, 16K), two jobs are running concurrently
300  * against it, t1 is buffered writing to [4K, 8K) and t2 is doing dio
301  * read from [0, 4K) or [8K, 12K) or [12K, 16K).
302  *
303  * t1 goes ahead of t2 and adds em [4K, 8K) into tree.
304  *
305  *         t1                       t2
306  *  cow_file_range()         btrfs_get_extent()
307  *                            -> lookup_extent_mapping()
308  *   -> add_extent_mapping()
309  *                            -> add_extent_mapping()
310  */
311 static int test_case_3(struct btrfs_fs_info *fs_info,
312                 struct extent_map_tree *em_tree)
313 {
314         int ret;
315
316         ret = __test_case_3(fs_info, em_tree, 0);
317         if (ret)
318                 return ret;
319         ret = __test_case_3(fs_info, em_tree, SZ_8K);
320         if (ret)
321                 return ret;
322         ret = __test_case_3(fs_info, em_tree, (12 * SZ_1K));
323
324         return ret;
325 }
326
327 static int __test_case_4(struct btrfs_fs_info *fs_info,
328                 struct extent_map_tree *em_tree, u64 start)
329 {
330         struct extent_map *em;
331         u64 len = SZ_4K;
332         int ret;
333
334         em = alloc_extent_map();
335         if (!em) {
336                 test_std_err(TEST_ALLOC_EXTENT_MAP);
337                 return -ENOMEM;
338         }
339
340         /* Add [0K, 8K) */
341         em->start = 0;
342         em->len = SZ_8K;
343         em->block_start = 0;
344         em->block_len = SZ_8K;
345         write_lock(&em_tree->lock);
346         ret = add_extent_mapping(em_tree, em, 0);
347         write_unlock(&em_tree->lock);
348         if (ret < 0) {
349                 test_err("cannot add extent range [0, 8K)");
350                 goto out;
351         }
352         free_extent_map(em);
353
354         em = alloc_extent_map();
355         if (!em) {
356                 test_std_err(TEST_ALLOC_EXTENT_MAP);
357                 ret = -ENOMEM;
358                 goto out;
359         }
360
361         /* Add [8K, 32K) */
362         em->start = SZ_8K;
363         em->len = 24 * SZ_1K;
364         em->block_start = SZ_16K; /* avoid merging */
365         em->block_len = 24 * SZ_1K;
366         write_lock(&em_tree->lock);
367         ret = add_extent_mapping(em_tree, em, 0);
368         write_unlock(&em_tree->lock);
369         if (ret < 0) {
370                 test_err("cannot add extent range [8K, 32K)");
371                 goto out;
372         }
373         free_extent_map(em);
374
375         em = alloc_extent_map();
376         if (!em) {
377                 test_std_err(TEST_ALLOC_EXTENT_MAP);
378                 ret = -ENOMEM;
379                 goto out;
380         }
381         /* Add [0K, 32K) */
382         em->start = 0;
383         em->len = SZ_32K;
384         em->block_start = 0;
385         em->block_len = SZ_32K;
386         write_lock(&em_tree->lock);
387         ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len);
388         write_unlock(&em_tree->lock);
389         if (ret) {
390                 test_err("case4 [0x%llx 0x%llx): ret %d",
391                          start, len, ret);
392                 goto out;
393         }
394         if (em && (start < em->start || start + len > extent_map_end(em))) {
395                 test_err(
396 "case4 [0x%llx 0x%llx): ret %d, added wrong em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)",
397                          start, len, ret, em->start, em->len, em->block_start,
398                          em->block_len);
399                 ret = -EINVAL;
400         }
401         free_extent_map(em);
402 out:
403         free_extent_map_tree(em_tree);
404
405         return ret;
406 }
407
408 /*
409  * Test scenario:
410  *
411  * Suppose that no extent map has been loaded into memory yet.
412  * There is a file extent [0, 32K), two jobs are running concurrently
413  * against it, t1 is doing dio write to [8K, 32K) and t2 is doing dio
414  * read from [0, 4K) or [4K, 8K).
415  *
416  * t1 goes ahead of t2 and splits em [0, 32K) to em [0K, 8K) and [8K 32K).
417  *
418  *         t1                                t2
419  *  btrfs_get_blocks_direct()          btrfs_get_blocks_direct()
420  *   -> btrfs_get_extent()              -> btrfs_get_extent()
421  *       -> lookup_extent_mapping()
422  *       -> add_extent_mapping()            -> lookup_extent_mapping()
423  *          # load [0, 32K)
424  *   -> btrfs_new_extent_direct()
425  *       -> btrfs_drop_extent_cache()
426  *          # split [0, 32K)
427  *       -> add_extent_mapping()
428  *          # add [8K, 32K)
429  *                                          -> add_extent_mapping()
430  *                                             # handle -EEXIST when adding
431  *                                             # [0, 32K)
432  */
433 static int test_case_4(struct btrfs_fs_info *fs_info,
434                 struct extent_map_tree *em_tree)
435 {
436         int ret;
437
438         ret = __test_case_4(fs_info, em_tree, 0);
439         if (ret)
440                 return ret;
441         ret = __test_case_4(fs_info, em_tree, SZ_4K);
442
443         return ret;
444 }
445
446 static int add_compressed_extent(struct extent_map_tree *em_tree,
447                                  u64 start, u64 len, u64 block_start)
448 {
449         struct extent_map *em;
450         int ret;
451
452         em = alloc_extent_map();
453         if (!em) {
454                 test_std_err(TEST_ALLOC_EXTENT_MAP);
455                 return -ENOMEM;
456         }
457
458         em->start = start;
459         em->len = len;
460         em->block_start = block_start;
461         em->block_len = SZ_4K;
462         set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
463         write_lock(&em_tree->lock);
464         ret = add_extent_mapping(em_tree, em, 0);
465         write_unlock(&em_tree->lock);
466         free_extent_map(em);
467         if (ret < 0) {
468                 test_err("cannot add extent map [%llu, %llu)", start, start + len);
469                 return ret;
470         }
471
472         return 0;
473 }
474
475 struct extent_range {
476         u64 start;
477         u64 len;
478 };
479
480 /* The valid states of the tree after every drop, as described below. */
481 struct extent_range valid_ranges[][7] = {
482         {
483           { .start = 0,                 .len = SZ_8K },         /* [0, 8K) */
484           { .start = SZ_4K * 3,         .len = SZ_4K * 3},      /* [12k, 24k) */
485           { .start = SZ_4K * 6,         .len = SZ_4K * 3},      /* [24k, 36k) */
486           { .start = SZ_32K + SZ_4K,    .len = SZ_4K},          /* [36k, 40k) */
487           { .start = SZ_4K * 10,        .len = SZ_4K * 6},      /* [40k, 64k) */
488         },
489         {
490           { .start = 0,                 .len = SZ_8K },         /* [0, 8K) */
491           { .start = SZ_4K * 5,         .len = SZ_4K},          /* [20k, 24k) */
492           { .start = SZ_4K * 6,         .len = SZ_4K * 3},      /* [24k, 36k) */
493           { .start = SZ_32K + SZ_4K,    .len = SZ_4K},          /* [36k, 40k) */
494           { .start = SZ_4K * 10,        .len = SZ_4K * 6},      /* [40k, 64k) */
495         },
496         {
497           { .start = 0,                 .len = SZ_8K },         /* [0, 8K) */
498           { .start = SZ_4K * 5,         .len = SZ_4K},          /* [20k, 24k) */
499           { .start = SZ_4K * 6,         .len = SZ_4K},          /* [24k, 28k) */
500           { .start = SZ_32K,            .len = SZ_4K},          /* [32k, 36k) */
501           { .start = SZ_32K + SZ_4K,    .len = SZ_4K},          /* [36k, 40k) */
502           { .start = SZ_4K * 10,        .len = SZ_4K * 6},      /* [40k, 64k) */
503         },
504         {
505           { .start = 0,                 .len = SZ_8K},          /* [0, 8K) */
506           { .start = SZ_4K * 5,         .len = SZ_4K},          /* [20k, 24k) */
507           { .start = SZ_4K * 6,         .len = SZ_4K},          /* [24k, 28k) */
508         }
509 };
510
511 static int validate_range(struct extent_map_tree *em_tree, int index)
512 {
513         struct rb_node *n;
514         int i;
515
516         for (i = 0, n = rb_first_cached(&em_tree->map);
517              valid_ranges[index][i].len && n;
518              i++, n = rb_next(n)) {
519                 struct extent_map *entry = rb_entry(n, struct extent_map, rb_node);
520
521                 if (entry->start != valid_ranges[index][i].start) {
522                         test_err("mapping has start %llu expected %llu",
523                                  entry->start, valid_ranges[index][i].start);
524                         return -EINVAL;
525                 }
526
527                 if (entry->len != valid_ranges[index][i].len) {
528                         test_err("mapping has len %llu expected %llu",
529                                  entry->len, valid_ranges[index][i].len);
530                         return -EINVAL;
531                 }
532         }
533
534         /*
535          * We exited because we don't have any more entries in the extent_map
536          * but we still expect more valid entries.
537          */
538         if (valid_ranges[index][i].len) {
539                 test_err("missing an entry");
540                 return -EINVAL;
541         }
542
543         /* We exited the loop but still have entries in the extent map. */
544         if (n) {
545                 test_err("we have a left over entry in the extent map we didn't expect");
546                 return -EINVAL;
547         }
548
549         return 0;
550 }
551
552 /*
553  * Test scenario:
554  *
555  * Test the various edge cases of btrfs_drop_extent_map_range, create the
556  * following ranges
557  *
558  * [0, 12k)[12k, 24k)[24k, 36k)[36k, 40k)[40k,64k)
559  *
560  * And then we'll drop:
561  *
562  * [8k, 12k) - test the single front split
563  * [12k, 20k) - test the single back split
564  * [28k, 32k) - test the double split
565  * [32k, 64k) - test whole em dropping
566  *
567  * They'll have the EXTENT_FLAG_COMPRESSED flag set to keep the em tree from
568  * merging the em's.
569  */
570 static int test_case_5(void)
571 {
572         struct extent_map_tree *em_tree;
573         struct inode *inode;
574         u64 start, end;
575         int ret;
576
577         test_msg("Running btrfs_drop_extent_map_range tests");
578
579         inode = btrfs_new_test_inode();
580         if (!inode) {
581                 test_std_err(TEST_ALLOC_INODE);
582                 return -ENOMEM;
583         }
584
585         em_tree = &BTRFS_I(inode)->extent_tree;
586
587         /* [0, 12k) */
588         ret = add_compressed_extent(em_tree, 0, SZ_4K * 3, 0);
589         if (ret) {
590                 test_err("cannot add extent range [0, 12K)");
591                 goto out;
592         }
593
594         /* [12k, 24k) */
595         ret = add_compressed_extent(em_tree, SZ_4K * 3, SZ_4K * 3, SZ_4K);
596         if (ret) {
597                 test_err("cannot add extent range [12k, 24k)");
598                 goto out;
599         }
600
601         /* [24k, 36k) */
602         ret = add_compressed_extent(em_tree, SZ_4K * 6, SZ_4K * 3, SZ_8K);
603         if (ret) {
604                 test_err("cannot add extent range [12k, 24k)");
605                 goto out;
606         }
607
608         /* [36k, 40k) */
609         ret = add_compressed_extent(em_tree, SZ_32K + SZ_4K, SZ_4K, SZ_4K * 3);
610         if (ret) {
611                 test_err("cannot add extent range [12k, 24k)");
612                 goto out;
613         }
614
615         /* [40k, 64k) */
616         ret = add_compressed_extent(em_tree, SZ_4K * 10, SZ_4K * 6, SZ_16K);
617         if (ret) {
618                 test_err("cannot add extent range [12k, 24k)");
619                 goto out;
620         }
621
622         /* Drop [8k, 12k) */
623         start = SZ_8K;
624         end = (3 * SZ_4K) - 1;
625         btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false);
626         ret = validate_range(&BTRFS_I(inode)->extent_tree, 0);
627         if (ret)
628                 goto out;
629
630         /* Drop [12k, 20k) */
631         start = SZ_4K * 3;
632         end = SZ_16K + SZ_4K - 1;
633         btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false);
634         ret = validate_range(&BTRFS_I(inode)->extent_tree, 1);
635         if (ret)
636                 goto out;
637
638         /* Drop [28k, 32k) */
639         start = SZ_32K - SZ_4K;
640         end = SZ_32K - 1;
641         btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false);
642         ret = validate_range(&BTRFS_I(inode)->extent_tree, 2);
643         if (ret)
644                 goto out;
645
646         /* Drop [32k, 64k) */
647         start = SZ_32K;
648         end = SZ_64K - 1;
649         btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false);
650         ret = validate_range(&BTRFS_I(inode)->extent_tree, 3);
651         if (ret)
652                 goto out;
653 out:
654         iput(inode);
655         return ret;
656 }
657
658 /*
659  * Test the btrfs_add_extent_mapping helper which will attempt to create an em
660  * for areas between two existing ems.  Validate it doesn't do this when there
661  * are two unmerged em's side by side.
662  */
663 static int test_case_6(struct btrfs_fs_info *fs_info, struct extent_map_tree *em_tree)
664 {
665         struct extent_map *em = NULL;
666         int ret;
667
668         ret = add_compressed_extent(em_tree, 0, SZ_4K, 0);
669         if (ret)
670                 goto out;
671
672         ret = add_compressed_extent(em_tree, SZ_4K, SZ_4K, 0);
673         if (ret)
674                 goto out;
675
676         em = alloc_extent_map();
677         if (!em) {
678                 test_std_err(TEST_ALLOC_EXTENT_MAP);
679                 return -ENOMEM;
680         }
681
682         em->start = SZ_4K;
683         em->len = SZ_4K;
684         em->block_start = SZ_16K;
685         em->block_len = SZ_16K;
686         write_lock(&em_tree->lock);
687         ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, 0, SZ_8K);
688         write_unlock(&em_tree->lock);
689
690         if (ret != 0) {
691                 test_err("got an error when adding our em: %d", ret);
692                 goto out;
693         }
694
695         ret = -EINVAL;
696         if (em->start != 0) {
697                 test_err("unexpected em->start at %llu, wanted 0", em->start);
698                 goto out;
699         }
700         if (em->len != SZ_4K) {
701                 test_err("unexpected em->len %llu, expected 4K", em->len);
702                 goto out;
703         }
704         ret = 0;
705 out:
706         free_extent_map(em);
707         free_extent_map_tree(em_tree);
708         return ret;
709 }
710
711 /*
712  * Regression test for btrfs_drop_extent_map_range.  Calling with skip_pinned ==
713  * true would mess up the start/end calculations and subsequent splits would be
714  * incorrect.
715  */
716 static int test_case_7(void)
717 {
718         struct extent_map_tree *em_tree;
719         struct extent_map *em;
720         struct inode *inode;
721         int ret;
722
723         test_msg("Running btrfs_drop_extent_cache with pinned");
724
725         inode = btrfs_new_test_inode();
726         if (!inode) {
727                 test_std_err(TEST_ALLOC_INODE);
728                 return -ENOMEM;
729         }
730
731         em_tree = &BTRFS_I(inode)->extent_tree;
732
733         em = alloc_extent_map();
734         if (!em) {
735                 test_std_err(TEST_ALLOC_EXTENT_MAP);
736                 ret = -ENOMEM;
737                 goto out;
738         }
739
740         /* [0, 16K), pinned */
741         em->start = 0;
742         em->len = SZ_16K;
743         em->block_start = 0;
744         em->block_len = SZ_4K;
745         set_bit(EXTENT_FLAG_PINNED, &em->flags);
746         write_lock(&em_tree->lock);
747         ret = add_extent_mapping(em_tree, em, 0);
748         write_unlock(&em_tree->lock);
749         if (ret < 0) {
750                 test_err("couldn't add extent map");
751                 goto out;
752         }
753         free_extent_map(em);
754
755         em = alloc_extent_map();
756         if (!em) {
757                 test_std_err(TEST_ALLOC_EXTENT_MAP);
758                 ret = -ENOMEM;
759                 goto out;
760         }
761
762         /* [32K, 48K), not pinned */
763         em->start = SZ_32K;
764         em->len = SZ_16K;
765         em->block_start = SZ_32K;
766         em->block_len = SZ_16K;
767         write_lock(&em_tree->lock);
768         ret = add_extent_mapping(em_tree, em, 0);
769         write_unlock(&em_tree->lock);
770         if (ret < 0) {
771                 test_err("couldn't add extent map");
772                 goto out;
773         }
774         free_extent_map(em);
775
776         /*
777          * Drop [0, 36K) This should skip the [0, 4K) extent and then split the
778          * [32K, 48K) extent.
779          */
780         btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (36 * SZ_1K) - 1, true);
781
782         /* Make sure our extent maps look sane. */
783         ret = -EINVAL;
784
785         em = lookup_extent_mapping(em_tree, 0, SZ_16K);
786         if (!em) {
787                 test_err("didn't find an em at 0 as expected");
788                 goto out;
789         }
790
791         if (em->start != 0) {
792                 test_err("em->start is %llu, expected 0", em->start);
793                 goto out;
794         }
795
796         if (em->len != SZ_16K) {
797                 test_err("em->len is %llu, expected 16K", em->len);
798                 goto out;
799         }
800
801         free_extent_map(em);
802
803         read_lock(&em_tree->lock);
804         em = lookup_extent_mapping(em_tree, SZ_16K, SZ_16K);
805         read_unlock(&em_tree->lock);
806         if (em) {
807                 test_err("found an em when we weren't expecting one");
808                 goto out;
809         }
810
811         read_lock(&em_tree->lock);
812         em = lookup_extent_mapping(em_tree, SZ_32K, SZ_16K);
813         read_unlock(&em_tree->lock);
814         if (!em) {
815                 test_err("didn't find an em at 32K as expected");
816                 goto out;
817         }
818
819         if (em->start != (36 * SZ_1K)) {
820                 test_err("em->start is %llu, expected 36K", em->start);
821                 goto out;
822         }
823
824         if (em->len != (12 * SZ_1K)) {
825                 test_err("em->len is %llu, expected 12K", em->len);
826                 goto out;
827         }
828
829         free_extent_map(em);
830
831         read_lock(&em_tree->lock);
832         em = lookup_extent_mapping(em_tree, 48 * SZ_1K, (u64)-1);
833         read_unlock(&em_tree->lock);
834         if (em) {
835                 test_err("found an unexpected em above 48K");
836                 goto out;
837         }
838
839         ret = 0;
840 out:
841         free_extent_map(em);
842         iput(inode);
843         return ret;
844 }
845
846 struct rmap_test_vector {
847         u64 raid_type;
848         u64 physical_start;
849         u64 data_stripe_size;
850         u64 num_data_stripes;
851         u64 num_stripes;
852         /* Assume we won't have more than 5 physical stripes */
853         u64 data_stripe_phys_start[5];
854         bool expected_mapped_addr;
855         /* Physical to logical addresses */
856         u64 mapped_logical[5];
857 };
858
859 static int test_rmap_block(struct btrfs_fs_info *fs_info,
860                            struct rmap_test_vector *test)
861 {
862         struct extent_map *em;
863         struct map_lookup *map = NULL;
864         u64 *logical = NULL;
865         int i, out_ndaddrs, out_stripe_len;
866         int ret;
867
868         em = alloc_extent_map();
869         if (!em) {
870                 test_std_err(TEST_ALLOC_EXTENT_MAP);
871                 return -ENOMEM;
872         }
873
874         map = kmalloc(map_lookup_size(test->num_stripes), GFP_KERNEL);
875         if (!map) {
876                 kfree(em);
877                 test_std_err(TEST_ALLOC_EXTENT_MAP);
878                 return -ENOMEM;
879         }
880
881         set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
882         /* Start at 4GiB logical address */
883         em->start = SZ_4G;
884         em->len = test->data_stripe_size * test->num_data_stripes;
885         em->block_len = em->len;
886         em->orig_block_len = test->data_stripe_size;
887         em->map_lookup = map;
888
889         map->num_stripes = test->num_stripes;
890         map->type = test->raid_type;
891
892         for (i = 0; i < map->num_stripes; i++) {
893                 struct btrfs_device *dev = btrfs_alloc_dummy_device(fs_info);
894
895                 if (IS_ERR(dev)) {
896                         test_err("cannot allocate device");
897                         ret = PTR_ERR(dev);
898                         goto out;
899                 }
900                 map->stripes[i].dev = dev;
901                 map->stripes[i].physical = test->data_stripe_phys_start[i];
902         }
903
904         write_lock(&fs_info->mapping_tree.lock);
905         ret = add_extent_mapping(&fs_info->mapping_tree, em, 0);
906         write_unlock(&fs_info->mapping_tree.lock);
907         if (ret) {
908                 test_err("error adding block group mapping to mapping tree");
909                 goto out_free;
910         }
911
912         ret = btrfs_rmap_block(fs_info, em->start, btrfs_sb_offset(1),
913                                &logical, &out_ndaddrs, &out_stripe_len);
914         if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) {
915                 test_err("didn't rmap anything but expected %d",
916                          test->expected_mapped_addr);
917                 goto out;
918         }
919
920         if (out_stripe_len != BTRFS_STRIPE_LEN) {
921                 test_err("calculated stripe length doesn't match");
922                 goto out;
923         }
924
925         if (out_ndaddrs != test->expected_mapped_addr) {
926                 for (i = 0; i < out_ndaddrs; i++)
927                         test_msg("mapped %llu", logical[i]);
928                 test_err("unexpected number of mapped addresses: %d", out_ndaddrs);
929                 goto out;
930         }
931
932         for (i = 0; i < out_ndaddrs; i++) {
933                 if (logical[i] != test->mapped_logical[i]) {
934                         test_err("unexpected logical address mapped");
935                         goto out;
936                 }
937         }
938
939         ret = 0;
940 out:
941         write_lock(&fs_info->mapping_tree.lock);
942         remove_extent_mapping(&fs_info->mapping_tree, em);
943         write_unlock(&fs_info->mapping_tree.lock);
944         /* For us */
945         free_extent_map(em);
946 out_free:
947         /* For the tree */
948         free_extent_map(em);
949         kfree(logical);
950         return ret;
951 }
952
953 int btrfs_test_extent_map(void)
954 {
955         struct btrfs_fs_info *fs_info = NULL;
956         struct extent_map_tree *em_tree;
957         int ret = 0, i;
958         struct rmap_test_vector rmap_tests[] = {
959                 {
960                         /*
961                          * Test a chunk with 2 data stripes one of which
962                          * intersects the physical address of the super block
963                          * is correctly recognised.
964                          */
965                         .raid_type = BTRFS_BLOCK_GROUP_RAID1,
966                         .physical_start = SZ_64M - SZ_4M,
967                         .data_stripe_size = SZ_256M,
968                         .num_data_stripes = 2,
969                         .num_stripes = 2,
970                         .data_stripe_phys_start =
971                                 {SZ_64M - SZ_4M, SZ_64M - SZ_4M + SZ_256M},
972                         .expected_mapped_addr = true,
973                         .mapped_logical= {SZ_4G + SZ_4M}
974                 },
975                 {
976                         /*
977                          * Test that out-of-range physical addresses are
978                          * ignored
979                          */
980
981                          /* SINGLE chunk type */
982                         .raid_type = 0,
983                         .physical_start = SZ_4G,
984                         .data_stripe_size = SZ_256M,
985                         .num_data_stripes = 1,
986                         .num_stripes = 1,
987                         .data_stripe_phys_start = {SZ_256M},
988                         .expected_mapped_addr = false,
989                         .mapped_logical = {0}
990                 }
991         };
992
993         test_msg("running extent_map tests");
994
995         /*
996          * Note: the fs_info is not set up completely, we only need
997          * fs_info::fsid for the tracepoint.
998          */
999         fs_info = btrfs_alloc_dummy_fs_info(PAGE_SIZE, PAGE_SIZE);
1000         if (!fs_info) {
1001                 test_std_err(TEST_ALLOC_FS_INFO);
1002                 return -ENOMEM;
1003         }
1004
1005         em_tree = kzalloc(sizeof(*em_tree), GFP_KERNEL);
1006         if (!em_tree) {
1007                 ret = -ENOMEM;
1008                 goto out;
1009         }
1010
1011         extent_map_tree_init(em_tree);
1012
1013         ret = test_case_1(fs_info, em_tree);
1014         if (ret)
1015                 goto out;
1016         ret = test_case_2(fs_info, em_tree);
1017         if (ret)
1018                 goto out;
1019         ret = test_case_3(fs_info, em_tree);
1020         if (ret)
1021                 goto out;
1022         ret = test_case_4(fs_info, em_tree);
1023         if (ret)
1024                 goto out;
1025         ret = test_case_5();
1026         if (ret)
1027                 goto out;
1028         ret = test_case_6(fs_info, em_tree);
1029         if (ret)
1030                 goto out;
1031         ret = test_case_7();
1032         if (ret)
1033                 goto out;
1034
1035         test_msg("running rmap tests");
1036         for (i = 0; i < ARRAY_SIZE(rmap_tests); i++) {
1037                 ret = test_rmap_block(fs_info, &rmap_tests[i]);
1038                 if (ret)
1039                         goto out;
1040         }
1041
1042 out:
1043         kfree(em_tree);
1044         btrfs_free_dummy_fs_info(fs_info);
1045
1046         return ret;
1047 }