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 } 439