| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * bitmap.c two-level bitmap (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 323 | 324 | wake_up(&bitmap->write_wait); |
|---|
| 324 | 325 | } |
|---|
| 325 | 326 | |
|---|
| 326 | | -/* copied from buffer.c */ |
|---|
| 327 | | -static void |
|---|
| 328 | | -__clear_page_buffers(struct page *page) |
|---|
| 329 | | -{ |
|---|
| 330 | | - ClearPagePrivate(page); |
|---|
| 331 | | - set_page_private(page, 0); |
|---|
| 332 | | - put_page(page); |
|---|
| 333 | | -} |
|---|
| 334 | 327 | static void free_buffers(struct page *page) |
|---|
| 335 | 328 | { |
|---|
| 336 | 329 | struct buffer_head *bh; |
|---|
| .. | .. |
|---|
| 344 | 337 | free_buffer_head(bh); |
|---|
| 345 | 338 | bh = next; |
|---|
| 346 | 339 | } |
|---|
| 347 | | - __clear_page_buffers(page); |
|---|
| 340 | + detach_page_private(page); |
|---|
| 348 | 341 | put_page(page); |
|---|
| 349 | 342 | } |
|---|
| 350 | 343 | |
|---|
| .. | .. |
|---|
| 363 | 356 | int ret = 0; |
|---|
| 364 | 357 | struct inode *inode = file_inode(file); |
|---|
| 365 | 358 | struct buffer_head *bh; |
|---|
| 366 | | - sector_t block; |
|---|
| 359 | + sector_t block, blk_cur; |
|---|
| 360 | + unsigned long blocksize = i_blocksize(inode); |
|---|
| 367 | 361 | |
|---|
| 368 | 362 | pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE, |
|---|
| 369 | 363 | (unsigned long long)index << PAGE_SHIFT); |
|---|
| 370 | 364 | |
|---|
| 371 | | - bh = alloc_page_buffers(page, 1<<inode->i_blkbits, false); |
|---|
| 365 | + bh = alloc_page_buffers(page, blocksize, false); |
|---|
| 372 | 366 | if (!bh) { |
|---|
| 373 | 367 | ret = -ENOMEM; |
|---|
| 374 | 368 | goto out; |
|---|
| 375 | 369 | } |
|---|
| 376 | | - attach_page_buffers(page, bh); |
|---|
| 377 | | - block = index << (PAGE_SHIFT - inode->i_blkbits); |
|---|
| 370 | + attach_page_private(page, bh); |
|---|
| 371 | + blk_cur = index << (PAGE_SHIFT - inode->i_blkbits); |
|---|
| 378 | 372 | while (bh) { |
|---|
| 373 | + block = blk_cur; |
|---|
| 374 | + |
|---|
| 379 | 375 | if (count == 0) |
|---|
| 380 | 376 | bh->b_blocknr = 0; |
|---|
| 381 | 377 | else { |
|---|
| 382 | | - bh->b_blocknr = bmap(inode, block); |
|---|
| 383 | | - if (bh->b_blocknr == 0) { |
|---|
| 384 | | - /* Cannot use this file! */ |
|---|
| 378 | + ret = bmap(inode, &block); |
|---|
| 379 | + if (ret || !block) { |
|---|
| 385 | 380 | ret = -EINVAL; |
|---|
| 381 | + bh->b_blocknr = 0; |
|---|
| 386 | 382 | goto out; |
|---|
| 387 | 383 | } |
|---|
| 384 | + |
|---|
| 385 | + bh->b_blocknr = block; |
|---|
| 388 | 386 | bh->b_bdev = inode->i_sb->s_bdev; |
|---|
| 389 | | - if (count < (1<<inode->i_blkbits)) |
|---|
| 387 | + if (count < blocksize) |
|---|
| 390 | 388 | count = 0; |
|---|
| 391 | 389 | else |
|---|
| 392 | | - count -= (1<<inode->i_blkbits); |
|---|
| 390 | + count -= blocksize; |
|---|
| 393 | 391 | |
|---|
| 394 | 392 | bh->b_end_io = end_bitmap_write; |
|---|
| 395 | 393 | bh->b_private = bitmap; |
|---|
| .. | .. |
|---|
| 398 | 396 | set_buffer_mapped(bh); |
|---|
| 399 | 397 | submit_bh(REQ_OP_READ, 0, bh); |
|---|
| 400 | 398 | } |
|---|
| 401 | | - block++; |
|---|
| 399 | + blk_cur++; |
|---|
| 402 | 400 | bh = bh->b_this_page; |
|---|
| 403 | 401 | } |
|---|
| 404 | 402 | page->index = index; |
|---|
| .. | .. |
|---|
| 490 | 488 | pr_debug(" magic: %08x\n", le32_to_cpu(sb->magic)); |
|---|
| 491 | 489 | pr_debug(" version: %d\n", le32_to_cpu(sb->version)); |
|---|
| 492 | 490 | pr_debug(" uuid: %08x.%08x.%08x.%08x\n", |
|---|
| 493 | | - le32_to_cpu(*(__u32 *)(sb->uuid+0)), |
|---|
| 494 | | - le32_to_cpu(*(__u32 *)(sb->uuid+4)), |
|---|
| 495 | | - le32_to_cpu(*(__u32 *)(sb->uuid+8)), |
|---|
| 496 | | - le32_to_cpu(*(__u32 *)(sb->uuid+12))); |
|---|
| 491 | + le32_to_cpu(*(__le32 *)(sb->uuid+0)), |
|---|
| 492 | + le32_to_cpu(*(__le32 *)(sb->uuid+4)), |
|---|
| 493 | + le32_to_cpu(*(__le32 *)(sb->uuid+8)), |
|---|
| 494 | + le32_to_cpu(*(__le32 *)(sb->uuid+12))); |
|---|
| 497 | 495 | pr_debug(" events: %llu\n", |
|---|
| 498 | 496 | (unsigned long long) le64_to_cpu(sb->events)); |
|---|
| 499 | 497 | pr_debug("events cleared: %llu\n", |
|---|
| .. | .. |
|---|
| 608 | 606 | if (bitmap->cluster_slot >= 0) { |
|---|
| 609 | 607 | sector_t bm_blocks = bitmap->mddev->resync_max_sectors; |
|---|
| 610 | 608 | |
|---|
| 611 | | - sector_div(bm_blocks, |
|---|
| 612 | | - bitmap->mddev->bitmap_info.chunksize >> 9); |
|---|
| 609 | + bm_blocks = DIV_ROUND_UP_SECTOR_T(bm_blocks, |
|---|
| 610 | + (bitmap->mddev->bitmap_info.chunksize >> 9)); |
|---|
| 613 | 611 | /* bits to bytes */ |
|---|
| 614 | 612 | bm_blocks = ((bm_blocks+7) >> 3) + sizeof(bitmap_super_t); |
|---|
| 615 | 613 | /* to 4k blocks */ |
|---|
| .. | .. |
|---|
| 641 | 639 | daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; |
|---|
| 642 | 640 | write_behind = le32_to_cpu(sb->write_behind); |
|---|
| 643 | 641 | sectors_reserved = le32_to_cpu(sb->sectors_reserved); |
|---|
| 644 | | - /* Setup nodes/clustername only if bitmap version is |
|---|
| 645 | | - * cluster-compatible |
|---|
| 646 | | - */ |
|---|
| 647 | | - if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { |
|---|
| 648 | | - nodes = le32_to_cpu(sb->nodes); |
|---|
| 649 | | - strlcpy(bitmap->mddev->bitmap_info.cluster_name, |
|---|
| 650 | | - sb->cluster_name, 64); |
|---|
| 651 | | - } |
|---|
| 652 | 642 | |
|---|
| 653 | 643 | /* verify that the bitmap-specific fields are valid */ |
|---|
| 654 | 644 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) |
|---|
| .. | .. |
|---|
| 668 | 658 | pr_warn("%s: invalid bitmap file superblock: %s\n", |
|---|
| 669 | 659 | bmname(bitmap), reason); |
|---|
| 670 | 660 | goto out; |
|---|
| 661 | + } |
|---|
| 662 | + |
|---|
| 663 | + /* |
|---|
| 664 | + * Setup nodes/clustername only if bitmap version is |
|---|
| 665 | + * cluster-compatible |
|---|
| 666 | + */ |
|---|
| 667 | + if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { |
|---|
| 668 | + nodes = le32_to_cpu(sb->nodes); |
|---|
| 669 | + strlcpy(bitmap->mddev->bitmap_info.cluster_name, |
|---|
| 670 | + sb->cluster_name, 64); |
|---|
| 671 | 671 | } |
|---|
| 672 | 672 | |
|---|
| 673 | 673 | /* keep the array size field of the bitmap superblock up to date */ |
|---|
| .. | .. |
|---|
| 702 | 702 | |
|---|
| 703 | 703 | out: |
|---|
| 704 | 704 | kunmap_atomic(sb); |
|---|
| 705 | | - /* Assigning chunksize is required for "re_read" */ |
|---|
| 706 | | - bitmap->mddev->bitmap_info.chunksize = chunksize; |
|---|
| 707 | 705 | if (err == 0 && nodes && (bitmap->cluster_slot < 0)) { |
|---|
| 706 | + /* Assigning chunksize is required for "re_read" */ |
|---|
| 707 | + bitmap->mddev->bitmap_info.chunksize = chunksize; |
|---|
| 708 | 708 | err = md_setup_cluster(bitmap->mddev, nodes); |
|---|
| 709 | 709 | if (err) { |
|---|
| 710 | 710 | pr_warn("%s: Could not setup cluster service (%d)\n", |
|---|
| .. | .. |
|---|
| 715 | 715 | goto re_read; |
|---|
| 716 | 716 | } |
|---|
| 717 | 717 | |
|---|
| 718 | | - |
|---|
| 719 | 718 | out_no_sb: |
|---|
| 720 | | - if (test_bit(BITMAP_STALE, &bitmap->flags)) |
|---|
| 721 | | - bitmap->events_cleared = bitmap->mddev->events; |
|---|
| 722 | | - bitmap->mddev->bitmap_info.chunksize = chunksize; |
|---|
| 723 | | - bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; |
|---|
| 724 | | - bitmap->mddev->bitmap_info.max_write_behind = write_behind; |
|---|
| 725 | | - bitmap->mddev->bitmap_info.nodes = nodes; |
|---|
| 726 | | - if (bitmap->mddev->bitmap_info.space == 0 || |
|---|
| 727 | | - bitmap->mddev->bitmap_info.space > sectors_reserved) |
|---|
| 728 | | - bitmap->mddev->bitmap_info.space = sectors_reserved; |
|---|
| 729 | | - if (err) { |
|---|
| 719 | + if (err == 0) { |
|---|
| 720 | + if (test_bit(BITMAP_STALE, &bitmap->flags)) |
|---|
| 721 | + bitmap->events_cleared = bitmap->mddev->events; |
|---|
| 722 | + bitmap->mddev->bitmap_info.chunksize = chunksize; |
|---|
| 723 | + bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; |
|---|
| 724 | + bitmap->mddev->bitmap_info.max_write_behind = write_behind; |
|---|
| 725 | + bitmap->mddev->bitmap_info.nodes = nodes; |
|---|
| 726 | + if (bitmap->mddev->bitmap_info.space == 0 || |
|---|
| 727 | + bitmap->mddev->bitmap_info.space > sectors_reserved) |
|---|
| 728 | + bitmap->mddev->bitmap_info.space = sectors_reserved; |
|---|
| 729 | + } else { |
|---|
| 730 | 730 | md_bitmap_print_sb(bitmap); |
|---|
| 731 | 731 | if (bitmap->cluster_slot < 0) |
|---|
| 732 | 732 | md_cluster_stop(bitmap->mddev); |
|---|
| .. | .. |
|---|
| 1018 | 1018 | /* look at each page to see if there are any set bits that need to be |
|---|
| 1019 | 1019 | * flushed out to disk */ |
|---|
| 1020 | 1020 | for (i = 0; i < bitmap->storage.file_pages; i++) { |
|---|
| 1021 | | - if (!bitmap->storage.filemap) |
|---|
| 1022 | | - return; |
|---|
| 1023 | 1021 | dirty = test_and_clear_page_attr(bitmap, i, BITMAP_PAGE_DIRTY); |
|---|
| 1024 | 1022 | need_write = test_and_clear_page_attr(bitmap, i, |
|---|
| 1025 | 1023 | BITMAP_PAGE_NEEDWRITE); |
|---|
| .. | .. |
|---|
| 1337 | 1335 | BITMAP_PAGE_DIRTY)) |
|---|
| 1338 | 1336 | /* bitmap_unplug will handle the rest */ |
|---|
| 1339 | 1337 | break; |
|---|
| 1340 | | - if (test_and_clear_page_attr(bitmap, j, |
|---|
| 1338 | + if (bitmap->storage.filemap && |
|---|
| 1339 | + test_and_clear_page_attr(bitmap, j, |
|---|
| 1341 | 1340 | BITMAP_PAGE_NEEDWRITE)) { |
|---|
| 1342 | 1341 | write_page(bitmap, bitmap->storage.filemap[j], 0); |
|---|
| 1343 | 1342 | } |
|---|
| .. | .. |
|---|
| 1437 | 1436 | case 0: |
|---|
| 1438 | 1437 | md_bitmap_file_set_bit(bitmap, offset); |
|---|
| 1439 | 1438 | md_bitmap_count_page(&bitmap->counts, offset, 1); |
|---|
| 1440 | | - /* fall through */ |
|---|
| 1439 | + fallthrough; |
|---|
| 1441 | 1440 | case 1: |
|---|
| 1442 | 1441 | *bmc = 2; |
|---|
| 1443 | 1442 | } |
|---|
| .. | .. |
|---|
| 1635 | 1634 | s += blocks; |
|---|
| 1636 | 1635 | } |
|---|
| 1637 | 1636 | bitmap->last_end_sync = jiffies; |
|---|
| 1638 | | - sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed"); |
|---|
| 1637 | + sysfs_notify_dirent_safe(bitmap->mddev->sysfs_completed); |
|---|
| 1639 | 1638 | } |
|---|
| 1640 | 1639 | EXPORT_SYMBOL(md_bitmap_cond_end_sync); |
|---|
| 1641 | 1640 | |
|---|
| .. | .. |
|---|
| 1791 | 1790 | return; |
|---|
| 1792 | 1791 | |
|---|
| 1793 | 1792 | md_bitmap_wait_behind_writes(mddev); |
|---|
| 1793 | + if (!mddev->serialize_policy) |
|---|
| 1794 | + mddev_destroy_serial_pool(mddev, NULL, true); |
|---|
| 1794 | 1795 | |
|---|
| 1795 | 1796 | mutex_lock(&mddev->bitmap_info.mutex); |
|---|
| 1796 | 1797 | spin_lock(&mddev->lock); |
|---|
| .. | .. |
|---|
| 1901 | 1902 | sector_t start = 0; |
|---|
| 1902 | 1903 | sector_t sector = 0; |
|---|
| 1903 | 1904 | struct bitmap *bitmap = mddev->bitmap; |
|---|
| 1905 | + struct md_rdev *rdev; |
|---|
| 1904 | 1906 | |
|---|
| 1905 | 1907 | if (!bitmap) |
|---|
| 1906 | 1908 | goto out; |
|---|
| 1909 | + |
|---|
| 1910 | + rdev_for_each(rdev, mddev) |
|---|
| 1911 | + mddev_create_serial_pool(mddev, rdev, true); |
|---|
| 1907 | 1912 | |
|---|
| 1908 | 1913 | if (mddev_is_clustered(mddev)) |
|---|
| 1909 | 1914 | md_cluster_ops->load_bitmaps(mddev, mddev->bitmap_info.nodes); |
|---|
| .. | .. |
|---|
| 1949 | 1954 | } |
|---|
| 1950 | 1955 | EXPORT_SYMBOL_GPL(md_bitmap_load); |
|---|
| 1951 | 1956 | |
|---|
| 1957 | +/* caller need to free returned bitmap with md_bitmap_free() */ |
|---|
| 1952 | 1958 | struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) |
|---|
| 1953 | 1959 | { |
|---|
| 1954 | 1960 | int rv = 0; |
|---|
| .. | .. |
|---|
| 2012 | 2018 | md_bitmap_unplug(mddev->bitmap); |
|---|
| 2013 | 2019 | *low = lo; |
|---|
| 2014 | 2020 | *high = hi; |
|---|
| 2021 | + md_bitmap_free(bitmap); |
|---|
| 2015 | 2022 | |
|---|
| 2016 | 2023 | return rv; |
|---|
| 2017 | 2024 | } |
|---|
| .. | .. |
|---|
| 2290 | 2297 | goto out; |
|---|
| 2291 | 2298 | } |
|---|
| 2292 | 2299 | if (mddev->pers) { |
|---|
| 2293 | | - mddev->pers->quiesce(mddev, 1); |
|---|
| 2300 | + mddev_suspend(mddev); |
|---|
| 2294 | 2301 | md_bitmap_destroy(mddev); |
|---|
| 2295 | | - mddev->pers->quiesce(mddev, 0); |
|---|
| 2302 | + mddev_resume(mddev); |
|---|
| 2296 | 2303 | } |
|---|
| 2297 | 2304 | mddev->bitmap_info.offset = 0; |
|---|
| 2298 | 2305 | if (mddev->bitmap_info.file) { |
|---|
| .. | .. |
|---|
| 2329 | 2336 | mddev->bitmap_info.offset = offset; |
|---|
| 2330 | 2337 | if (mddev->pers) { |
|---|
| 2331 | 2338 | struct bitmap *bitmap; |
|---|
| 2332 | | - mddev->pers->quiesce(mddev, 1); |
|---|
| 2333 | 2339 | bitmap = md_bitmap_create(mddev, -1); |
|---|
| 2340 | + mddev_suspend(mddev); |
|---|
| 2334 | 2341 | if (IS_ERR(bitmap)) |
|---|
| 2335 | 2342 | rv = PTR_ERR(bitmap); |
|---|
| 2336 | 2343 | else { |
|---|
| .. | .. |
|---|
| 2339 | 2346 | if (rv) |
|---|
| 2340 | 2347 | mddev->bitmap_info.offset = 0; |
|---|
| 2341 | 2348 | } |
|---|
| 2342 | | - mddev->pers->quiesce(mddev, 0); |
|---|
| 2343 | 2349 | if (rv) { |
|---|
| 2344 | 2350 | md_bitmap_destroy(mddev); |
|---|
| 2351 | + mddev_resume(mddev); |
|---|
| 2345 | 2352 | goto out; |
|---|
| 2346 | 2353 | } |
|---|
| 2354 | + mddev_resume(mddev); |
|---|
| 2347 | 2355 | } |
|---|
| 2348 | 2356 | } |
|---|
| 2349 | 2357 | } |
|---|
| .. | .. |
|---|
| 2462 | 2470 | backlog_store(struct mddev *mddev, const char *buf, size_t len) |
|---|
| 2463 | 2471 | { |
|---|
| 2464 | 2472 | unsigned long backlog; |
|---|
| 2473 | + unsigned long old_mwb = mddev->bitmap_info.max_write_behind; |
|---|
| 2465 | 2474 | int rv = kstrtoul(buf, 10, &backlog); |
|---|
| 2466 | 2475 | if (rv) |
|---|
| 2467 | 2476 | return rv; |
|---|
| 2468 | 2477 | if (backlog > COUNTER_MAX) |
|---|
| 2469 | 2478 | return -EINVAL; |
|---|
| 2470 | 2479 | mddev->bitmap_info.max_write_behind = backlog; |
|---|
| 2480 | + if (!backlog && mddev->serial_info_pool) { |
|---|
| 2481 | + /* serial_info_pool is not needed if backlog is zero */ |
|---|
| 2482 | + if (!mddev->serialize_policy) |
|---|
| 2483 | + mddev_destroy_serial_pool(mddev, NULL, false); |
|---|
| 2484 | + } else if (backlog && !mddev->serial_info_pool) { |
|---|
| 2485 | + /* serial_info_pool is needed since backlog is not zero */ |
|---|
| 2486 | + struct md_rdev *rdev; |
|---|
| 2487 | + |
|---|
| 2488 | + rdev_for_each(rdev, mddev) |
|---|
| 2489 | + mddev_create_serial_pool(mddev, rdev, false); |
|---|
| 2490 | + } |
|---|
| 2491 | + if (old_mwb != backlog) |
|---|
| 2492 | + md_bitmap_update_sb(mddev->bitmap); |
|---|
| 2471 | 2493 | return len; |
|---|
| 2472 | 2494 | } |
|---|
| 2473 | 2495 | |
|---|
| .. | .. |
|---|
| 2600 | 2622 | .name = "bitmap", |
|---|
| 2601 | 2623 | .attrs = md_bitmap_attrs, |
|---|
| 2602 | 2624 | }; |
|---|
| 2603 | | - |
|---|