btrfs: Introduce fs_info to extent_io_tree
[linux-block.git] / fs / btrfs / tests / extent-io-tests.c
CommitLineData
c1d7c514 1// SPDX-License-Identifier: GPL-2.0
294e30fe
JB
2/*
3 * Copyright (C) 2013 Fusion IO. All rights reserved.
294e30fe
JB
4 */
5
6#include <linux/pagemap.h>
7#include <linux/sched.h>
0f331229 8#include <linux/slab.h>
ee22184b 9#include <linux/sizes.h>
294e30fe 10#include "btrfs-tests.h"
ed9e4afd 11#include "../ctree.h"
294e30fe
JB
12#include "../extent_io.h"
13
14#define PROCESS_UNLOCK (1 << 0)
15#define PROCESS_RELEASE (1 << 1)
16#define PROCESS_TEST_LOCKED (1 << 2)
17
18static noinline int process_page_range(struct inode *inode, u64 start, u64 end,
19 unsigned long flags)
20{
21 int ret;
22 struct page *pages[16];
09cbfeaf
KS
23 unsigned long index = start >> PAGE_SHIFT;
24 unsigned long end_index = end >> PAGE_SHIFT;
294e30fe
JB
25 unsigned long nr_pages = end_index - index + 1;
26 int i;
27 int count = 0;
28 int loops = 0;
29
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]))
37 count++;
38 if (flags & PROCESS_UNLOCK && PageLocked(pages[i]))
39 unlock_page(pages[i]);
09cbfeaf 40 put_page(pages[i]);
294e30fe 41 if (flags & PROCESS_RELEASE)
09cbfeaf 42 put_page(pages[i]);
294e30fe
JB
43 }
44 nr_pages -= ret;
45 index += ret;
46 cond_resched();
47 loops++;
48 if (loops > 100000) {
3c7251f2
DS
49 printk(KERN_ERR
50 "stuck in a loop, start %llu, end %llu, nr_pages %lu, ret %d\n",
51 start, end, nr_pages, ret);
294e30fe
JB
52 break;
53 }
54 }
55 return count;
56}
57
b9ef22de 58static int test_find_delalloc(u32 sectorsize)
294e30fe
JB
59{
60 struct inode *inode;
61 struct extent_io_tree tmp;
62 struct page *page;
63 struct page *locked_page = NULL;
64 unsigned long index = 0;
d9cb2459
QW
65 /* In this test we need at least 2 file extents at its maximum size */
66 u64 max_bytes = BTRFS_MAX_EXTENT_SIZE;
67 u64 total_dirty = 2 * max_bytes;
294e30fe 68 u64 start, end, test_start;
3522e903 69 bool found;
294e30fe
JB
70 int ret = -EINVAL;
71
315b76b4 72 test_msg("running find delalloc tests");
0f331229 73
294e30fe
JB
74 inode = btrfs_new_test_inode();
75 if (!inode) {
3c7251f2 76 test_err("failed to allocate test inode");
294e30fe
JB
77 return -ENOMEM;
78 }
79
c258d6e3 80 extent_io_tree_init(NULL, &tmp, NULL);
294e30fe
JB
81
82 /*
83 * First go through and create and mark all of our pages dirty, we pin
84 * everything to make sure our pages don't get evicted and screw up our
85 * test.
86 */
09cbfeaf 87 for (index = 0; index < (total_dirty >> PAGE_SHIFT); index++) {
8cce83ba 88 page = find_or_create_page(inode->i_mapping, index, GFP_KERNEL);
294e30fe 89 if (!page) {
3c7251f2 90 test_err("failed to allocate test page");
294e30fe
JB
91 ret = -ENOMEM;
92 goto out;
93 }
94 SetPageDirty(page);
95 if (index) {
96 unlock_page(page);
97 } else {
09cbfeaf 98 get_page(page);
294e30fe
JB
99 locked_page = page;
100 }
101 }
102
103 /* Test this scenario
104 * |--- delalloc ---|
105 * |--- search ---|
106 */
e3b8a485 107 set_extent_delalloc(&tmp, 0, sectorsize - 1, 0, NULL);
294e30fe
JB
108 start = 0;
109 end = 0;
ce9f967f 110 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
917aacec 111 &end);
294e30fe 112 if (!found) {
3c7251f2 113 test_err("should have found at least one delalloc");
294e30fe
JB
114 goto out_bits;
115 }
b9ef22de 116 if (start != 0 || end != (sectorsize - 1)) {
3c7251f2 117 test_err("expected start 0 end %u, got start %llu end %llu",
b9ef22de 118 sectorsize - 1, start, end);
294e30fe
JB
119 goto out_bits;
120 }
121 unlock_extent(&tmp, start, end);
122 unlock_page(locked_page);
09cbfeaf 123 put_page(locked_page);
294e30fe
JB
124
125 /*
126 * Test this scenario
127 *
128 * |--- delalloc ---|
129 * |--- search ---|
130 */
ee22184b 131 test_start = SZ_64M;
294e30fe 132 locked_page = find_lock_page(inode->i_mapping,
09cbfeaf 133 test_start >> PAGE_SHIFT);
294e30fe 134 if (!locked_page) {
3c7251f2 135 test_err("couldn't find the locked page");
294e30fe
JB
136 goto out_bits;
137 }
e3b8a485 138 set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, 0, NULL);
294e30fe
JB
139 start = test_start;
140 end = 0;
ce9f967f 141 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
917aacec 142 &end);
294e30fe 143 if (!found) {
3c7251f2 144 test_err("couldn't find delalloc in our range");
294e30fe
JB
145 goto out_bits;
146 }
147 if (start != test_start || end != max_bytes - 1) {
3c7251f2
DS
148 test_err("expected start %llu end %llu, got start %llu, end %llu",
149 test_start, max_bytes - 1, start, end);
294e30fe
JB
150 goto out_bits;
151 }
152 if (process_page_range(inode, start, end,
153 PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
3c7251f2 154 test_err("there were unlocked pages in the range");
294e30fe
JB
155 goto out_bits;
156 }
157 unlock_extent(&tmp, start, end);
158 /* locked_page was unlocked above */
09cbfeaf 159 put_page(locked_page);
294e30fe
JB
160
161 /*
162 * Test this scenario
163 * |--- delalloc ---|
164 * |--- search ---|
165 */
b9ef22de 166 test_start = max_bytes + sectorsize;
294e30fe 167 locked_page = find_lock_page(inode->i_mapping, test_start >>
09cbfeaf 168 PAGE_SHIFT);
294e30fe 169 if (!locked_page) {
3c7251f2 170 test_err("couldn't find the locked page");
294e30fe
JB
171 goto out_bits;
172 }
173 start = test_start;
174 end = 0;
ce9f967f 175 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
917aacec 176 &end);
294e30fe 177 if (found) {
3c7251f2 178 test_err("found range when we shouldn't have");
294e30fe
JB
179 goto out_bits;
180 }
181 if (end != (u64)-1) {
3c7251f2 182 test_err("did not return the proper end offset");
294e30fe
JB
183 goto out_bits;
184 }
185
186 /*
187 * Test this scenario
188 * [------- delalloc -------|
189 * [max_bytes]|-- search--|
190 *
191 * We are re-using our test_start from above since it works out well.
192 */
e3b8a485 193 set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, 0, NULL);
294e30fe
JB
194 start = test_start;
195 end = 0;
ce9f967f 196 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
917aacec 197 &end);
294e30fe 198 if (!found) {
3c7251f2 199 test_err("didn't find our range");
294e30fe
JB
200 goto out_bits;
201 }
202 if (start != test_start || end != total_dirty - 1) {
3c7251f2 203 test_err("expected start %llu end %llu, got start %llu end %llu",
294e30fe
JB
204 test_start, total_dirty - 1, start, end);
205 goto out_bits;
206 }
207 if (process_page_range(inode, start, end,
208 PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
3c7251f2 209 test_err("pages in range were not all locked");
294e30fe
JB
210 goto out_bits;
211 }
212 unlock_extent(&tmp, start, end);
213
214 /*
215 * Now to test where we run into a page that is no longer dirty in the
216 * range we want to find.
217 */
ee22184b 218 page = find_get_page(inode->i_mapping,
09cbfeaf 219 (max_bytes + SZ_1M) >> PAGE_SHIFT);
294e30fe 220 if (!page) {
3c7251f2 221 test_err("couldn't find our page");
294e30fe
JB
222 goto out_bits;
223 }
224 ClearPageDirty(page);
09cbfeaf 225 put_page(page);
294e30fe
JB
226
227 /* We unlocked it in the previous test */
228 lock_page(locked_page);
229 start = test_start;
230 end = 0;
231 /*
232 * Currently if we fail to find dirty pages in the delalloc range we
ea1754a0 233 * will adjust max_bytes down to PAGE_SIZE and then re-search. If
294e30fe
JB
234 * this changes at any point in the future we will need to fix this
235 * tests expected behavior.
236 */
ce9f967f 237 found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
917aacec 238 &end);
294e30fe 239 if (!found) {
3c7251f2 240 test_err("didn't find our range");
294e30fe
JB
241 goto out_bits;
242 }
09cbfeaf 243 if (start != test_start && end != test_start + PAGE_SIZE - 1) {
3c7251f2
DS
244 test_err("expected start %llu end %llu, got start %llu end %llu",
245 test_start, test_start + PAGE_SIZE - 1, start, end);
294e30fe
JB
246 goto out_bits;
247 }
248 if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED |
249 PROCESS_UNLOCK)) {
3c7251f2 250 test_err("pages in range were not all locked");
294e30fe
JB
251 goto out_bits;
252 }
253 ret = 0;
254out_bits:
91166212 255 clear_extent_bits(&tmp, 0, total_dirty - 1, (unsigned)-1);
294e30fe
JB
256out:
257 if (locked_page)
09cbfeaf 258 put_page(locked_page);
294e30fe
JB
259 process_page_range(inode, 0, total_dirty - 1,
260 PROCESS_UNLOCK | PROCESS_RELEASE);
261 iput(inode);
262 return ret;
263}
264
9426ce75
OS
265static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb,
266 unsigned long len)
34b3e6c9 267{
9426ce75
OS
268 unsigned long i;
269
270 for (i = 0; i < len * BITS_PER_BYTE; i++) {
271 int bit, bit1;
272
273 bit = !!test_bit(i, bitmap);
274 bit1 = !!extent_buffer_test_bit(eb, 0, i);
275 if (bit1 != bit) {
3c7251f2 276 test_err("bits do not match");
9426ce75
OS
277 return -EINVAL;
278 }
279
280 bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
281 i % BITS_PER_BYTE);
282 if (bit1 != bit) {
3c7251f2 283 test_err("offset bits do not match");
9426ce75
OS
284 return -EINVAL;
285 }
286 }
287 return 0;
34b3e6c9
FX
288}
289
0f331229
OS
290static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
291 unsigned long len)
292{
9426ce75
OS
293 unsigned long i, j;
294 u32 x;
295 int ret;
0f331229
OS
296
297 memset(bitmap, 0, len);
b159fa28 298 memzero_extent_buffer(eb, 0, len);
0f331229 299 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) {
3c7251f2 300 test_err("bitmap was not zeroed");
0f331229
OS
301 return -EINVAL;
302 }
303
304 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
305 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
9426ce75
OS
306 ret = check_eb_bitmap(bitmap, eb, len);
307 if (ret) {
3c7251f2 308 test_err("setting all bits failed");
9426ce75 309 return ret;
0f331229
OS
310 }
311
312 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
313 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
9426ce75
OS
314 ret = check_eb_bitmap(bitmap, eb, len);
315 if (ret) {
3c7251f2 316 test_err("clearing all bits failed");
9426ce75 317 return ret;
0f331229
OS
318 }
319
ed9e4afd
FX
320 /* Straddling pages test */
321 if (len > PAGE_SIZE) {
322 bitmap_set(bitmap,
323 (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE,
324 sizeof(long) * BITS_PER_BYTE);
325 extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0,
326 sizeof(long) * BITS_PER_BYTE);
9426ce75
OS
327 ret = check_eb_bitmap(bitmap, eb, len);
328 if (ret) {
3c7251f2 329 test_err("setting straddling pages failed");
9426ce75 330 return ret;
ed9e4afd 331 }
0f331229 332
ed9e4afd
FX
333 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
334 bitmap_clear(bitmap,
335 (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE,
336 sizeof(long) * BITS_PER_BYTE);
337 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
338 extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0,
339 sizeof(long) * BITS_PER_BYTE);
9426ce75
OS
340 ret = check_eb_bitmap(bitmap, eb, len);
341 if (ret) {
3c7251f2 342 test_err("clearing straddling pages failed");
9426ce75 343 return ret;
ed9e4afd 344 }
0f331229
OS
345 }
346
347 /*
348 * Generate a wonky pseudo-random bit pattern for the sake of not using
349 * something repetitive that could miss some hypothetical off-by-n bug.
350 */
351 x = 0;
9426ce75
OS
352 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
353 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
354 for (i = 0; i < len * BITS_PER_BYTE / 32; i++) {
355 x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffU;
356 for (j = 0; j < 32; j++) {
357 if (x & (1U << j)) {
358 bitmap_set(bitmap, i * 32 + j, 1);
359 extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
360 }
0f331229 361 }
9426ce75 362 }
0f331229 363
9426ce75
OS
364 ret = check_eb_bitmap(bitmap, eb, len);
365 if (ret) {
3c7251f2 366 test_err("random bit pattern failed");
9426ce75 367 return ret;
0f331229
OS
368 }
369
370 return 0;
371}
372
b9ef22de 373static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
0f331229 374{
da17066c 375 struct btrfs_fs_info *fs_info;
b9ef22de 376 unsigned long len;
0f331229
OS
377 unsigned long *bitmap;
378 struct extent_buffer *eb;
379 int ret;
380
315b76b4 381 test_msg("running extent buffer bitmap tests");
ed9e4afd
FX
382
383 /*
384 * In ppc64, sectorsize can be 64K, thus 4 * 64K will be larger than
385 * BTRFS_MAX_METADATA_BLOCKSIZE.
386 */
387 len = (sectorsize < BTRFS_MAX_METADATA_BLOCKSIZE)
388 ? sectorsize * 4 : sectorsize;
0f331229 389
da17066c
JM
390 fs_info = btrfs_alloc_dummy_fs_info(len, len);
391
8cce83ba 392 bitmap = kmalloc(len, GFP_KERNEL);
0f331229 393 if (!bitmap) {
3c7251f2 394 test_err("couldn't allocate test bitmap");
0f331229
OS
395 return -ENOMEM;
396 }
397
da17066c 398 eb = __alloc_dummy_extent_buffer(fs_info, 0, len);
0f331229 399 if (!eb) {
3c7251f2 400 test_err("couldn't allocate test extent buffer");
0f331229
OS
401 kfree(bitmap);
402 return -ENOMEM;
403 }
404
405 ret = __test_eb_bitmaps(bitmap, eb, len);
406 if (ret)
407 goto out;
408
409 /* Do it over again with an extent buffer which isn't page-aligned. */
410 free_extent_buffer(eb);
b9ef22de 411 eb = __alloc_dummy_extent_buffer(NULL, nodesize / 2, len);
0f331229 412 if (!eb) {
3c7251f2 413 test_err("couldn't allocate test extent buffer");
0f331229
OS
414 kfree(bitmap);
415 return -ENOMEM;
416 }
417
418 ret = __test_eb_bitmaps(bitmap, eb, len);
419out:
420 free_extent_buffer(eb);
421 kfree(bitmap);
422 return ret;
423}
424
b9ef22de 425int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
294e30fe 426{
0f331229
OS
427 int ret;
428
315b76b4 429 test_msg("running extent I/O tests");
0f331229 430
b9ef22de 431 ret = test_find_delalloc(sectorsize);
0f331229
OS
432 if (ret)
433 goto out;
434
b9ef22de 435 ret = test_eb_bitmaps(sectorsize, nodesize);
0f331229 436out:
315b76b4 437 test_msg("extent I/O tests finished");
0f331229 438 return ret;
294e30fe 439}