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