| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2015 Shaohua Li <shli@fb.com> |
|---|
| 3 | 4 | * Copyright (C) 2016 Song Liu <songliubraving@fb.com> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | | - * |
|---|
| 14 | 5 | */ |
|---|
| 15 | 6 | #include <linux/kernel.h> |
|---|
| 16 | 7 | #include <linux/wait.h> |
|---|
| .. | .. |
|---|
| 204 | 195 | static inline sector_t r5c_tree_index(struct r5conf *conf, |
|---|
| 205 | 196 | sector_t sect) |
|---|
| 206 | 197 | { |
|---|
| 207 | | - sector_t offset; |
|---|
| 208 | | - |
|---|
| 209 | | - offset = sector_div(sect, conf->chunk_sectors); |
|---|
| 198 | + sector_div(sect, conf->chunk_sectors); |
|---|
| 210 | 199 | return sect; |
|---|
| 211 | 200 | } |
|---|
| 212 | 201 | |
|---|
| .. | .. |
|---|
| 307 | 296 | wbi = dev->written; |
|---|
| 308 | 297 | dev->written = NULL; |
|---|
| 309 | 298 | while (wbi && wbi->bi_iter.bi_sector < |
|---|
| 310 | | - dev->sector + STRIPE_SECTORS) { |
|---|
| 311 | | - wbi2 = r5_next_bio(wbi, dev->sector); |
|---|
| 299 | + dev->sector + RAID5_STRIPE_SECTORS(conf)) { |
|---|
| 300 | + wbi2 = r5_next_bio(conf, wbi, dev->sector); |
|---|
| 312 | 301 | md_write_end(conf->mddev); |
|---|
| 313 | 302 | bio_endio(wbi); |
|---|
| 314 | 303 | wbi = wbi2; |
|---|
| .. | .. |
|---|
| 325 | 314 | set_bit(R5_UPTODATE, &sh->dev[i].flags); |
|---|
| 326 | 315 | r5c_return_dev_pending_writes(conf, &sh->dev[i]); |
|---|
| 327 | 316 | md_bitmap_endwrite(conf->mddev->bitmap, sh->sector, |
|---|
| 328 | | - STRIPE_SECTORS, |
|---|
| 317 | + RAID5_STRIPE_SECTORS(conf), |
|---|
| 329 | 318 | !test_bit(STRIPE_DEGRADED, &sh->state), |
|---|
| 330 | 319 | 0); |
|---|
| 331 | 320 | } |
|---|
| .. | .. |
|---|
| 373 | 362 | */ |
|---|
| 374 | 363 | if (atomic_read(&conf->r5c_cached_full_stripes) >= |
|---|
| 375 | 364 | min(R5C_FULL_STRIPE_FLUSH_BATCH(conf), |
|---|
| 376 | | - conf->chunk_sectors >> STRIPE_SHIFT)) |
|---|
| 365 | + conf->chunk_sectors >> RAID5_STRIPE_SHIFT(conf))) |
|---|
| 377 | 366 | r5l_wake_reclaim(conf->log, 0); |
|---|
| 378 | 367 | } |
|---|
| 379 | 368 | |
|---|
| .. | .. |
|---|
| 2439 | 2428 | struct mddev *mddev = log->rdev->mddev; |
|---|
| 2440 | 2429 | struct r5conf *conf = mddev->private; |
|---|
| 2441 | 2430 | struct stripe_head *sh, *next; |
|---|
| 2431 | + bool cleared_pending = false; |
|---|
| 2442 | 2432 | |
|---|
| 2443 | 2433 | if (ctx->data_only_stripes == 0) |
|---|
| 2444 | 2434 | return; |
|---|
| 2445 | 2435 | |
|---|
| 2436 | + if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) { |
|---|
| 2437 | + cleared_pending = true; |
|---|
| 2438 | + clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags); |
|---|
| 2439 | + } |
|---|
| 2446 | 2440 | log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_BACK; |
|---|
| 2447 | 2441 | |
|---|
| 2448 | 2442 | list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) { |
|---|
| .. | .. |
|---|
| 2457 | 2451 | atomic_read(&conf->active_stripes) == 0); |
|---|
| 2458 | 2452 | |
|---|
| 2459 | 2453 | log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH; |
|---|
| 2454 | + if (cleared_pending) |
|---|
| 2455 | + set_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags); |
|---|
| 2460 | 2456 | } |
|---|
| 2461 | 2457 | |
|---|
| 2462 | 2458 | static int r5l_recovery_log(struct r5l_log *log) |
|---|
| .. | .. |
|---|
| 2541 | 2537 | struct r5conf *conf; |
|---|
| 2542 | 2538 | int ret; |
|---|
| 2543 | 2539 | |
|---|
| 2544 | | - ret = mddev_lock(mddev); |
|---|
| 2545 | | - if (ret) |
|---|
| 2546 | | - return ret; |
|---|
| 2547 | | - |
|---|
| 2540 | + spin_lock(&mddev->lock); |
|---|
| 2548 | 2541 | conf = mddev->private; |
|---|
| 2549 | 2542 | if (!conf || !conf->log) { |
|---|
| 2550 | | - mddev_unlock(mddev); |
|---|
| 2543 | + spin_unlock(&mddev->lock); |
|---|
| 2551 | 2544 | return 0; |
|---|
| 2552 | 2545 | } |
|---|
| 2553 | 2546 | |
|---|
| .. | .. |
|---|
| 2567 | 2560 | default: |
|---|
| 2568 | 2561 | ret = 0; |
|---|
| 2569 | 2562 | } |
|---|
| 2570 | | - mddev_unlock(mddev); |
|---|
| 2563 | + spin_unlock(&mddev->lock); |
|---|
| 2571 | 2564 | return ret; |
|---|
| 2572 | 2565 | } |
|---|
| 2573 | 2566 | |
|---|
| .. | .. |
|---|
| 3162 | 3155 | set_bit(MD_HAS_JOURNAL, &conf->mddev->flags); |
|---|
| 3163 | 3156 | return 0; |
|---|
| 3164 | 3157 | |
|---|
| 3165 | | - rcu_assign_pointer(conf->log, NULL); |
|---|
| 3166 | | - md_unregister_thread(&log->reclaim_thread); |
|---|
| 3167 | 3158 | reclaim_thread: |
|---|
| 3168 | 3159 | mempool_exit(&log->meta_pool); |
|---|
| 3169 | 3160 | out_mempool: |
|---|