.. | .. |
---|
54 | 54 | { |
---|
55 | 55 | unsigned char *mappage; |
---|
56 | 56 | |
---|
57 | | - if (page >= bitmap->pages) { |
---|
58 | | - /* This can happen if bitmap_start_sync goes beyond |
---|
59 | | - * End-of-device while looking for a whole page. |
---|
60 | | - * It is harmless. |
---|
61 | | - */ |
---|
62 | | - return -EINVAL; |
---|
63 | | - } |
---|
64 | | - |
---|
| 57 | + WARN_ON_ONCE(page >= bitmap->pages); |
---|
65 | 58 | if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ |
---|
66 | 59 | return 0; |
---|
67 | 60 | |
---|
.. | .. |
---|
486 | 479 | sb = kmap_atomic(bitmap->storage.sb_page); |
---|
487 | 480 | pr_debug("%s: bitmap file superblock:\n", bmname(bitmap)); |
---|
488 | 481 | pr_debug(" magic: %08x\n", le32_to_cpu(sb->magic)); |
---|
489 | | - pr_debug(" version: %d\n", le32_to_cpu(sb->version)); |
---|
| 482 | + pr_debug(" version: %u\n", le32_to_cpu(sb->version)); |
---|
490 | 483 | pr_debug(" uuid: %08x.%08x.%08x.%08x\n", |
---|
491 | 484 | le32_to_cpu(*(__le32 *)(sb->uuid+0)), |
---|
492 | 485 | le32_to_cpu(*(__le32 *)(sb->uuid+4)), |
---|
.. | .. |
---|
497 | 490 | pr_debug("events cleared: %llu\n", |
---|
498 | 491 | (unsigned long long) le64_to_cpu(sb->events_cleared)); |
---|
499 | 492 | pr_debug(" state: %08x\n", le32_to_cpu(sb->state)); |
---|
500 | | - pr_debug(" chunksize: %d B\n", le32_to_cpu(sb->chunksize)); |
---|
501 | | - pr_debug(" daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); |
---|
| 493 | + pr_debug(" chunksize: %u B\n", le32_to_cpu(sb->chunksize)); |
---|
| 494 | + pr_debug(" daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep)); |
---|
502 | 495 | pr_debug(" sync size: %llu KB\n", |
---|
503 | 496 | (unsigned long long)le64_to_cpu(sb->sync_size)/2); |
---|
504 | | - pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind)); |
---|
| 497 | + pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind)); |
---|
505 | 498 | kunmap_atomic(sb); |
---|
506 | 499 | } |
---|
507 | 500 | |
---|
.. | .. |
---|
1365 | 1358 | sector_t csize; |
---|
1366 | 1359 | int err; |
---|
1367 | 1360 | |
---|
| 1361 | + if (page >= bitmap->pages) { |
---|
| 1362 | + /* |
---|
| 1363 | + * This can happen if bitmap_start_sync goes beyond |
---|
| 1364 | + * End-of-device while looking for a whole page or |
---|
| 1365 | + * user set a huge number to sysfs bitmap_set_bits. |
---|
| 1366 | + */ |
---|
| 1367 | + return NULL; |
---|
| 1368 | + } |
---|
1368 | 1369 | err = md_bitmap_checkpage(bitmap, page, create, 0); |
---|
1369 | 1370 | |
---|
1370 | 1371 | if (bitmap->bp[page].hijacked || |
---|
.. | .. |
---|
2106 | 2107 | bytes = DIV_ROUND_UP(chunks, 8); |
---|
2107 | 2108 | if (!bitmap->mddev->bitmap_info.external) |
---|
2108 | 2109 | bytes += sizeof(bitmap_super_t); |
---|
2109 | | - } while (bytes > (space << 9)); |
---|
| 2110 | + } while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) < |
---|
| 2111 | + (BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1)); |
---|
2110 | 2112 | } else |
---|
2111 | 2113 | chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT; |
---|
2112 | 2114 | |
---|
.. | .. |
---|
2151 | 2153 | bitmap->counts.missing_pages = pages; |
---|
2152 | 2154 | bitmap->counts.chunkshift = chunkshift; |
---|
2153 | 2155 | bitmap->counts.chunks = chunks; |
---|
2154 | | - bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift + |
---|
| 2156 | + bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift + |
---|
2155 | 2157 | BITMAP_BLOCK_SHIFT); |
---|
2156 | 2158 | |
---|
2157 | 2159 | blocks = min(old_counts.chunks << old_counts.chunkshift, |
---|
.. | .. |
---|
2177 | 2179 | bitmap->counts.missing_pages = old_counts.pages; |
---|
2178 | 2180 | bitmap->counts.chunkshift = old_counts.chunkshift; |
---|
2179 | 2181 | bitmap->counts.chunks = old_counts.chunks; |
---|
2180 | | - bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift + |
---|
2181 | | - BITMAP_BLOCK_SHIFT); |
---|
| 2182 | + bitmap->mddev->bitmap_info.chunksize = |
---|
| 2183 | + 1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT); |
---|
2182 | 2184 | blocks = old_counts.chunks << old_counts.chunkshift; |
---|
2183 | 2185 | pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n"); |
---|
2184 | 2186 | break; |
---|
.. | .. |
---|
2196 | 2198 | |
---|
2197 | 2199 | if (set) { |
---|
2198 | 2200 | bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1); |
---|
2199 | | - if (*bmc_new == 0) { |
---|
2200 | | - /* need to set on-disk bits too. */ |
---|
2201 | | - sector_t end = block + new_blocks; |
---|
2202 | | - sector_t start = block >> chunkshift; |
---|
2203 | | - start <<= chunkshift; |
---|
2204 | | - while (start < end) { |
---|
2205 | | - md_bitmap_file_set_bit(bitmap, block); |
---|
2206 | | - start += 1 << chunkshift; |
---|
| 2201 | + if (bmc_new) { |
---|
| 2202 | + if (*bmc_new == 0) { |
---|
| 2203 | + /* need to set on-disk bits too. */ |
---|
| 2204 | + sector_t end = block + new_blocks; |
---|
| 2205 | + sector_t start = block >> chunkshift; |
---|
| 2206 | + |
---|
| 2207 | + start <<= chunkshift; |
---|
| 2208 | + while (start < end) { |
---|
| 2209 | + md_bitmap_file_set_bit(bitmap, block); |
---|
| 2210 | + start += 1 << chunkshift; |
---|
| 2211 | + } |
---|
| 2212 | + *bmc_new = 2; |
---|
| 2213 | + md_bitmap_count_page(&bitmap->counts, block, 1); |
---|
| 2214 | + md_bitmap_set_pending(&bitmap->counts, block); |
---|
2207 | 2215 | } |
---|
2208 | | - *bmc_new = 2; |
---|
2209 | | - md_bitmap_count_page(&bitmap->counts, block, 1); |
---|
2210 | | - md_bitmap_set_pending(&bitmap->counts, block); |
---|
| 2216 | + *bmc_new |= NEEDED_MASK; |
---|
2211 | 2217 | } |
---|
2212 | | - *bmc_new |= NEEDED_MASK; |
---|
2213 | 2218 | if (new_blocks < old_blocks) |
---|
2214 | 2219 | old_blocks = new_blocks; |
---|
2215 | 2220 | } |
---|
.. | .. |
---|
2471 | 2476 | { |
---|
2472 | 2477 | unsigned long backlog; |
---|
2473 | 2478 | unsigned long old_mwb = mddev->bitmap_info.max_write_behind; |
---|
| 2479 | + struct md_rdev *rdev; |
---|
| 2480 | + bool has_write_mostly = false; |
---|
2474 | 2481 | int rv = kstrtoul(buf, 10, &backlog); |
---|
2475 | 2482 | if (rv) |
---|
2476 | 2483 | return rv; |
---|
2477 | 2484 | if (backlog > COUNTER_MAX) |
---|
2478 | 2485 | return -EINVAL; |
---|
| 2486 | + |
---|
| 2487 | + rv = mddev_lock(mddev); |
---|
| 2488 | + if (rv) |
---|
| 2489 | + return rv; |
---|
| 2490 | + |
---|
| 2491 | + /* |
---|
| 2492 | + * Without write mostly device, it doesn't make sense to set |
---|
| 2493 | + * backlog for max_write_behind. |
---|
| 2494 | + */ |
---|
| 2495 | + rdev_for_each(rdev, mddev) { |
---|
| 2496 | + if (test_bit(WriteMostly, &rdev->flags)) { |
---|
| 2497 | + has_write_mostly = true; |
---|
| 2498 | + break; |
---|
| 2499 | + } |
---|
| 2500 | + } |
---|
| 2501 | + if (!has_write_mostly) { |
---|
| 2502 | + pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n", |
---|
| 2503 | + mdname(mddev)); |
---|
| 2504 | + mddev_unlock(mddev); |
---|
| 2505 | + return -EINVAL; |
---|
| 2506 | + } |
---|
| 2507 | + |
---|
2479 | 2508 | mddev->bitmap_info.max_write_behind = backlog; |
---|
2480 | 2509 | if (!backlog && mddev->serial_info_pool) { |
---|
2481 | 2510 | /* serial_info_pool is not needed if backlog is zero */ |
---|
.. | .. |
---|
2483 | 2512 | mddev_destroy_serial_pool(mddev, NULL, false); |
---|
2484 | 2513 | } else if (backlog && !mddev->serial_info_pool) { |
---|
2485 | 2514 | /* serial_info_pool is needed since backlog is not zero */ |
---|
2486 | | - struct md_rdev *rdev; |
---|
2487 | | - |
---|
2488 | 2515 | rdev_for_each(rdev, mddev) |
---|
2489 | 2516 | mddev_create_serial_pool(mddev, rdev, false); |
---|
2490 | 2517 | } |
---|
2491 | 2518 | if (old_mwb != backlog) |
---|
2492 | 2519 | md_bitmap_update_sb(mddev->bitmap); |
---|
| 2520 | + |
---|
| 2521 | + mddev_unlock(mddev); |
---|
2493 | 2522 | return len; |
---|
2494 | 2523 | } |
---|
2495 | 2524 | |
---|
.. | .. |
---|
2516 | 2545 | if (csize < 512 || |
---|
2517 | 2546 | !is_power_of_2(csize)) |
---|
2518 | 2547 | return -EINVAL; |
---|
| 2548 | + if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE * |
---|
| 2549 | + sizeof(((bitmap_super_t *)0)->chunksize)))) |
---|
| 2550 | + return -EOVERFLOW; |
---|
2519 | 2551 | mddev->bitmap_info.chunksize = csize; |
---|
2520 | 2552 | return len; |
---|
2521 | 2553 | } |
---|