1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2013 Fusion IO. All rights reserved.
6 #include <linux/types.h>
7 #include "btrfs-tests.h"
9 #include "../btrfs_inode.h"
10 #include "../disk-io.h"
11 #include "../extent_io.h"
12 #include "../volumes.h"
13 #include "../compression.h"
15 static void insert_extent(struct btrfs_root
*root
, u64 start
, u64 len
,
16 u64 ram_bytes
, u64 offset
, u64 disk_bytenr
,
17 u64 disk_len
, u32 type
, u8 compression
, int slot
)
19 struct btrfs_path path
;
20 struct btrfs_file_extent_item
*fi
;
21 struct extent_buffer
*leaf
= root
->node
;
23 u32 value_len
= sizeof(struct btrfs_file_extent_item
);
25 if (type
== BTRFS_FILE_EXTENT_INLINE
)
27 memset(&path
, 0, sizeof(path
));
32 key
.objectid
= BTRFS_FIRST_FREE_OBJECTID
;
33 key
.type
= BTRFS_EXTENT_DATA_KEY
;
36 setup_items_for_insert(root
, &path
, &key
, &value_len
, 1);
37 fi
= btrfs_item_ptr(leaf
, slot
, struct btrfs_file_extent_item
);
38 btrfs_set_file_extent_generation(leaf
, fi
, 1);
39 btrfs_set_file_extent_type(leaf
, fi
, type
);
40 btrfs_set_file_extent_disk_bytenr(leaf
, fi
, disk_bytenr
);
41 btrfs_set_file_extent_disk_num_bytes(leaf
, fi
, disk_len
);
42 btrfs_set_file_extent_offset(leaf
, fi
, offset
);
43 btrfs_set_file_extent_num_bytes(leaf
, fi
, len
);
44 btrfs_set_file_extent_ram_bytes(leaf
, fi
, ram_bytes
);
45 btrfs_set_file_extent_compression(leaf
, fi
, compression
);
46 btrfs_set_file_extent_encryption(leaf
, fi
, 0);
47 btrfs_set_file_extent_other_encoding(leaf
, fi
, 0);
50 static void insert_inode_item_key(struct btrfs_root
*root
)
52 struct btrfs_path path
;
53 struct extent_buffer
*leaf
= root
->node
;
57 memset(&path
, 0, sizeof(path
));
62 key
.objectid
= BTRFS_INODE_ITEM_KEY
;
63 key
.type
= BTRFS_INODE_ITEM_KEY
;
66 setup_items_for_insert(root
, &path
, &key
, &value_len
, 1);
70 * Build the most complicated map of extents the earth has ever seen. We want
71 * this so we can test all of the corner cases of btrfs_get_extent. Here is a
72 * diagram of how the extents will look though this may not be possible we still
73 * want to make sure everything acts normally (the last number is not inclusive)
75 * [0 - 5][5 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291]
76 * [hole ][inline][hole but no extent][ hole ][ regular ][regular1 split]
78 * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ]
79 * [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written]
81 * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635]
82 * [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1]
84 * [69635-73731][ 73731 - 86019 ][86019-90115]
85 * [ regular ][ hole but no extent][ regular ]
87 static void setup_file_extents(struct btrfs_root
*root
, u32 sectorsize
)
90 u64 disk_bytenr
= SZ_1M
;
93 /* First we want a hole */
94 insert_extent(root
, offset
, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG
, 0,
100 * Now we want an inline extent, I don't think this is possible but hey
101 * why not? Also keep in mind if we have an inline extent it counts as
102 * the whole first page. If we were to expand it we would have to cow
103 * and we wouldn't have an inline extent anymore.
105 insert_extent(root
, offset
, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE
, 0,
110 /* Now another hole */
111 insert_extent(root
, offset
, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG
, 0,
116 /* Now for a regular extent */
117 insert_extent(root
, offset
, sectorsize
- 1, sectorsize
- 1, 0,
118 disk_bytenr
, sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
120 disk_bytenr
+= sectorsize
;
121 offset
+= sectorsize
- 1;
124 * Now for 3 extents that were split from a hole punch so we test
127 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
128 4 * sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
130 offset
+= sectorsize
;
131 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, 0, 0,
132 BTRFS_FILE_EXTENT_REG
, 0, slot
);
134 offset
+= sectorsize
;
135 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
136 2 * sectorsize
, disk_bytenr
, 4 * sectorsize
,
137 BTRFS_FILE_EXTENT_REG
, 0, slot
);
139 offset
+= 2 * sectorsize
;
140 disk_bytenr
+= 4 * sectorsize
;
142 /* Now for a unwritten prealloc extent */
143 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
144 sectorsize
, BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
146 offset
+= sectorsize
;
149 * We want to jack up disk_bytenr a little more so the em stuff doesn't
152 disk_bytenr
+= 2 * sectorsize
;
155 * Now for a partially written prealloc extent, basically the same as
156 * the hole punch example above. Ram_bytes never changes when you mark
157 * extents written btw.
159 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
160 4 * sectorsize
, BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
162 offset
+= sectorsize
;
163 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, sectorsize
,
164 disk_bytenr
, 4 * sectorsize
, BTRFS_FILE_EXTENT_REG
, 0,
167 offset
+= sectorsize
;
168 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
169 2 * sectorsize
, disk_bytenr
, 4 * sectorsize
,
170 BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
172 offset
+= 2 * sectorsize
;
173 disk_bytenr
+= 4 * sectorsize
;
175 /* Now a normal compressed extent */
176 insert_extent(root
, offset
, 2 * sectorsize
, 2 * sectorsize
, 0,
177 disk_bytenr
, sectorsize
, BTRFS_FILE_EXTENT_REG
,
178 BTRFS_COMPRESS_ZLIB
, slot
);
180 offset
+= 2 * sectorsize
;
182 disk_bytenr
+= 2 * sectorsize
;
184 /* Now a split compressed extent */
185 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
186 sectorsize
, BTRFS_FILE_EXTENT_REG
,
187 BTRFS_COMPRESS_ZLIB
, slot
);
189 offset
+= sectorsize
;
190 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0,
191 disk_bytenr
+ sectorsize
, sectorsize
,
192 BTRFS_FILE_EXTENT_REG
, 0, slot
);
194 offset
+= sectorsize
;
195 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
196 2 * sectorsize
, disk_bytenr
, sectorsize
,
197 BTRFS_FILE_EXTENT_REG
, BTRFS_COMPRESS_ZLIB
, slot
);
199 offset
+= 2 * sectorsize
;
200 disk_bytenr
+= 2 * sectorsize
;
202 /* Now extents that have a hole but no hole extent */
203 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
204 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
206 offset
+= 4 * sectorsize
;
207 disk_bytenr
+= sectorsize
;
208 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
209 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
212 static unsigned long prealloc_only
= 0;
213 static unsigned long compressed_only
= 0;
214 static unsigned long vacancy_only
= 0;
216 static noinline
int test_btrfs_get_extent(u32 sectorsize
, u32 nodesize
)
218 struct btrfs_fs_info
*fs_info
= NULL
;
219 struct inode
*inode
= NULL
;
220 struct btrfs_root
*root
= NULL
;
221 struct extent_map
*em
= NULL
;
227 test_msg("running btrfs_get_extent tests");
229 inode
= btrfs_new_test_inode();
231 test_std_err(TEST_ALLOC_INODE
);
235 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
237 test_std_err(TEST_ALLOC_FS_INFO
);
241 root
= btrfs_alloc_dummy_root(fs_info
);
243 test_std_err(TEST_ALLOC_ROOT
);
247 root
->node
= alloc_dummy_extent_buffer(fs_info
, nodesize
);
249 test_std_err(TEST_ALLOC_ROOT
);
253 btrfs_set_header_nritems(root
->node
, 0);
254 btrfs_set_header_level(root
->node
, 0);
257 /* First with no extents */
258 BTRFS_I(inode
)->root
= root
;
259 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, 0, sectorsize
);
262 test_err("got an error when we shouldn't have");
265 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
266 test_err("expected a hole, got %llu", em
->block_start
);
270 btrfs_drop_extent_cache(BTRFS_I(inode
), 0, (u64
)-1, 0);
273 * All of the magic numbers are based on the mapping setup in
274 * setup_file_extents, so if you change anything there you need to
275 * update the comment and update the expected values below.
277 setup_file_extents(root
, sectorsize
);
279 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, 0, (u64
)-1);
281 test_err("got an error when we shouldn't have");
284 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
285 test_err("expected a hole, got %llu", em
->block_start
);
288 if (em
->start
!= 0 || em
->len
!= 5) {
290 "unexpected extent wanted start 0 len 5, got start %llu len %llu",
294 if (em
->flags
!= 0) {
295 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
298 offset
= em
->start
+ em
->len
;
301 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
303 test_err("got an error when we shouldn't have");
306 if (em
->block_start
!= EXTENT_MAP_INLINE
) {
307 test_err("expected an inline, got %llu", em
->block_start
);
311 if (em
->start
!= offset
|| em
->len
!= (sectorsize
- 5)) {
313 "unexpected extent wanted start %llu len 1, got start %llu len %llu",
314 offset
, em
->start
, em
->len
);
317 if (em
->flags
!= 0) {
318 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
322 * We don't test anything else for inline since it doesn't get set
323 * unless we have a page for it to write into. Maybe we should change
326 offset
= em
->start
+ em
->len
;
329 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
331 test_err("got an error when we shouldn't have");
334 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
335 test_err("expected a hole, got %llu", em
->block_start
);
338 if (em
->start
!= offset
|| em
->len
!= 4) {
340 "unexpected extent wanted start %llu len 4, got start %llu len %llu",
341 offset
, em
->start
, em
->len
);
344 if (em
->flags
!= 0) {
345 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
348 offset
= em
->start
+ em
->len
;
352 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
354 test_err("got an error when we shouldn't have");
357 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
358 test_err("expected a real extent, got %llu", em
->block_start
);
361 if (em
->start
!= offset
|| em
->len
!= sectorsize
- 1) {
363 "unexpected extent wanted start %llu len 4095, got start %llu len %llu",
364 offset
, em
->start
, em
->len
);
367 if (em
->flags
!= 0) {
368 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
371 if (em
->orig_start
!= em
->start
) {
372 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
376 offset
= em
->start
+ em
->len
;
379 /* The next 3 are split extents */
380 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
382 test_err("got an error when we shouldn't have");
385 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
386 test_err("expected a real extent, got %llu", em
->block_start
);
389 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
391 "unexpected extent start %llu len %u, got start %llu len %llu",
392 offset
, sectorsize
, em
->start
, em
->len
);
395 if (em
->flags
!= 0) {
396 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
399 if (em
->orig_start
!= em
->start
) {
400 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
404 disk_bytenr
= em
->block_start
;
405 orig_start
= em
->start
;
406 offset
= em
->start
+ em
->len
;
409 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
411 test_err("got an error when we shouldn't have");
414 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
415 test_err("expected a hole, got %llu", em
->block_start
);
418 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
420 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
421 offset
, sectorsize
, em
->start
, em
->len
);
424 if (em
->flags
!= 0) {
425 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
428 offset
= em
->start
+ em
->len
;
431 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
433 test_err("got an error when we shouldn't have");
436 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
437 test_err("expected a real extent, got %llu", em
->block_start
);
440 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
442 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
443 offset
, 2 * sectorsize
, em
->start
, em
->len
);
446 if (em
->flags
!= 0) {
447 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
450 if (em
->orig_start
!= orig_start
) {
451 test_err("wrong orig offset, want %llu, have %llu",
452 orig_start
, em
->orig_start
);
455 disk_bytenr
+= (em
->start
- orig_start
);
456 if (em
->block_start
!= disk_bytenr
) {
457 test_err("wrong block start, want %llu, have %llu",
458 disk_bytenr
, em
->block_start
);
461 offset
= em
->start
+ em
->len
;
464 /* Prealloc extent */
465 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
467 test_err("got an error when we shouldn't have");
470 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
471 test_err("expected a real extent, got %llu", em
->block_start
);
474 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
476 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
477 offset
, sectorsize
, em
->start
, em
->len
);
480 if (em
->flags
!= prealloc_only
) {
481 test_err("unexpected flags set, want %lu have %lu",
482 prealloc_only
, em
->flags
);
485 if (em
->orig_start
!= em
->start
) {
486 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
490 offset
= em
->start
+ em
->len
;
493 /* The next 3 are a half written prealloc extent */
494 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
496 test_err("got an error when we shouldn't have");
499 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
500 test_err("expected a real extent, got %llu", em
->block_start
);
503 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
505 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
506 offset
, sectorsize
, em
->start
, em
->len
);
509 if (em
->flags
!= prealloc_only
) {
510 test_err("unexpected flags set, want %lu have %lu",
511 prealloc_only
, em
->flags
);
514 if (em
->orig_start
!= em
->start
) {
515 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
519 disk_bytenr
= em
->block_start
;
520 orig_start
= em
->start
;
521 offset
= em
->start
+ em
->len
;
524 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
526 test_err("got an error when we shouldn't have");
529 if (em
->block_start
>= EXTENT_MAP_HOLE
) {
530 test_err("expected a real extent, got %llu", em
->block_start
);
533 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
535 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
536 offset
, sectorsize
, em
->start
, em
->len
);
539 if (em
->flags
!= 0) {
540 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
543 if (em
->orig_start
!= orig_start
) {
544 test_err("unexpected orig offset, wanted %llu, have %llu",
545 orig_start
, em
->orig_start
);
548 if (em
->block_start
!= (disk_bytenr
+ (em
->start
- em
->orig_start
))) {
549 test_err("unexpected block start, wanted %llu, have %llu",
550 disk_bytenr
+ (em
->start
- em
->orig_start
),
554 offset
= em
->start
+ em
->len
;
557 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
559 test_err("got an error when we shouldn't have");
562 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
563 test_err("expected a real extent, got %llu", em
->block_start
);
566 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
568 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
569 offset
, 2 * sectorsize
, em
->start
, em
->len
);
572 if (em
->flags
!= prealloc_only
) {
573 test_err("unexpected flags set, want %lu have %lu",
574 prealloc_only
, em
->flags
);
577 if (em
->orig_start
!= orig_start
) {
578 test_err("wrong orig offset, want %llu, have %llu", orig_start
,
582 if (em
->block_start
!= (disk_bytenr
+ (em
->start
- em
->orig_start
))) {
583 test_err("unexpected block start, wanted %llu, have %llu",
584 disk_bytenr
+ (em
->start
- em
->orig_start
),
588 offset
= em
->start
+ em
->len
;
591 /* Now for the compressed extent */
592 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
594 test_err("got an error when we shouldn't have");
597 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
598 test_err("expected a real extent, got %llu", em
->block_start
);
601 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
603 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
604 offset
, 2 * sectorsize
, em
->start
, em
->len
);
607 if (em
->flags
!= compressed_only
) {
608 test_err("unexpected flags set, want %lu have %lu",
609 compressed_only
, em
->flags
);
612 if (em
->orig_start
!= em
->start
) {
613 test_err("wrong orig offset, want %llu, have %llu",
614 em
->start
, em
->orig_start
);
617 if (em
->compress_type
!= BTRFS_COMPRESS_ZLIB
) {
618 test_err("unexpected compress type, wanted %d, got %d",
619 BTRFS_COMPRESS_ZLIB
, em
->compress_type
);
622 offset
= em
->start
+ em
->len
;
625 /* Split compressed extent */
626 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
628 test_err("got an error when we shouldn't have");
631 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
632 test_err("expected a real extent, got %llu", em
->block_start
);
635 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
637 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
638 offset
, sectorsize
, em
->start
, em
->len
);
641 if (em
->flags
!= compressed_only
) {
642 test_err("unexpected flags set, want %lu have %lu",
643 compressed_only
, em
->flags
);
646 if (em
->orig_start
!= em
->start
) {
647 test_err("wrong orig offset, want %llu, have %llu",
648 em
->start
, em
->orig_start
);
651 if (em
->compress_type
!= BTRFS_COMPRESS_ZLIB
) {
652 test_err("unexpected compress type, wanted %d, got %d",
653 BTRFS_COMPRESS_ZLIB
, em
->compress_type
);
656 disk_bytenr
= em
->block_start
;
657 orig_start
= em
->start
;
658 offset
= em
->start
+ em
->len
;
661 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
663 test_err("got an error when we shouldn't have");
666 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
667 test_err("expected a real extent, got %llu", em
->block_start
);
670 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
672 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
673 offset
, sectorsize
, em
->start
, em
->len
);
676 if (em
->flags
!= 0) {
677 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
680 if (em
->orig_start
!= em
->start
) {
681 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
685 offset
= em
->start
+ em
->len
;
688 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
690 test_err("got an error when we shouldn't have");
693 if (em
->block_start
!= disk_bytenr
) {
694 test_err("block start does not match, want %llu got %llu",
695 disk_bytenr
, em
->block_start
);
698 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
700 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
701 offset
, 2 * sectorsize
, em
->start
, em
->len
);
704 if (em
->flags
!= compressed_only
) {
705 test_err("unexpected flags set, want %lu have %lu",
706 compressed_only
, em
->flags
);
709 if (em
->orig_start
!= orig_start
) {
710 test_err("wrong orig offset, want %llu, have %llu",
711 em
->start
, orig_start
);
714 if (em
->compress_type
!= BTRFS_COMPRESS_ZLIB
) {
715 test_err("unexpected compress type, wanted %d, got %d",
716 BTRFS_COMPRESS_ZLIB
, em
->compress_type
);
719 offset
= em
->start
+ em
->len
;
722 /* A hole between regular extents but no hole extent */
723 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
+ 6, sectorsize
);
725 test_err("got an error when we shouldn't have");
728 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
729 test_err("expected a real extent, got %llu", em
->block_start
);
732 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
734 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
735 offset
, sectorsize
, em
->start
, em
->len
);
738 if (em
->flags
!= 0) {
739 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
742 if (em
->orig_start
!= em
->start
) {
743 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
747 offset
= em
->start
+ em
->len
;
750 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, SZ_4M
);
752 test_err("got an error when we shouldn't have");
755 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
756 test_err("expected a hole extent, got %llu", em
->block_start
);
760 * Currently we just return a length that we requested rather than the
761 * length of the actual hole, if this changes we'll have to change this
764 if (em
->start
!= offset
|| em
->len
!= 3 * sectorsize
) {
766 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
767 offset
, 3 * sectorsize
, em
->start
, em
->len
);
770 if (em
->flags
!= vacancy_only
) {
771 test_err("unexpected flags set, want %lu have %lu",
772 vacancy_only
, em
->flags
);
775 if (em
->orig_start
!= em
->start
) {
776 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
780 offset
= em
->start
+ em
->len
;
783 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, offset
, sectorsize
);
785 test_err("got an error when we shouldn't have");
788 if (em
->block_start
>= EXTENT_MAP_LAST_BYTE
) {
789 test_err("expected a real extent, got %llu", em
->block_start
);
792 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
794 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
795 offset
, sectorsize
, em
->start
, em
->len
);
798 if (em
->flags
!= 0) {
799 test_err("unexpected flags set, want 0 have %lu", em
->flags
);
802 if (em
->orig_start
!= em
->start
) {
803 test_err("wrong orig offset, want %llu, have %llu", em
->start
,
812 btrfs_free_dummy_root(root
);
813 btrfs_free_dummy_fs_info(fs_info
);
817 static int test_hole_first(u32 sectorsize
, u32 nodesize
)
819 struct btrfs_fs_info
*fs_info
= NULL
;
820 struct inode
*inode
= NULL
;
821 struct btrfs_root
*root
= NULL
;
822 struct extent_map
*em
= NULL
;
825 test_msg("running hole first btrfs_get_extent test");
827 inode
= btrfs_new_test_inode();
829 test_std_err(TEST_ALLOC_INODE
);
833 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
835 test_std_err(TEST_ALLOC_FS_INFO
);
839 root
= btrfs_alloc_dummy_root(fs_info
);
841 test_std_err(TEST_ALLOC_ROOT
);
845 root
->node
= alloc_dummy_extent_buffer(fs_info
, nodesize
);
847 test_std_err(TEST_ALLOC_ROOT
);
851 btrfs_set_header_nritems(root
->node
, 0);
852 btrfs_set_header_level(root
->node
, 0);
853 BTRFS_I(inode
)->root
= root
;
857 * Need a blank inode item here just so we don't confuse
860 insert_inode_item_key(root
);
861 insert_extent(root
, sectorsize
, sectorsize
, sectorsize
, 0, sectorsize
,
862 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, 1);
863 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, 0, 2 * sectorsize
);
865 test_err("got an error when we shouldn't have");
868 if (em
->block_start
!= EXTENT_MAP_HOLE
) {
869 test_err("expected a hole, got %llu", em
->block_start
);
872 if (em
->start
!= 0 || em
->len
!= sectorsize
) {
874 "unexpected extent wanted start 0 len %u, got start %llu len %llu",
875 sectorsize
, em
->start
, em
->len
);
878 if (em
->flags
!= vacancy_only
) {
879 test_err("wrong flags, wanted %lu, have %lu", vacancy_only
,
885 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, sectorsize
, 2 * sectorsize
);
887 test_err("got an error when we shouldn't have");
890 if (em
->block_start
!= sectorsize
) {
891 test_err("expected a real extent, got %llu", em
->block_start
);
894 if (em
->start
!= sectorsize
|| em
->len
!= sectorsize
) {
896 "unexpected extent wanted start %u len %u, got start %llu len %llu",
897 sectorsize
, sectorsize
, em
->start
, em
->len
);
900 if (em
->flags
!= 0) {
901 test_err("unexpected flags set, wanted 0 got %lu",
910 btrfs_free_dummy_root(root
);
911 btrfs_free_dummy_fs_info(fs_info
);
915 static int test_extent_accounting(u32 sectorsize
, u32 nodesize
)
917 struct btrfs_fs_info
*fs_info
= NULL
;
918 struct inode
*inode
= NULL
;
919 struct btrfs_root
*root
= NULL
;
922 test_msg("running outstanding_extents tests");
924 inode
= btrfs_new_test_inode();
926 test_std_err(TEST_ALLOC_INODE
);
930 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
932 test_std_err(TEST_ALLOC_FS_INFO
);
936 root
= btrfs_alloc_dummy_root(fs_info
);
938 test_std_err(TEST_ALLOC_ROOT
);
942 BTRFS_I(inode
)->root
= root
;
944 /* [BTRFS_MAX_EXTENT_SIZE] */
945 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), 0,
946 BTRFS_MAX_EXTENT_SIZE
- 1, 0, NULL
);
948 test_err("btrfs_set_extent_delalloc returned %d", ret
);
951 if (BTRFS_I(inode
)->outstanding_extents
!= 1) {
953 test_err("miscount, wanted 1, got %u",
954 BTRFS_I(inode
)->outstanding_extents
);
958 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
959 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), BTRFS_MAX_EXTENT_SIZE
,
960 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
- 1,
963 test_err("btrfs_set_extent_delalloc returned %d", ret
);
966 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
968 test_err("miscount, wanted 2, got %u",
969 BTRFS_I(inode
)->outstanding_extents
);
973 /* [BTRFS_MAX_EXTENT_SIZE/2][sectorsize HOLE][the rest] */
974 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
,
975 BTRFS_MAX_EXTENT_SIZE
>> 1,
976 (BTRFS_MAX_EXTENT_SIZE
>> 1) + sectorsize
- 1,
977 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
978 EXTENT_UPTODATE
, 0, 0, NULL
);
980 test_err("clear_extent_bit returned %d", ret
);
983 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
985 test_err("miscount, wanted 2, got %u",
986 BTRFS_I(inode
)->outstanding_extents
);
990 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
991 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), BTRFS_MAX_EXTENT_SIZE
>> 1,
992 (BTRFS_MAX_EXTENT_SIZE
>> 1)
996 test_err("btrfs_set_extent_delalloc returned %d", ret
);
999 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
1001 test_err("miscount, wanted 2, got %u",
1002 BTRFS_I(inode
)->outstanding_extents
);
1007 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize HOLE][BTRFS_MAX_EXTENT_SIZE+sectorsize]
1009 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
1010 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
,
1011 (BTRFS_MAX_EXTENT_SIZE
<< 1) + 3 * sectorsize
- 1,
1014 test_err("btrfs_set_extent_delalloc returned %d", ret
);
1017 if (BTRFS_I(inode
)->outstanding_extents
!= 4) {
1019 test_err("miscount, wanted 4, got %u",
1020 BTRFS_I(inode
)->outstanding_extents
);
1025 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize]
1027 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
1028 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1029 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1, 0, NULL
);
1031 test_err("btrfs_set_extent_delalloc returned %d", ret
);
1034 if (BTRFS_I(inode
)->outstanding_extents
!= 3) {
1036 test_err("miscount, wanted 3, got %u",
1037 BTRFS_I(inode
)->outstanding_extents
);
1041 /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */
1042 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
,
1043 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1044 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1,
1045 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1046 EXTENT_UPTODATE
, 0, 0, NULL
);
1048 test_err("clear_extent_bit returned %d", ret
);
1051 if (BTRFS_I(inode
)->outstanding_extents
!= 4) {
1053 test_err("miscount, wanted 4, got %u",
1054 BTRFS_I(inode
)->outstanding_extents
);
1059 * Refill the hole again just for good measure, because I thought it
1060 * might fail and I'd rather satisfy my paranoia at this point.
1062 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
1063 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1064 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1, 0, NULL
);
1066 test_err("btrfs_set_extent_delalloc returned %d", ret
);
1069 if (BTRFS_I(inode
)->outstanding_extents
!= 3) {
1071 test_err("miscount, wanted 3, got %u",
1072 BTRFS_I(inode
)->outstanding_extents
);
1077 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
, 0, (u64
)-1,
1078 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1079 EXTENT_UPTODATE
, 0, 0, NULL
);
1081 test_err("clear_extent_bit returned %d", ret
);
1084 if (BTRFS_I(inode
)->outstanding_extents
) {
1086 test_err("miscount, wanted 0, got %u",
1087 BTRFS_I(inode
)->outstanding_extents
);
1093 clear_extent_bit(&BTRFS_I(inode
)->io_tree
, 0, (u64
)-1,
1094 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1095 EXTENT_UPTODATE
, 0, 0, NULL
);
1097 btrfs_free_dummy_root(root
);
1098 btrfs_free_dummy_fs_info(fs_info
);
1102 int btrfs_test_inodes(u32 sectorsize
, u32 nodesize
)
1106 test_msg("running inode tests");
1108 set_bit(EXTENT_FLAG_COMPRESSED
, &compressed_only
);
1109 set_bit(EXTENT_FLAG_PREALLOC
, &prealloc_only
);
1111 ret
= test_btrfs_get_extent(sectorsize
, nodesize
);
1114 ret
= test_hole_first(sectorsize
, nodesize
);
1117 return test_extent_accounting(sectorsize
, nodesize
);