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"
14 #include "../accessors.h"
16 static void insert_extent(struct btrfs_root
*root
, u64 start
, u64 len
,
17 u64 ram_bytes
, u64 offset
, u64 disk_bytenr
,
18 u64 disk_len
, u32 type
, u8 compression
, int slot
)
20 struct btrfs_path path
;
21 struct btrfs_file_extent_item
*fi
;
22 struct extent_buffer
*leaf
= root
->node
;
24 u32 value_len
= sizeof(struct btrfs_file_extent_item
);
26 if (type
== BTRFS_FILE_EXTENT_INLINE
)
28 memset(&path
, 0, sizeof(path
));
33 key
.objectid
= BTRFS_FIRST_FREE_OBJECTID
;
34 key
.type
= BTRFS_EXTENT_DATA_KEY
;
38 * Passing a NULL trans handle is fine here, we have a dummy root eb
39 * and the tree is a single node (level 0).
41 btrfs_setup_item_for_insert(NULL
, root
, &path
, &key
, value_len
);
42 fi
= btrfs_item_ptr(leaf
, slot
, struct btrfs_file_extent_item
);
43 btrfs_set_file_extent_generation(leaf
, fi
, 1);
44 btrfs_set_file_extent_type(leaf
, fi
, type
);
45 btrfs_set_file_extent_disk_bytenr(leaf
, fi
, disk_bytenr
);
46 btrfs_set_file_extent_disk_num_bytes(leaf
, fi
, disk_len
);
47 btrfs_set_file_extent_offset(leaf
, fi
, offset
);
48 btrfs_set_file_extent_num_bytes(leaf
, fi
, len
);
49 btrfs_set_file_extent_ram_bytes(leaf
, fi
, ram_bytes
);
50 btrfs_set_file_extent_compression(leaf
, fi
, compression
);
51 btrfs_set_file_extent_encryption(leaf
, fi
, 0);
52 btrfs_set_file_extent_other_encoding(leaf
, fi
, 0);
55 static void insert_inode_item_key(struct btrfs_root
*root
)
57 struct btrfs_path path
;
58 struct extent_buffer
*leaf
= root
->node
;
62 memset(&path
, 0, sizeof(path
));
67 key
.objectid
= BTRFS_INODE_ITEM_KEY
;
68 key
.type
= BTRFS_INODE_ITEM_KEY
;
72 * Passing a NULL trans handle is fine here, we have a dummy root eb
73 * and the tree is a single node (level 0).
75 btrfs_setup_item_for_insert(NULL
, root
, &path
, &key
, value_len
);
79 * Build the most complicated map of extents the earth has ever seen. We want
80 * this so we can test all of the corner cases of btrfs_get_extent. Here is a
81 * diagram of how the extents will look though this may not be possible we still
82 * want to make sure everything acts normally (the last number is not inclusive)
84 * [0 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291]
85 * [inline][hole but no extent][ hole ][ regular ][regular1 split]
87 * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ]
88 * [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written]
90 * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635]
91 * [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1]
93 * [69635-73731][ 73731 - 86019 ][86019-90115]
94 * [ regular ][ hole but no extent][ regular ]
96 static void setup_file_extents(struct btrfs_root
*root
, u32 sectorsize
)
99 u64 disk_bytenr
= SZ_1M
;
103 * Tree-checker has strict limits on inline extents that they can only
104 * exist at file offset 0, thus we can only have one inline file extent
107 insert_extent(root
, offset
, 6, 6, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE
, 0,
112 /* Now another hole */
113 insert_extent(root
, offset
, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG
, 0,
118 /* Now for a regular extent */
119 insert_extent(root
, offset
, sectorsize
- 1, sectorsize
- 1, 0,
120 disk_bytenr
, sectorsize
- 1, BTRFS_FILE_EXTENT_REG
, 0, slot
);
122 disk_bytenr
+= sectorsize
;
123 offset
+= sectorsize
- 1;
126 * Now for 3 extents that were split from a hole punch so we test
129 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
130 4 * sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
132 offset
+= sectorsize
;
133 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, 0, 0,
134 BTRFS_FILE_EXTENT_REG
, 0, slot
);
136 offset
+= sectorsize
;
137 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
138 2 * sectorsize
, disk_bytenr
, 4 * sectorsize
,
139 BTRFS_FILE_EXTENT_REG
, 0, slot
);
141 offset
+= 2 * sectorsize
;
142 disk_bytenr
+= 4 * sectorsize
;
144 /* Now for a unwritten prealloc extent */
145 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
146 sectorsize
, BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
148 offset
+= sectorsize
;
151 * We want to jack up disk_bytenr a little more so the em stuff doesn't
154 disk_bytenr
+= 2 * sectorsize
;
157 * Now for a partially written prealloc extent, basically the same as
158 * the hole punch example above. Ram_bytes never changes when you mark
159 * extents written btw.
161 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
162 4 * sectorsize
, BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
164 offset
+= sectorsize
;
165 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, sectorsize
,
166 disk_bytenr
, 4 * sectorsize
, BTRFS_FILE_EXTENT_REG
, 0,
169 offset
+= sectorsize
;
170 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
171 2 * sectorsize
, disk_bytenr
, 4 * sectorsize
,
172 BTRFS_FILE_EXTENT_PREALLOC
, 0, slot
);
174 offset
+= 2 * sectorsize
;
175 disk_bytenr
+= 4 * sectorsize
;
177 /* Now a normal compressed extent */
178 insert_extent(root
, offset
, 2 * sectorsize
, 2 * sectorsize
, 0,
179 disk_bytenr
, sectorsize
, BTRFS_FILE_EXTENT_REG
,
180 BTRFS_COMPRESS_ZLIB
, slot
);
182 offset
+= 2 * sectorsize
;
184 disk_bytenr
+= 2 * sectorsize
;
186 /* Now a split compressed extent */
187 insert_extent(root
, offset
, sectorsize
, 4 * sectorsize
, 0, disk_bytenr
,
188 sectorsize
, BTRFS_FILE_EXTENT_REG
,
189 BTRFS_COMPRESS_ZLIB
, slot
);
191 offset
+= sectorsize
;
192 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0,
193 disk_bytenr
+ sectorsize
, sectorsize
,
194 BTRFS_FILE_EXTENT_REG
, 0, slot
);
196 offset
+= sectorsize
;
197 insert_extent(root
, offset
, 2 * sectorsize
, 4 * sectorsize
,
198 2 * sectorsize
, disk_bytenr
, sectorsize
,
199 BTRFS_FILE_EXTENT_REG
, BTRFS_COMPRESS_ZLIB
, slot
);
201 offset
+= 2 * sectorsize
;
202 disk_bytenr
+= 2 * sectorsize
;
204 /* Now extents that have a hole but no hole extent */
205 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
206 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
208 offset
+= 4 * sectorsize
;
209 disk_bytenr
+= sectorsize
;
210 insert_extent(root
, offset
, sectorsize
, sectorsize
, 0, disk_bytenr
,
211 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, slot
);
214 static u32 prealloc_only
= 0;
215 static u32 compressed_only
= 0;
216 static u32 vacancy_only
= 0;
218 static noinline
int test_btrfs_get_extent(u32 sectorsize
, u32 nodesize
)
220 struct btrfs_fs_info
*fs_info
= NULL
;
221 struct inode
*inode
= NULL
;
222 struct btrfs_root
*root
= NULL
;
223 struct extent_map
*em
= NULL
;
229 test_msg("running btrfs_get_extent tests");
231 inode
= btrfs_new_test_inode();
233 test_std_err(TEST_ALLOC_INODE
);
237 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
239 test_std_err(TEST_ALLOC_FS_INFO
);
243 root
= btrfs_alloc_dummy_root(fs_info
);
245 test_std_err(TEST_ALLOC_ROOT
);
249 root
->node
= alloc_dummy_extent_buffer(fs_info
, nodesize
);
251 test_std_err(TEST_ALLOC_ROOT
);
255 btrfs_set_header_nritems(root
->node
, 0);
256 btrfs_set_header_level(root
->node
, 0);
259 /* First with no extents */
260 BTRFS_I(inode
)->root
= root
;
261 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, sectorsize
);
264 test_err("got an error when we shouldn't have");
267 if (em
->disk_bytenr
!= EXTENT_MAP_HOLE
) {
268 test_err("expected a hole, got %llu", em
->disk_bytenr
);
272 btrfs_drop_extent_map_range(BTRFS_I(inode
), 0, (u64
)-1, false);
275 * All of the magic numbers are based on the mapping setup in
276 * setup_file_extents, so if you change anything there you need to
277 * update the comment and update the expected values below.
279 setup_file_extents(root
, sectorsize
);
281 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, (u64
)-1);
283 test_err("got an error when we shouldn't have");
286 if (em
->disk_bytenr
!= EXTENT_MAP_INLINE
) {
287 test_err("expected an inline, got %llu", em
->disk_bytenr
);
292 * For inline extent, we always round up the em to sectorsize, as
296 * The range will be zeroed at inline extent read time.
298 * b) a file extent with unaligned bytenr
299 * Tree checker will reject it.
301 if (em
->start
!= 0 || em
->len
!= sectorsize
) {
303 "unexpected extent wanted start 0 len %u, got start %llu len %llu",
304 sectorsize
, em
->start
, em
->len
);
307 if (em
->flags
!= 0) {
308 test_err("unexpected flags set, want 0 have %u", em
->flags
);
312 * We don't test anything else for inline since it doesn't get set
313 * unless we have a page for it to write into. Maybe we should change
316 offset
= em
->start
+ em
->len
;
319 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
321 test_err("got an error when we shouldn't have");
324 if (em
->disk_bytenr
!= EXTENT_MAP_HOLE
) {
325 test_err("expected a hole, got %llu", em
->disk_bytenr
);
328 if (em
->start
!= offset
|| em
->len
!= 4) {
330 "unexpected extent wanted start %llu len 4, got start %llu len %llu",
331 offset
, em
->start
, em
->len
);
334 if (em
->flags
!= 0) {
335 test_err("unexpected flags set, want 0 have %u", em
->flags
);
338 offset
= em
->start
+ em
->len
;
342 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
344 test_err("got an error when we shouldn't have");
347 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
348 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
351 if (em
->start
!= offset
|| em
->len
!= sectorsize
- 1) {
353 "unexpected extent wanted start %llu len 4095, got start %llu len %llu",
354 offset
, em
->start
, em
->len
);
357 if (em
->flags
!= 0) {
358 test_err("unexpected flags set, want 0 have %u", em
->flags
);
361 if (em
->offset
!= 0) {
362 test_err("wrong offset, want 0, have %llu", em
->offset
);
365 offset
= em
->start
+ em
->len
;
368 /* The next 3 are split extents */
369 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
371 test_err("got an error when we shouldn't have");
374 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
375 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
378 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
380 "unexpected extent start %llu len %u, got start %llu len %llu",
381 offset
, sectorsize
, em
->start
, em
->len
);
384 if (em
->flags
!= 0) {
385 test_err("unexpected flags set, want 0 have %u", em
->flags
);
388 if (em
->offset
!= 0) {
389 test_err("wrong offset, want 0, have %llu", em
->offset
);
392 disk_bytenr
= extent_map_block_start(em
);
393 orig_start
= em
->start
;
394 offset
= em
->start
+ em
->len
;
397 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
399 test_err("got an error when we shouldn't have");
402 if (em
->disk_bytenr
!= EXTENT_MAP_HOLE
) {
403 test_err("expected a hole, got %llu", em
->disk_bytenr
);
406 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
408 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
409 offset
, sectorsize
, em
->start
, em
->len
);
412 if (em
->flags
!= 0) {
413 test_err("unexpected flags set, want 0 have %u", em
->flags
);
416 offset
= em
->start
+ em
->len
;
419 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
421 test_err("got an error when we shouldn't have");
424 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
425 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
428 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
430 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
431 offset
, 2 * sectorsize
, em
->start
, em
->len
);
434 if (em
->flags
!= 0) {
435 test_err("unexpected flags set, want 0 have %u", em
->flags
);
438 if (em
->start
- em
->offset
!= orig_start
) {
439 test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
440 em
->start
, em
->offset
, orig_start
);
443 disk_bytenr
+= (em
->start
- orig_start
);
444 if (extent_map_block_start(em
) != disk_bytenr
) {
445 test_err("wrong block start, want %llu, have %llu",
446 disk_bytenr
, extent_map_block_start(em
));
449 offset
= em
->start
+ em
->len
;
452 /* Prealloc extent */
453 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
455 test_err("got an error when we shouldn't have");
458 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
459 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
462 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
464 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
465 offset
, sectorsize
, em
->start
, em
->len
);
468 if (em
->flags
!= prealloc_only
) {
469 test_err("unexpected flags set, want %u have %u",
470 prealloc_only
, em
->flags
);
473 if (em
->offset
!= 0) {
474 test_err("wrong offset, want 0, have %llu", em
->offset
);
477 offset
= em
->start
+ em
->len
;
480 /* The next 3 are a half written prealloc extent */
481 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
483 test_err("got an error when we shouldn't have");
486 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
487 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
490 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
492 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
493 offset
, sectorsize
, em
->start
, em
->len
);
496 if (em
->flags
!= prealloc_only
) {
497 test_err("unexpected flags set, want %u have %u",
498 prealloc_only
, em
->flags
);
501 if (em
->offset
!= 0) {
502 test_err("wrong offset, want 0, have %llu", em
->offset
);
505 disk_bytenr
= extent_map_block_start(em
);
506 orig_start
= em
->start
;
507 offset
= em
->start
+ em
->len
;
510 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
512 test_err("got an error when we shouldn't have");
515 if (em
->disk_bytenr
>= EXTENT_MAP_HOLE
) {
516 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
519 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
521 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
522 offset
, sectorsize
, em
->start
, em
->len
);
525 if (em
->flags
!= 0) {
526 test_err("unexpected flags set, want 0 have %u", em
->flags
);
529 if (em
->start
- em
->offset
!= orig_start
) {
530 test_err("unexpected offset, wanted %llu, have %llu",
531 em
->start
- orig_start
, em
->offset
);
534 if (extent_map_block_start(em
) != disk_bytenr
+ em
->offset
) {
535 test_err("unexpected block start, wanted %llu, have %llu",
536 disk_bytenr
+ em
->offset
, extent_map_block_start(em
));
539 offset
= em
->start
+ em
->len
;
542 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
544 test_err("got an error when we shouldn't have");
547 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
548 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
551 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
553 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
554 offset
, 2 * sectorsize
, em
->start
, em
->len
);
557 if (em
->flags
!= prealloc_only
) {
558 test_err("unexpected flags set, want %u have %u",
559 prealloc_only
, em
->flags
);
562 if (em
->start
- em
->offset
!= orig_start
) {
563 test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
564 em
->start
, em
->offset
, orig_start
);
567 if (extent_map_block_start(em
) != disk_bytenr
+ em
->offset
) {
568 test_err("unexpected block start, wanted %llu, have %llu",
569 disk_bytenr
+ em
->offset
, extent_map_block_start(em
));
572 offset
= em
->start
+ em
->len
;
575 /* Now for the compressed extent */
576 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
578 test_err("got an error when we shouldn't have");
581 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
582 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
585 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
587 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
588 offset
, 2 * sectorsize
, em
->start
, em
->len
);
591 if (em
->flags
!= compressed_only
) {
592 test_err("unexpected flags set, want %u have %u",
593 compressed_only
, em
->flags
);
596 if (em
->offset
!= 0) {
597 test_err("wrong offset, want 0, have %llu", em
->offset
);
600 if (extent_map_compression(em
) != BTRFS_COMPRESS_ZLIB
) {
601 test_err("unexpected compress type, wanted %d, got %d",
602 BTRFS_COMPRESS_ZLIB
, extent_map_compression(em
));
605 offset
= em
->start
+ em
->len
;
608 /* Split compressed extent */
609 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
611 test_err("got an error when we shouldn't have");
614 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
615 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
618 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
620 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
621 offset
, sectorsize
, em
->start
, em
->len
);
624 if (em
->flags
!= compressed_only
) {
625 test_err("unexpected flags set, want %u have %u",
626 compressed_only
, em
->flags
);
629 if (em
->offset
!= 0) {
630 test_err("wrong offset, want 0, have %llu", em
->offset
);
633 if (extent_map_compression(em
) != BTRFS_COMPRESS_ZLIB
) {
634 test_err("unexpected compress type, wanted %d, got %d",
635 BTRFS_COMPRESS_ZLIB
, extent_map_compression(em
));
638 disk_bytenr
= extent_map_block_start(em
);
639 orig_start
= em
->start
;
640 offset
= em
->start
+ em
->len
;
643 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
645 test_err("got an error when we shouldn't have");
648 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
649 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
652 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
654 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
655 offset
, sectorsize
, em
->start
, em
->len
);
658 if (em
->flags
!= 0) {
659 test_err("unexpected flags set, want 0 have %u", em
->flags
);
662 if (em
->offset
!= 0) {
663 test_err("wrong offset, want 0, have %llu", em
->offset
);
666 offset
= em
->start
+ em
->len
;
669 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
671 test_err("got an error when we shouldn't have");
674 if (extent_map_block_start(em
) != disk_bytenr
) {
675 test_err("block start does not match, want %llu got %llu",
676 disk_bytenr
, extent_map_block_start(em
));
679 if (em
->start
!= offset
|| em
->len
!= 2 * sectorsize
) {
681 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
682 offset
, 2 * sectorsize
, em
->start
, em
->len
);
685 if (em
->flags
!= compressed_only
) {
686 test_err("unexpected flags set, want %u have %u",
687 compressed_only
, em
->flags
);
690 if (em
->start
- em
->offset
!= orig_start
) {
691 test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
692 em
->start
, em
->offset
, orig_start
);
695 if (extent_map_compression(em
) != BTRFS_COMPRESS_ZLIB
) {
696 test_err("unexpected compress type, wanted %d, got %d",
697 BTRFS_COMPRESS_ZLIB
, extent_map_compression(em
));
700 offset
= em
->start
+ em
->len
;
703 /* A hole between regular extents but no hole extent */
704 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
+ 6, sectorsize
);
706 test_err("got an error when we shouldn't have");
709 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
710 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
713 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
715 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
716 offset
, sectorsize
, em
->start
, em
->len
);
719 if (em
->flags
!= 0) {
720 test_err("unexpected flags set, want 0 have %u", em
->flags
);
723 if (em
->offset
!= 0) {
724 test_err("wrong offset, want 0, have %llu", em
->offset
);
727 offset
= em
->start
+ em
->len
;
730 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, SZ_4M
);
732 test_err("got an error when we shouldn't have");
735 if (em
->disk_bytenr
!= EXTENT_MAP_HOLE
) {
736 test_err("expected a hole extent, got %llu", em
->disk_bytenr
);
740 * Currently we just return a length that we requested rather than the
741 * length of the actual hole, if this changes we'll have to change this
744 if (em
->start
!= offset
|| em
->len
!= 3 * sectorsize
) {
746 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
747 offset
, 3 * sectorsize
, em
->start
, em
->len
);
750 if (em
->flags
!= vacancy_only
) {
751 test_err("unexpected flags set, want %u have %u",
752 vacancy_only
, em
->flags
);
755 if (em
->offset
!= 0) {
756 test_err("wrong offset, want 0, have %llu", em
->offset
);
759 offset
= em
->start
+ em
->len
;
762 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, offset
, sectorsize
);
764 test_err("got an error when we shouldn't have");
767 if (em
->disk_bytenr
>= EXTENT_MAP_LAST_BYTE
) {
768 test_err("expected a real extent, got %llu", em
->disk_bytenr
);
771 if (em
->start
!= offset
|| em
->len
!= sectorsize
) {
773 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
774 offset
, sectorsize
, em
->start
, em
->len
);
777 if (em
->flags
!= 0) {
778 test_err("unexpected flags set, want 0 have %u", em
->flags
);
781 if (em
->offset
!= 0) {
782 test_err("wrong orig offset, want 0, have %llu", em
->offset
);
790 btrfs_free_dummy_root(root
);
791 btrfs_free_dummy_fs_info(fs_info
);
795 static int test_hole_first(u32 sectorsize
, u32 nodesize
)
797 struct btrfs_fs_info
*fs_info
= NULL
;
798 struct inode
*inode
= NULL
;
799 struct btrfs_root
*root
= NULL
;
800 struct extent_map
*em
= NULL
;
803 test_msg("running hole first btrfs_get_extent test");
805 inode
= btrfs_new_test_inode();
807 test_std_err(TEST_ALLOC_INODE
);
811 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
813 test_std_err(TEST_ALLOC_FS_INFO
);
817 root
= btrfs_alloc_dummy_root(fs_info
);
819 test_std_err(TEST_ALLOC_ROOT
);
823 root
->node
= alloc_dummy_extent_buffer(fs_info
, nodesize
);
825 test_std_err(TEST_ALLOC_ROOT
);
829 btrfs_set_header_nritems(root
->node
, 0);
830 btrfs_set_header_level(root
->node
, 0);
831 BTRFS_I(inode
)->root
= root
;
835 * Need a blank inode item here just so we don't confuse
838 insert_inode_item_key(root
);
839 insert_extent(root
, sectorsize
, sectorsize
, sectorsize
, 0, sectorsize
,
840 sectorsize
, BTRFS_FILE_EXTENT_REG
, 0, 1);
841 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, 0, 2 * sectorsize
);
843 test_err("got an error when we shouldn't have");
846 if (em
->disk_bytenr
!= EXTENT_MAP_HOLE
) {
847 test_err("expected a hole, got %llu", em
->disk_bytenr
);
850 if (em
->start
!= 0 || em
->len
!= sectorsize
) {
852 "unexpected extent wanted start 0 len %u, got start %llu len %llu",
853 sectorsize
, em
->start
, em
->len
);
856 if (em
->flags
!= vacancy_only
) {
857 test_err("wrong flags, wanted %u, have %u", vacancy_only
,
863 em
= btrfs_get_extent(BTRFS_I(inode
), NULL
, sectorsize
, 2 * sectorsize
);
865 test_err("got an error when we shouldn't have");
868 if (extent_map_block_start(em
) != sectorsize
) {
869 test_err("expected a real extent, got %llu", extent_map_block_start(em
));
872 if (em
->start
!= sectorsize
|| em
->len
!= sectorsize
) {
874 "unexpected extent wanted start %u len %u, got start %llu len %llu",
875 sectorsize
, sectorsize
, em
->start
, em
->len
);
878 if (em
->flags
!= 0) {
879 test_err("unexpected flags set, wanted 0 got %u",
888 btrfs_free_dummy_root(root
);
889 btrfs_free_dummy_fs_info(fs_info
);
893 static int test_extent_accounting(u32 sectorsize
, u32 nodesize
)
895 struct btrfs_fs_info
*fs_info
= NULL
;
896 struct inode
*inode
= NULL
;
897 struct btrfs_root
*root
= NULL
;
900 test_msg("running outstanding_extents tests");
902 inode
= btrfs_new_test_inode();
904 test_std_err(TEST_ALLOC_INODE
);
908 fs_info
= btrfs_alloc_dummy_fs_info(nodesize
, sectorsize
);
910 test_std_err(TEST_ALLOC_FS_INFO
);
914 root
= btrfs_alloc_dummy_root(fs_info
);
916 test_std_err(TEST_ALLOC_ROOT
);
920 BTRFS_I(inode
)->root
= root
;
922 /* [BTRFS_MAX_EXTENT_SIZE] */
923 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), 0,
924 BTRFS_MAX_EXTENT_SIZE
- 1, 0, NULL
);
926 test_err("btrfs_set_extent_delalloc returned %d", ret
);
929 if (BTRFS_I(inode
)->outstanding_extents
!= 1) {
931 test_err("miscount, wanted 1, got %u",
932 BTRFS_I(inode
)->outstanding_extents
);
936 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
937 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), BTRFS_MAX_EXTENT_SIZE
,
938 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
- 1,
941 test_err("btrfs_set_extent_delalloc returned %d", ret
);
944 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
946 test_err("miscount, wanted 2, got %u",
947 BTRFS_I(inode
)->outstanding_extents
);
951 /* [BTRFS_MAX_EXTENT_SIZE/2][sectorsize HOLE][the rest] */
952 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
,
953 BTRFS_MAX_EXTENT_SIZE
>> 1,
954 (BTRFS_MAX_EXTENT_SIZE
>> 1) + sectorsize
- 1,
955 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
956 EXTENT_UPTODATE
, NULL
);
958 test_err("clear_extent_bit returned %d", ret
);
961 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
963 test_err("miscount, wanted 2, got %u",
964 BTRFS_I(inode
)->outstanding_extents
);
968 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
969 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
), BTRFS_MAX_EXTENT_SIZE
>> 1,
970 (BTRFS_MAX_EXTENT_SIZE
>> 1)
974 test_err("btrfs_set_extent_delalloc returned %d", ret
);
977 if (BTRFS_I(inode
)->outstanding_extents
!= 2) {
979 test_err("miscount, wanted 2, got %u",
980 BTRFS_I(inode
)->outstanding_extents
);
985 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize HOLE][BTRFS_MAX_EXTENT_SIZE+sectorsize]
987 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
988 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
,
989 (BTRFS_MAX_EXTENT_SIZE
<< 1) + 3 * sectorsize
- 1,
992 test_err("btrfs_set_extent_delalloc returned %d", ret
);
995 if (BTRFS_I(inode
)->outstanding_extents
!= 4) {
997 test_err("miscount, wanted 4, got %u",
998 BTRFS_I(inode
)->outstanding_extents
);
1003 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize]
1005 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
1006 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1007 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1, 0, NULL
);
1009 test_err("btrfs_set_extent_delalloc returned %d", ret
);
1012 if (BTRFS_I(inode
)->outstanding_extents
!= 3) {
1014 test_err("miscount, wanted 3, got %u",
1015 BTRFS_I(inode
)->outstanding_extents
);
1019 /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */
1020 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
,
1021 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1022 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1,
1023 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1024 EXTENT_UPTODATE
, NULL
);
1026 test_err("clear_extent_bit returned %d", ret
);
1029 if (BTRFS_I(inode
)->outstanding_extents
!= 4) {
1031 test_err("miscount, wanted 4, got %u",
1032 BTRFS_I(inode
)->outstanding_extents
);
1037 * Refill the hole again just for good measure, because I thought it
1038 * might fail and I'd rather satisfy my paranoia at this point.
1040 ret
= btrfs_set_extent_delalloc(BTRFS_I(inode
),
1041 BTRFS_MAX_EXTENT_SIZE
+ sectorsize
,
1042 BTRFS_MAX_EXTENT_SIZE
+ 2 * sectorsize
- 1, 0, NULL
);
1044 test_err("btrfs_set_extent_delalloc returned %d", ret
);
1047 if (BTRFS_I(inode
)->outstanding_extents
!= 3) {
1049 test_err("miscount, wanted 3, got %u",
1050 BTRFS_I(inode
)->outstanding_extents
);
1055 ret
= clear_extent_bit(&BTRFS_I(inode
)->io_tree
, 0, (u64
)-1,
1056 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1057 EXTENT_UPTODATE
, NULL
);
1059 test_err("clear_extent_bit returned %d", ret
);
1062 if (BTRFS_I(inode
)->outstanding_extents
) {
1064 test_err("miscount, wanted 0, got %u",
1065 BTRFS_I(inode
)->outstanding_extents
);
1071 clear_extent_bit(&BTRFS_I(inode
)->io_tree
, 0, (u64
)-1,
1072 EXTENT_DELALLOC
| EXTENT_DELALLOC_NEW
|
1073 EXTENT_UPTODATE
, NULL
);
1075 btrfs_free_dummy_root(root
);
1076 btrfs_free_dummy_fs_info(fs_info
);
1080 int btrfs_test_inodes(u32 sectorsize
, u32 nodesize
)
1084 test_msg("running inode tests");
1086 compressed_only
|= EXTENT_FLAG_COMPRESS_ZLIB
;
1087 prealloc_only
|= EXTENT_FLAG_PREALLOC
;
1089 ret
= test_btrfs_get_extent(sectorsize
, nodesize
);
1092 ret
= test_hole_first(sectorsize
, nodesize
);
1095 return test_extent_accounting(sectorsize
, nodesize
);