Merge tag 'stackleak-v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / fs / btrfs / tests / extent-io-tests.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2013 Fusion IO.  All rights reserved.
4  */
5
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"
11 #include "../ctree.h"
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
18 static 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];
23         unsigned long index = start >> PAGE_SHIFT;
24         unsigned long end_index = end >> PAGE_SHIFT;
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]);
40                         put_page(pages[i]);
41                         if (flags & PROCESS_RELEASE)
42                                 put_page(pages[i]);
43                 }
44                 nr_pages -= ret;
45                 index += ret;
46                 cond_resched();
47                 loops++;
48                 if (loops > 100000) {
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);
52                         break;
53                 }
54         }
55         return count;
56 }
57
58 static int test_find_delalloc(u32 sectorsize)
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;
65         u64 total_dirty = SZ_256M;
66         u64 max_bytes = SZ_128M;
67         u64 start, end, test_start;
68         u64 found;
69         int ret = -EINVAL;
70
71         test_msg("running find delalloc tests");
72
73         inode = btrfs_new_test_inode();
74         if (!inode) {
75                 test_err("failed to allocate test inode");
76                 return -ENOMEM;
77         }
78
79         extent_io_tree_init(&tmp, inode);
80
81         /*
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
84          * test.
85          */
86         for (index = 0; index < (total_dirty >> PAGE_SHIFT); index++) {
87                 page = find_or_create_page(inode->i_mapping, index, GFP_KERNEL);
88                 if (!page) {
89                         test_err("failed to allocate test page");
90                         ret = -ENOMEM;
91                         goto out;
92                 }
93                 SetPageDirty(page);
94                 if (index) {
95                         unlock_page(page);
96                 } else {
97                         get_page(page);
98                         locked_page = page;
99                 }
100         }
101
102         /* Test this scenario
103          * |--- delalloc ---|
104          * |---  search  ---|
105          */
106         set_extent_delalloc(&tmp, 0, sectorsize - 1, 0, NULL);
107         start = 0;
108         end = 0;
109         found = btrfs_find_lock_delalloc_range(inode, &tmp, locked_page, &start,
110                                          &end, max_bytes);
111         if (!found) {
112                 test_err("should have found at least one delalloc");
113                 goto out_bits;
114         }
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);
118                 goto out_bits;
119         }
120         unlock_extent(&tmp, start, end);
121         unlock_page(locked_page);
122         put_page(locked_page);
123
124         /*
125          * Test this scenario
126          *
127          * |--- delalloc ---|
128          *           |--- search ---|
129          */
130         test_start = SZ_64M;
131         locked_page = find_lock_page(inode->i_mapping,
132                                      test_start >> PAGE_SHIFT);
133         if (!locked_page) {
134                 test_err("couldn't find the locked page");
135                 goto out_bits;
136         }
137         set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, 0, NULL);
138         start = test_start;
139         end = 0;
140         found = btrfs_find_lock_delalloc_range(inode, &tmp, locked_page, &start,
141                                          &end, max_bytes);
142         if (!found) {
143                 test_err("couldn't find delalloc in our range");
144                 goto out_bits;
145         }
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);
149                 goto out_bits;
150         }
151         if (process_page_range(inode, start, end,
152                                PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
153                 test_err("there were unlocked pages in the range");
154                 goto out_bits;
155         }
156         unlock_extent(&tmp, start, end);
157         /* locked_page was unlocked above */
158         put_page(locked_page);
159
160         /*
161          * Test this scenario
162          * |--- delalloc ---|
163          *                    |--- search ---|
164          */
165         test_start = max_bytes + sectorsize;
166         locked_page = find_lock_page(inode->i_mapping, test_start >>
167                                      PAGE_SHIFT);
168         if (!locked_page) {
169                 test_err("couldn't find the locked page");
170                 goto out_bits;
171         }
172         start = test_start;
173         end = 0;
174         found = btrfs_find_lock_delalloc_range(inode, &tmp, locked_page, &start,
175                                          &end, max_bytes);
176         if (found) {
177                 test_err("found range when we shouldn't have");
178                 goto out_bits;
179         }
180         if (end != (u64)-1) {
181                 test_err("did not return the proper end offset");
182                 goto out_bits;
183         }
184
185         /*
186          * Test this scenario
187          * [------- delalloc -------|
188          * [max_bytes]|-- search--|
189          *
190          * We are re-using our test_start from above since it works out well.
191          */
192         set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, 0, NULL);
193         start = test_start;
194         end = 0;
195         found = btrfs_find_lock_delalloc_range(inode, &tmp, locked_page, &start,
196                                          &end, max_bytes);
197         if (!found) {
198                 test_err("didn't find our range");
199                 goto out_bits;
200         }
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);
204                 goto out_bits;
205         }
206         if (process_page_range(inode, start, end,
207                                PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
208                 test_err("pages in range were not all locked");
209                 goto out_bits;
210         }
211         unlock_extent(&tmp, start, end);
212
213         /*
214          * Now to test where we run into a page that is no longer dirty in the
215          * range we want to find.
216          */
217         page = find_get_page(inode->i_mapping,
218                              (max_bytes + SZ_1M) >> PAGE_SHIFT);
219         if (!page) {
220                 test_err("couldn't find our page");
221                 goto out_bits;
222         }
223         ClearPageDirty(page);
224         put_page(page);
225
226         /* We unlocked it in the previous test */
227         lock_page(locked_page);
228         start = test_start;
229         end = 0;
230         /*
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.
235          */
236         found = btrfs_find_lock_delalloc_range(inode, &tmp, locked_page, &start,
237                                          &end, max_bytes);
238         if (!found) {
239                 test_err("didn't find our range");
240                 goto out_bits;
241         }
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);
245                 goto out_bits;
246         }
247         if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED |
248                                PROCESS_UNLOCK)) {
249                 test_err("pages in range were not all locked");
250                 goto out_bits;
251         }
252         ret = 0;
253 out_bits:
254         clear_extent_bits(&tmp, 0, total_dirty - 1, (unsigned)-1);
255 out:
256         if (locked_page)
257                 put_page(locked_page);
258         process_page_range(inode, 0, total_dirty - 1,
259                            PROCESS_UNLOCK | PROCESS_RELEASE);
260         iput(inode);
261         return ret;
262 }
263
264 static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb,
265                            unsigned long len)
266 {
267         unsigned long i;
268
269         for (i = 0; i < len * BITS_PER_BYTE; i++) {
270                 int bit, bit1;
271
272                 bit = !!test_bit(i, bitmap);
273                 bit1 = !!extent_buffer_test_bit(eb, 0, i);
274                 if (bit1 != bit) {
275                         test_err("bits do not match");
276                         return -EINVAL;
277                 }
278
279                 bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
280                                                 i % BITS_PER_BYTE);
281                 if (bit1 != bit) {
282                         test_err("offset bits do not match");
283                         return -EINVAL;
284                 }
285         }
286         return 0;
287 }
288
289 static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
290                              unsigned long len)
291 {
292         unsigned long i, j;
293         u32 x;
294         int ret;
295
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");
300                 return -EINVAL;
301         }
302
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);
306         if (ret) {
307                 test_err("setting all bits failed");
308                 return ret;
309         }
310
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);
314         if (ret) {
315                 test_err("clearing all bits failed");
316                 return ret;
317         }
318
319         /* Straddling pages test */
320         if (len > PAGE_SIZE) {
321                 bitmap_set(bitmap,
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);
327                 if (ret) {
328                         test_err("setting straddling pages failed");
329                         return ret;
330                 }
331
332                 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
333                 bitmap_clear(bitmap,
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);
340                 if (ret) {
341                         test_err("clearing straddling pages failed");
342                         return ret;
343                 }
344         }
345
346         /*
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.
349          */
350         x = 0;
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++) {
356                         if (x & (1U << j)) {
357                                 bitmap_set(bitmap, i * 32 + j, 1);
358                                 extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
359                         }
360                 }
361         }
362
363         ret = check_eb_bitmap(bitmap, eb, len);
364         if (ret) {
365                 test_err("random bit pattern failed");
366                 return ret;
367         }
368
369         return 0;
370 }
371
372 static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
373 {
374         struct btrfs_fs_info *fs_info;
375         unsigned long len;
376         unsigned long *bitmap;
377         struct extent_buffer *eb;
378         int ret;
379
380         test_msg("running extent buffer bitmap tests");
381
382         /*
383          * In ppc64, sectorsize can be 64K, thus 4 * 64K will be larger than
384          * BTRFS_MAX_METADATA_BLOCKSIZE.
385          */
386         len = (sectorsize < BTRFS_MAX_METADATA_BLOCKSIZE)
387                 ? sectorsize * 4 : sectorsize;
388
389         fs_info = btrfs_alloc_dummy_fs_info(len, len);
390
391         bitmap = kmalloc(len, GFP_KERNEL);
392         if (!bitmap) {
393                 test_err("couldn't allocate test bitmap");
394                 return -ENOMEM;
395         }
396
397         eb = __alloc_dummy_extent_buffer(fs_info, 0, len);
398         if (!eb) {
399                 test_err("couldn't allocate test extent buffer");
400                 kfree(bitmap);
401                 return -ENOMEM;
402         }
403
404         ret = __test_eb_bitmaps(bitmap, eb, len);
405         if (ret)
406                 goto out;
407
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);
411         if (!eb) {
412                 test_err("couldn't allocate test extent buffer");
413                 kfree(bitmap);
414                 return -ENOMEM;
415         }
416
417         ret = __test_eb_bitmaps(bitmap, eb, len);
418 out:
419         free_extent_buffer(eb);
420         kfree(bitmap);
421         return ret;
422 }
423
424 int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
425 {
426         int ret;
427
428         test_msg("running extent I/O tests");
429
430         ret = test_find_delalloc(sectorsize);
431         if (ret)
432                 goto out;
433
434         ret = test_eb_bitmaps(sectorsize, nodesize);
435 out:
436         test_msg("extent I/O tests finished");
437         return ret;
438 }