1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2013 Fusion IO. All rights reserved.
6 #include <linux/pagemap.h>
7 #include <linux/sched.h>
8 #include <linux/slab.h>
9 #include <linux/sizes.h>
10 #include "btrfs-tests.h"
12 #include "../extent_io.h"
14 #define PROCESS_UNLOCK (1 << 0)
15 #define PROCESS_RELEASE (1 << 1)
16 #define PROCESS_TEST_LOCKED (1 << 2)
18 static noinline
int process_page_range(struct inode
*inode
, u64 start
, u64 end
,
22 struct page
*pages
[16];
23 unsigned long index
= start
>> PAGE_SHIFT
;
24 unsigned long end_index
= end
>> PAGE_SHIFT
;
25 unsigned long nr_pages
= end_index
- index
+ 1;
30 while (nr_pages
> 0) {
31 ret
= find_get_pages_contig(inode
->i_mapping
, index
,
32 min_t(unsigned long, nr_pages
,
33 ARRAY_SIZE(pages
)), pages
);
34 for (i
= 0; i
< ret
; i
++) {
35 if (flags
& PROCESS_TEST_LOCKED
&&
36 !PageLocked(pages
[i
]))
38 if (flags
& PROCESS_UNLOCK
&& PageLocked(pages
[i
]))
39 unlock_page(pages
[i
]);
41 if (flags
& PROCESS_RELEASE
)
50 "stuck in a loop, start %llu, end %llu, nr_pages %lu, ret %d\n",
51 start
, end
, nr_pages
, ret
);
58 static int test_find_delalloc(u32 sectorsize
)
61 struct extent_io_tree tmp
;
63 struct page
*locked_page
= NULL
;
64 unsigned long index
= 0;
65 u64 total_dirty
= SZ_256M
;
66 u64 max_bytes
= SZ_128M
;
67 u64 start
, end
, test_start
;
71 test_msg("running find delalloc tests");
73 inode
= btrfs_new_test_inode();
75 test_err("failed to allocate test inode");
79 extent_io_tree_init(&tmp
, inode
);
82 * First go through and create and mark all of our pages dirty, we pin
83 * everything to make sure our pages don't get evicted and screw up our
86 for (index
= 0; index
< (total_dirty
>> PAGE_SHIFT
); index
++) {
87 page
= find_or_create_page(inode
->i_mapping
, index
, GFP_KERNEL
);
89 test_err("failed to allocate test page");
102 /* Test this scenario
106 set_extent_delalloc(&tmp
, 0, sectorsize
- 1, 0, NULL
);
109 found
= btrfs_find_lock_delalloc_range(inode
, &tmp
, locked_page
, &start
,
112 test_err("should have found at least one delalloc");
115 if (start
!= 0 || end
!= (sectorsize
- 1)) {
116 test_err("expected start 0 end %u, got start %llu end %llu",
117 sectorsize
- 1, start
, end
);
120 unlock_extent(&tmp
, start
, end
);
121 unlock_page(locked_page
);
122 put_page(locked_page
);
131 locked_page
= find_lock_page(inode
->i_mapping
,
132 test_start
>> PAGE_SHIFT
);
134 test_err("couldn't find the locked page");
137 set_extent_delalloc(&tmp
, sectorsize
, max_bytes
- 1, 0, NULL
);
140 found
= btrfs_find_lock_delalloc_range(inode
, &tmp
, locked_page
, &start
,
143 test_err("couldn't find delalloc in our range");
146 if (start
!= test_start
|| end
!= max_bytes
- 1) {
147 test_err("expected start %llu end %llu, got start %llu, end %llu",
148 test_start
, max_bytes
- 1, start
, end
);
151 if (process_page_range(inode
, start
, end
,
152 PROCESS_TEST_LOCKED
| PROCESS_UNLOCK
)) {
153 test_err("there were unlocked pages in the range");
156 unlock_extent(&tmp
, start
, end
);
157 /* locked_page was unlocked above */
158 put_page(locked_page
);
165 test_start
= max_bytes
+ sectorsize
;
166 locked_page
= find_lock_page(inode
->i_mapping
, test_start
>>
169 test_err("couldn't find the locked page");
174 found
= btrfs_find_lock_delalloc_range(inode
, &tmp
, locked_page
, &start
,
177 test_err("found range when we shouldn't have");
180 if (end
!= (u64
)-1) {
181 test_err("did not return the proper end offset");
187 * [------- delalloc -------|
188 * [max_bytes]|-- search--|
190 * We are re-using our test_start from above since it works out well.
192 set_extent_delalloc(&tmp
, max_bytes
, total_dirty
- 1, 0, NULL
);
195 found
= btrfs_find_lock_delalloc_range(inode
, &tmp
, locked_page
, &start
,
198 test_err("didn't find our range");
201 if (start
!= test_start
|| end
!= total_dirty
- 1) {
202 test_err("expected start %llu end %llu, got start %llu end %llu",
203 test_start
, total_dirty
- 1, start
, end
);
206 if (process_page_range(inode
, start
, end
,
207 PROCESS_TEST_LOCKED
| PROCESS_UNLOCK
)) {
208 test_err("pages in range were not all locked");
211 unlock_extent(&tmp
, start
, end
);
214 * Now to test where we run into a page that is no longer dirty in the
215 * range we want to find.
217 page
= find_get_page(inode
->i_mapping
,
218 (max_bytes
+ SZ_1M
) >> PAGE_SHIFT
);
220 test_err("couldn't find our page");
223 ClearPageDirty(page
);
226 /* We unlocked it in the previous test */
227 lock_page(locked_page
);
231 * Currently if we fail to find dirty pages in the delalloc range we
232 * will adjust max_bytes down to PAGE_SIZE and then re-search. If
233 * this changes at any point in the future we will need to fix this
234 * tests expected behavior.
236 found
= btrfs_find_lock_delalloc_range(inode
, &tmp
, locked_page
, &start
,
239 test_err("didn't find our range");
242 if (start
!= test_start
&& end
!= test_start
+ PAGE_SIZE
- 1) {
243 test_err("expected start %llu end %llu, got start %llu end %llu",
244 test_start
, test_start
+ PAGE_SIZE
- 1, start
, end
);
247 if (process_page_range(inode
, start
, end
, PROCESS_TEST_LOCKED
|
249 test_err("pages in range were not all locked");
254 clear_extent_bits(&tmp
, 0, total_dirty
- 1, (unsigned)-1);
257 put_page(locked_page
);
258 process_page_range(inode
, 0, total_dirty
- 1,
259 PROCESS_UNLOCK
| PROCESS_RELEASE
);
264 static int check_eb_bitmap(unsigned long *bitmap
, struct extent_buffer
*eb
,
269 for (i
= 0; i
< len
* BITS_PER_BYTE
; i
++) {
272 bit
= !!test_bit(i
, bitmap
);
273 bit1
= !!extent_buffer_test_bit(eb
, 0, i
);
275 test_err("bits do not match");
279 bit1
= !!extent_buffer_test_bit(eb
, i
/ BITS_PER_BYTE
,
282 test_err("offset bits do not match");
289 static int __test_eb_bitmaps(unsigned long *bitmap
, struct extent_buffer
*eb
,
296 memset(bitmap
, 0, len
);
297 memzero_extent_buffer(eb
, 0, len
);
298 if (memcmp_extent_buffer(eb
, bitmap
, 0, len
) != 0) {
299 test_err("bitmap was not zeroed");
303 bitmap_set(bitmap
, 0, len
* BITS_PER_BYTE
);
304 extent_buffer_bitmap_set(eb
, 0, 0, len
* BITS_PER_BYTE
);
305 ret
= check_eb_bitmap(bitmap
, eb
, len
);
307 test_err("setting all bits failed");
311 bitmap_clear(bitmap
, 0, len
* BITS_PER_BYTE
);
312 extent_buffer_bitmap_clear(eb
, 0, 0, len
* BITS_PER_BYTE
);
313 ret
= check_eb_bitmap(bitmap
, eb
, len
);
315 test_err("clearing all bits failed");
319 /* Straddling pages test */
320 if (len
> PAGE_SIZE
) {
322 (PAGE_SIZE
- sizeof(long) / 2) * BITS_PER_BYTE
,
323 sizeof(long) * BITS_PER_BYTE
);
324 extent_buffer_bitmap_set(eb
, PAGE_SIZE
- sizeof(long) / 2, 0,
325 sizeof(long) * BITS_PER_BYTE
);
326 ret
= check_eb_bitmap(bitmap
, eb
, len
);
328 test_err("setting straddling pages failed");
332 bitmap_set(bitmap
, 0, len
* BITS_PER_BYTE
);
334 (PAGE_SIZE
- sizeof(long) / 2) * BITS_PER_BYTE
,
335 sizeof(long) * BITS_PER_BYTE
);
336 extent_buffer_bitmap_set(eb
, 0, 0, len
* BITS_PER_BYTE
);
337 extent_buffer_bitmap_clear(eb
, PAGE_SIZE
- sizeof(long) / 2, 0,
338 sizeof(long) * BITS_PER_BYTE
);
339 ret
= check_eb_bitmap(bitmap
, eb
, len
);
341 test_err("clearing straddling pages failed");
347 * Generate a wonky pseudo-random bit pattern for the sake of not using
348 * something repetitive that could miss some hypothetical off-by-n bug.
351 bitmap_clear(bitmap
, 0, len
* BITS_PER_BYTE
);
352 extent_buffer_bitmap_clear(eb
, 0, 0, len
* BITS_PER_BYTE
);
353 for (i
= 0; i
< len
* BITS_PER_BYTE
/ 32; i
++) {
354 x
= (0x19660dULL
* (u64
)x
+ 0x3c6ef35fULL
) & 0xffffffffU
;
355 for (j
= 0; j
< 32; j
++) {
357 bitmap_set(bitmap
, i
* 32 + j
, 1);
358 extent_buffer_bitmap_set(eb
, 0, i
* 32 + j
, 1);
363 ret
= check_eb_bitmap(bitmap
, eb
, len
);
365 test_err("random bit pattern failed");
372 static int test_eb_bitmaps(u32 sectorsize
, u32 nodesize
)
374 struct btrfs_fs_info
*fs_info
;
376 unsigned long *bitmap
;
377 struct extent_buffer
*eb
;
380 test_msg("running extent buffer bitmap tests");
383 * In ppc64, sectorsize can be 64K, thus 4 * 64K will be larger than
384 * BTRFS_MAX_METADATA_BLOCKSIZE.
386 len
= (sectorsize
< BTRFS_MAX_METADATA_BLOCKSIZE
)
387 ? sectorsize
* 4 : sectorsize
;
389 fs_info
= btrfs_alloc_dummy_fs_info(len
, len
);
391 bitmap
= kmalloc(len
, GFP_KERNEL
);
393 test_err("couldn't allocate test bitmap");
397 eb
= __alloc_dummy_extent_buffer(fs_info
, 0, len
);
399 test_err("couldn't allocate test extent buffer");
404 ret
= __test_eb_bitmaps(bitmap
, eb
, len
);
408 /* Do it over again with an extent buffer which isn't page-aligned. */
409 free_extent_buffer(eb
);
410 eb
= __alloc_dummy_extent_buffer(NULL
, nodesize
/ 2, len
);
412 test_err("couldn't allocate test extent buffer");
417 ret
= __test_eb_bitmaps(bitmap
, eb
, len
);
419 free_extent_buffer(eb
);
424 int btrfs_test_extent_io(u32 sectorsize
, u32 nodesize
)
428 test_msg("running extent I/O tests");
430 ret
= test_find_delalloc(sectorsize
);
434 ret
= test_eb_bitmaps(sectorsize
, nodesize
);
436 test_msg("extent I/O tests finished");