| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | md.c : Multiple Devices driver for Linux |
|---|
| 3 | 4 | Copyright (C) 1998, 1999, 2000 Ingo Molnar |
|---|
| .. | .. |
|---|
| 22 | 23 | - persistent bitmap code |
|---|
| 23 | 24 | Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc. |
|---|
| 24 | 25 | |
|---|
| 25 | | - This program is free software; you can redistribute it and/or modify |
|---|
| 26 | | - it under the terms of the GNU General Public License as published by |
|---|
| 27 | | - the Free Software Foundation; either version 2, or (at your option) |
|---|
| 28 | | - any later version. |
|---|
| 29 | | - |
|---|
| 30 | | - You should have received a copy of the GNU General Public License |
|---|
| 31 | | - (for example /usr/src/linux/COPYING); if not, write to the Free |
|---|
| 32 | | - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 33 | 26 | |
|---|
| 34 | 27 | Errors, Warnings, etc. |
|---|
| 35 | 28 | Please use: |
|---|
| .. | .. |
|---|
| 44 | 37 | |
|---|
| 45 | 38 | */ |
|---|
| 46 | 39 | |
|---|
| 40 | +#include <linux/sched/mm.h> |
|---|
| 47 | 41 | #include <linux/sched/signal.h> |
|---|
| 48 | 42 | #include <linux/kthread.h> |
|---|
| 49 | 43 | #include <linux/blkdev.h> |
|---|
| .. | .. |
|---|
| 64 | 58 | #include <linux/delay.h> |
|---|
| 65 | 59 | #include <linux/raid/md_p.h> |
|---|
| 66 | 60 | #include <linux/raid/md_u.h> |
|---|
| 61 | +#include <linux/raid/detect.h> |
|---|
| 67 | 62 | #include <linux/slab.h> |
|---|
| 68 | 63 | #include <linux/percpu-refcount.h> |
|---|
| 64 | +#include <linux/part_stat.h> |
|---|
| 69 | 65 | |
|---|
| 70 | 66 | #include <trace/events/block.h> |
|---|
| 71 | 67 | #include "md.h" |
|---|
| 72 | 68 | #include "md-bitmap.h" |
|---|
| 73 | 69 | #include "md-cluster.h" |
|---|
| 74 | | - |
|---|
| 75 | | -#ifndef MODULE |
|---|
| 76 | | -static void autostart_arrays(int part); |
|---|
| 77 | | -#endif |
|---|
| 78 | 70 | |
|---|
| 79 | 71 | /* pers_list is a list of registered personalities protected |
|---|
| 80 | 72 | * by pers_lock. |
|---|
| .. | .. |
|---|
| 88 | 80 | |
|---|
| 89 | 81 | struct md_cluster_operations *md_cluster_ops; |
|---|
| 90 | 82 | EXPORT_SYMBOL(md_cluster_ops); |
|---|
| 91 | | -struct module *md_cluster_mod; |
|---|
| 92 | | -EXPORT_SYMBOL(md_cluster_mod); |
|---|
| 83 | +static struct module *md_cluster_mod; |
|---|
| 93 | 84 | |
|---|
| 94 | 85 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); |
|---|
| 95 | 86 | static struct workqueue_struct *md_wq; |
|---|
| 96 | 87 | static struct workqueue_struct *md_misc_wq; |
|---|
| 88 | +static struct workqueue_struct *md_rdev_misc_wq; |
|---|
| 97 | 89 | |
|---|
| 98 | 90 | static int remove_and_add_spares(struct mddev *mddev, |
|---|
| 99 | 91 | struct md_rdev *this); |
|---|
| .. | .. |
|---|
| 105 | 97 | * count by 2 for every hour elapsed between read errors. |
|---|
| 106 | 98 | */ |
|---|
| 107 | 99 | #define MD_DEFAULT_MAX_CORRECTED_READ_ERRORS 20 |
|---|
| 100 | +/* Default safemode delay: 200 msec */ |
|---|
| 101 | +#define DEFAULT_SAFEMODE_DELAY ((200 * HZ)/1000 +1) |
|---|
| 108 | 102 | /* |
|---|
| 109 | 103 | * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit' |
|---|
| 110 | 104 | * is 1000 KB/sec, so the extra system load does not show up that much. |
|---|
| .. | .. |
|---|
| 130 | 124 | { |
|---|
| 131 | 125 | return mddev->sync_speed_max ? |
|---|
| 132 | 126 | mddev->sync_speed_max : sysctl_speed_limit_max; |
|---|
| 127 | +} |
|---|
| 128 | + |
|---|
| 129 | +static void rdev_uninit_serial(struct md_rdev *rdev) |
|---|
| 130 | +{ |
|---|
| 131 | + if (!test_and_clear_bit(CollisionCheck, &rdev->flags)) |
|---|
| 132 | + return; |
|---|
| 133 | + |
|---|
| 134 | + kvfree(rdev->serial); |
|---|
| 135 | + rdev->serial = NULL; |
|---|
| 136 | +} |
|---|
| 137 | + |
|---|
| 138 | +static void rdevs_uninit_serial(struct mddev *mddev) |
|---|
| 139 | +{ |
|---|
| 140 | + struct md_rdev *rdev; |
|---|
| 141 | + |
|---|
| 142 | + rdev_for_each(rdev, mddev) |
|---|
| 143 | + rdev_uninit_serial(rdev); |
|---|
| 144 | +} |
|---|
| 145 | + |
|---|
| 146 | +static int rdev_init_serial(struct md_rdev *rdev) |
|---|
| 147 | +{ |
|---|
| 148 | + /* serial_nums equals with BARRIER_BUCKETS_NR */ |
|---|
| 149 | + int i, serial_nums = 1 << ((PAGE_SHIFT - ilog2(sizeof(atomic_t)))); |
|---|
| 150 | + struct serial_in_rdev *serial = NULL; |
|---|
| 151 | + |
|---|
| 152 | + if (test_bit(CollisionCheck, &rdev->flags)) |
|---|
| 153 | + return 0; |
|---|
| 154 | + |
|---|
| 155 | + serial = kvmalloc(sizeof(struct serial_in_rdev) * serial_nums, |
|---|
| 156 | + GFP_KERNEL); |
|---|
| 157 | + if (!serial) |
|---|
| 158 | + return -ENOMEM; |
|---|
| 159 | + |
|---|
| 160 | + for (i = 0; i < serial_nums; i++) { |
|---|
| 161 | + struct serial_in_rdev *serial_tmp = &serial[i]; |
|---|
| 162 | + |
|---|
| 163 | + spin_lock_init(&serial_tmp->serial_lock); |
|---|
| 164 | + serial_tmp->serial_rb = RB_ROOT_CACHED; |
|---|
| 165 | + init_waitqueue_head(&serial_tmp->serial_io_wait); |
|---|
| 166 | + } |
|---|
| 167 | + |
|---|
| 168 | + rdev->serial = serial; |
|---|
| 169 | + set_bit(CollisionCheck, &rdev->flags); |
|---|
| 170 | + |
|---|
| 171 | + return 0; |
|---|
| 172 | +} |
|---|
| 173 | + |
|---|
| 174 | +static int rdevs_init_serial(struct mddev *mddev) |
|---|
| 175 | +{ |
|---|
| 176 | + struct md_rdev *rdev; |
|---|
| 177 | + int ret = 0; |
|---|
| 178 | + |
|---|
| 179 | + rdev_for_each(rdev, mddev) { |
|---|
| 180 | + ret = rdev_init_serial(rdev); |
|---|
| 181 | + if (ret) |
|---|
| 182 | + break; |
|---|
| 183 | + } |
|---|
| 184 | + |
|---|
| 185 | + /* Free all resources if pool is not existed */ |
|---|
| 186 | + if (ret && !mddev->serial_info_pool) |
|---|
| 187 | + rdevs_uninit_serial(mddev); |
|---|
| 188 | + |
|---|
| 189 | + return ret; |
|---|
| 190 | +} |
|---|
| 191 | + |
|---|
| 192 | +/* |
|---|
| 193 | + * rdev needs to enable serial stuffs if it meets the conditions: |
|---|
| 194 | + * 1. it is multi-queue device flaged with writemostly. |
|---|
| 195 | + * 2. the write-behind mode is enabled. |
|---|
| 196 | + */ |
|---|
| 197 | +static int rdev_need_serial(struct md_rdev *rdev) |
|---|
| 198 | +{ |
|---|
| 199 | + return (rdev && rdev->mddev->bitmap_info.max_write_behind > 0 && |
|---|
| 200 | + rdev->bdev->bd_disk->queue->nr_hw_queues != 1 && |
|---|
| 201 | + test_bit(WriteMostly, &rdev->flags)); |
|---|
| 202 | +} |
|---|
| 203 | + |
|---|
| 204 | +/* |
|---|
| 205 | + * Init resource for rdev(s), then create serial_info_pool if: |
|---|
| 206 | + * 1. rdev is the first device which return true from rdev_enable_serial. |
|---|
| 207 | + * 2. rdev is NULL, means we want to enable serialization for all rdevs. |
|---|
| 208 | + */ |
|---|
| 209 | +void mddev_create_serial_pool(struct mddev *mddev, struct md_rdev *rdev, |
|---|
| 210 | + bool is_suspend) |
|---|
| 211 | +{ |
|---|
| 212 | + int ret = 0; |
|---|
| 213 | + |
|---|
| 214 | + if (rdev && !rdev_need_serial(rdev) && |
|---|
| 215 | + !test_bit(CollisionCheck, &rdev->flags)) |
|---|
| 216 | + return; |
|---|
| 217 | + |
|---|
| 218 | + if (!is_suspend) |
|---|
| 219 | + mddev_suspend(mddev); |
|---|
| 220 | + |
|---|
| 221 | + if (!rdev) |
|---|
| 222 | + ret = rdevs_init_serial(mddev); |
|---|
| 223 | + else |
|---|
| 224 | + ret = rdev_init_serial(rdev); |
|---|
| 225 | + if (ret) |
|---|
| 226 | + goto abort; |
|---|
| 227 | + |
|---|
| 228 | + if (mddev->serial_info_pool == NULL) { |
|---|
| 229 | + /* |
|---|
| 230 | + * already in memalloc noio context by |
|---|
| 231 | + * mddev_suspend() |
|---|
| 232 | + */ |
|---|
| 233 | + mddev->serial_info_pool = |
|---|
| 234 | + mempool_create_kmalloc_pool(NR_SERIAL_INFOS, |
|---|
| 235 | + sizeof(struct serial_info)); |
|---|
| 236 | + if (!mddev->serial_info_pool) { |
|---|
| 237 | + rdevs_uninit_serial(mddev); |
|---|
| 238 | + pr_err("can't alloc memory pool for serialization\n"); |
|---|
| 239 | + } |
|---|
| 240 | + } |
|---|
| 241 | + |
|---|
| 242 | +abort: |
|---|
| 243 | + if (!is_suspend) |
|---|
| 244 | + mddev_resume(mddev); |
|---|
| 245 | +} |
|---|
| 246 | + |
|---|
| 247 | +/* |
|---|
| 248 | + * Free resource from rdev(s), and destroy serial_info_pool under conditions: |
|---|
| 249 | + * 1. rdev is the last device flaged with CollisionCheck. |
|---|
| 250 | + * 2. when bitmap is destroyed while policy is not enabled. |
|---|
| 251 | + * 3. for disable policy, the pool is destroyed only when no rdev needs it. |
|---|
| 252 | + */ |
|---|
| 253 | +void mddev_destroy_serial_pool(struct mddev *mddev, struct md_rdev *rdev, |
|---|
| 254 | + bool is_suspend) |
|---|
| 255 | +{ |
|---|
| 256 | + if (rdev && !test_bit(CollisionCheck, &rdev->flags)) |
|---|
| 257 | + return; |
|---|
| 258 | + |
|---|
| 259 | + if (mddev->serial_info_pool) { |
|---|
| 260 | + struct md_rdev *temp; |
|---|
| 261 | + int num = 0; /* used to track if other rdevs need the pool */ |
|---|
| 262 | + |
|---|
| 263 | + if (!is_suspend) |
|---|
| 264 | + mddev_suspend(mddev); |
|---|
| 265 | + rdev_for_each(temp, mddev) { |
|---|
| 266 | + if (!rdev) { |
|---|
| 267 | + if (!mddev->serialize_policy || |
|---|
| 268 | + !rdev_need_serial(temp)) |
|---|
| 269 | + rdev_uninit_serial(temp); |
|---|
| 270 | + else |
|---|
| 271 | + num++; |
|---|
| 272 | + } else if (temp != rdev && |
|---|
| 273 | + test_bit(CollisionCheck, &temp->flags)) |
|---|
| 274 | + num++; |
|---|
| 275 | + } |
|---|
| 276 | + |
|---|
| 277 | + if (rdev) |
|---|
| 278 | + rdev_uninit_serial(rdev); |
|---|
| 279 | + |
|---|
| 280 | + if (num) |
|---|
| 281 | + pr_info("The mempool could be used by other devices\n"); |
|---|
| 282 | + else { |
|---|
| 283 | + mempool_destroy(mddev->serial_info_pool); |
|---|
| 284 | + mddev->serial_info_pool = NULL; |
|---|
| 285 | + } |
|---|
| 286 | + if (!is_suspend) |
|---|
| 287 | + mddev_resume(mddev); |
|---|
| 288 | + } |
|---|
| 133 | 289 | } |
|---|
| 134 | 290 | |
|---|
| 135 | 291 | static struct ctl_table_header *raid_table_header; |
|---|
| .. | .. |
|---|
| 172 | 328 | { } |
|---|
| 173 | 329 | }; |
|---|
| 174 | 330 | |
|---|
| 175 | | -static const struct block_device_operations md_fops; |
|---|
| 176 | | - |
|---|
| 177 | 331 | static int start_readonly; |
|---|
| 178 | 332 | |
|---|
| 179 | 333 | /* |
|---|
| .. | .. |
|---|
| 189 | 343 | struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, |
|---|
| 190 | 344 | struct mddev *mddev) |
|---|
| 191 | 345 | { |
|---|
| 192 | | - struct bio *b; |
|---|
| 193 | | - |
|---|
| 194 | 346 | if (!mddev || !bioset_initialized(&mddev->bio_set)) |
|---|
| 195 | 347 | return bio_alloc(gfp_mask, nr_iovecs); |
|---|
| 196 | 348 | |
|---|
| 197 | | - b = bio_alloc_bioset(gfp_mask, nr_iovecs, &mddev->bio_set); |
|---|
| 198 | | - if (!b) |
|---|
| 199 | | - return NULL; |
|---|
| 200 | | - return b; |
|---|
| 349 | + return bio_alloc_bioset(gfp_mask, nr_iovecs, &mddev->bio_set); |
|---|
| 201 | 350 | } |
|---|
| 202 | 351 | EXPORT_SYMBOL_GPL(bio_alloc_mddev); |
|---|
| 203 | 352 | |
|---|
| .. | .. |
|---|
| 310 | 459 | } |
|---|
| 311 | 460 | EXPORT_SYMBOL(md_handle_request); |
|---|
| 312 | 461 | |
|---|
| 313 | | -static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) |
|---|
| 462 | +static blk_qc_t md_submit_bio(struct bio *bio) |
|---|
| 314 | 463 | { |
|---|
| 315 | 464 | const int rw = bio_data_dir(bio); |
|---|
| 316 | 465 | const int sgrp = op_stat_group(bio_op(bio)); |
|---|
| 317 | | - struct mddev *mddev = q->queuedata; |
|---|
| 466 | + struct mddev *mddev = bio->bi_disk->private_data; |
|---|
| 318 | 467 | unsigned int sectors; |
|---|
| 319 | | - int cpu; |
|---|
| 320 | | - |
|---|
| 321 | | - blk_queue_split(q, &bio); |
|---|
| 322 | 468 | |
|---|
| 323 | 469 | if (mddev == NULL || mddev->pers == NULL) { |
|---|
| 324 | 470 | bio_io_error(bio); |
|---|
| 325 | 471 | return BLK_QC_T_NONE; |
|---|
| 326 | 472 | } |
|---|
| 473 | + |
|---|
| 474 | + if (unlikely(test_bit(MD_BROKEN, &mddev->flags)) && (rw == WRITE)) { |
|---|
| 475 | + bio_io_error(bio); |
|---|
| 476 | + return BLK_QC_T_NONE; |
|---|
| 477 | + } |
|---|
| 478 | + |
|---|
| 479 | + blk_queue_split(&bio); |
|---|
| 480 | + |
|---|
| 327 | 481 | if (mddev->ro == 1 && unlikely(rw == WRITE)) { |
|---|
| 328 | 482 | if (bio_sectors(bio) != 0) |
|---|
| 329 | 483 | bio->bi_status = BLK_STS_IOERR; |
|---|
| .. | .. |
|---|
| 341 | 495 | |
|---|
| 342 | 496 | md_handle_request(mddev, bio); |
|---|
| 343 | 497 | |
|---|
| 344 | | - cpu = part_stat_lock(); |
|---|
| 345 | | - part_stat_inc(cpu, &mddev->gendisk->part0, ios[sgrp]); |
|---|
| 346 | | - part_stat_add(cpu, &mddev->gendisk->part0, sectors[sgrp], sectors); |
|---|
| 498 | + part_stat_lock(); |
|---|
| 499 | + part_stat_inc(&mddev->gendisk->part0, ios[sgrp]); |
|---|
| 500 | + part_stat_add(&mddev->gendisk->part0, sectors[sgrp], sectors); |
|---|
| 347 | 501 | part_stat_unlock(); |
|---|
| 348 | 502 | |
|---|
| 349 | 503 | return BLK_QC_T_NONE; |
|---|
| .. | .. |
|---|
| 371 | 525 | wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); |
|---|
| 372 | 526 | |
|---|
| 373 | 527 | del_timer_sync(&mddev->safemode_timer); |
|---|
| 528 | + /* restrict memory reclaim I/O during raid array is suspend */ |
|---|
| 529 | + mddev->noio_flag = memalloc_noio_save(); |
|---|
| 374 | 530 | } |
|---|
| 375 | 531 | EXPORT_SYMBOL_GPL(mddev_suspend); |
|---|
| 376 | 532 | |
|---|
| 377 | 533 | void mddev_resume(struct mddev *mddev) |
|---|
| 378 | 534 | { |
|---|
| 535 | + /* entred the memalloc scope from mddev_suspend() */ |
|---|
| 536 | + memalloc_noio_restore(mddev->noio_flag); |
|---|
| 379 | 537 | lockdep_assert_held(&mddev->reconfig_mutex); |
|---|
| 380 | 538 | if (--mddev->suspended) |
|---|
| 381 | 539 | return; |
|---|
| .. | .. |
|---|
| 388 | 546 | } |
|---|
| 389 | 547 | EXPORT_SYMBOL_GPL(mddev_resume); |
|---|
| 390 | 548 | |
|---|
| 391 | | -int mddev_congested(struct mddev *mddev, int bits) |
|---|
| 392 | | -{ |
|---|
| 393 | | - struct md_personality *pers = mddev->pers; |
|---|
| 394 | | - int ret = 0; |
|---|
| 395 | | - |
|---|
| 396 | | - rcu_read_lock(); |
|---|
| 397 | | - if (mddev->suspended) |
|---|
| 398 | | - ret = 1; |
|---|
| 399 | | - else if (pers && pers->congested) |
|---|
| 400 | | - ret = pers->congested(mddev, bits); |
|---|
| 401 | | - rcu_read_unlock(); |
|---|
| 402 | | - return ret; |
|---|
| 403 | | -} |
|---|
| 404 | | -EXPORT_SYMBOL_GPL(mddev_congested); |
|---|
| 405 | | -static int md_congested(void *data, int bits) |
|---|
| 406 | | -{ |
|---|
| 407 | | - struct mddev *mddev = data; |
|---|
| 408 | | - return mddev_congested(mddev, bits); |
|---|
| 409 | | -} |
|---|
| 410 | | - |
|---|
| 411 | 549 | /* |
|---|
| 412 | 550 | * Generic flush handling for md |
|---|
| 413 | 551 | */ |
|---|
| .. | .. |
|---|
| 417 | 555 | struct md_rdev *rdev = bio->bi_private; |
|---|
| 418 | 556 | struct mddev *mddev = rdev->mddev; |
|---|
| 419 | 557 | |
|---|
| 558 | + bio_put(bio); |
|---|
| 559 | + |
|---|
| 420 | 560 | rdev_dec_pending(rdev, mddev); |
|---|
| 421 | 561 | |
|---|
| 422 | 562 | if (atomic_dec_and_test(&mddev->flush_pending)) { |
|---|
| 423 | 563 | /* The pre-request flush has finished */ |
|---|
| 424 | 564 | queue_work(md_wq, &mddev->flush_work); |
|---|
| 425 | 565 | } |
|---|
| 426 | | - bio_put(bio); |
|---|
| 427 | 566 | } |
|---|
| 428 | 567 | |
|---|
| 429 | 568 | static void md_submit_flush_data(struct work_struct *ws); |
|---|
| .. | .. |
|---|
| 709 | 848 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); |
|---|
| 710 | 849 | if (mddev->sysfs_action) |
|---|
| 711 | 850 | sysfs_put(mddev->sysfs_action); |
|---|
| 851 | + if (mddev->sysfs_completed) |
|---|
| 852 | + sysfs_put(mddev->sysfs_completed); |
|---|
| 853 | + if (mddev->sysfs_degraded) |
|---|
| 854 | + sysfs_put(mddev->sysfs_degraded); |
|---|
| 712 | 855 | mddev->sysfs_action = NULL; |
|---|
| 856 | + mddev->sysfs_completed = NULL; |
|---|
| 857 | + mddev->sysfs_degraded = NULL; |
|---|
| 713 | 858 | } |
|---|
| 714 | 859 | } |
|---|
| 715 | 860 | mddev->sysfs_active = 0; |
|---|
| .. | .. |
|---|
| 811 | 956 | struct mddev *mddev = rdev->mddev; |
|---|
| 812 | 957 | |
|---|
| 813 | 958 | if (bio->bi_status) { |
|---|
| 814 | | - pr_err("md: super_written gets error=%d\n", bio->bi_status); |
|---|
| 959 | + pr_err("md: %s gets error=%d\n", __func__, |
|---|
| 960 | + blk_status_to_errno(bio->bi_status)); |
|---|
| 815 | 961 | md_error(mddev, rdev); |
|---|
| 816 | 962 | if (!test_bit(Faulty, &rdev->flags) |
|---|
| 817 | 963 | && (bio->bi_opf & MD_FAILFAST)) { |
|---|
| .. | .. |
|---|
| 821 | 967 | } else |
|---|
| 822 | 968 | clear_bit(LastDev, &rdev->flags); |
|---|
| 823 | 969 | |
|---|
| 970 | + bio_put(bio); |
|---|
| 971 | + |
|---|
| 972 | + rdev_dec_pending(rdev, mddev); |
|---|
| 973 | + |
|---|
| 824 | 974 | if (atomic_dec_and_test(&mddev->pending_writes)) |
|---|
| 825 | 975 | wake_up(&mddev->sb_wait); |
|---|
| 826 | | - rdev_dec_pending(rdev, mddev); |
|---|
| 827 | | - bio_put(bio); |
|---|
| 828 | 976 | } |
|---|
| 829 | 977 | |
|---|
| 830 | 978 | void md_super_write(struct mddev *mddev, struct md_rdev *rdev, |
|---|
| .. | .. |
|---|
| 1066 | 1214 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
|---|
| 1067 | 1215 | mdp_super_t *sb; |
|---|
| 1068 | 1216 | int ret; |
|---|
| 1217 | + bool spare_disk = true; |
|---|
| 1069 | 1218 | |
|---|
| 1070 | 1219 | /* |
|---|
| 1071 | 1220 | * Calculate the position of the superblock (512byte sectors), |
|---|
| .. | .. |
|---|
| 1116 | 1265 | else |
|---|
| 1117 | 1266 | rdev->desc_nr = sb->this_disk.number; |
|---|
| 1118 | 1267 | |
|---|
| 1268 | + /* not spare disk, or LEVEL_MULTIPATH */ |
|---|
| 1269 | + if (sb->level == LEVEL_MULTIPATH || |
|---|
| 1270 | + (rdev->desc_nr >= 0 && |
|---|
| 1271 | + rdev->desc_nr < MD_SB_DISKS && |
|---|
| 1272 | + sb->disks[rdev->desc_nr].state & |
|---|
| 1273 | + ((1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)))) |
|---|
| 1274 | + spare_disk = false; |
|---|
| 1275 | + |
|---|
| 1119 | 1276 | if (!refdev) { |
|---|
| 1120 | | - ret = 1; |
|---|
| 1277 | + if (!spare_disk) |
|---|
| 1278 | + ret = 1; |
|---|
| 1279 | + else |
|---|
| 1280 | + ret = 0; |
|---|
| 1121 | 1281 | } else { |
|---|
| 1122 | 1282 | __u64 ev1, ev2; |
|---|
| 1123 | 1283 | mdp_super_t *refsb = page_address(refdev->sb_page); |
|---|
| .. | .. |
|---|
| 1133 | 1293 | } |
|---|
| 1134 | 1294 | ev1 = md_event(sb); |
|---|
| 1135 | 1295 | ev2 = md_event(refsb); |
|---|
| 1136 | | - if (ev1 > ev2) |
|---|
| 1296 | + |
|---|
| 1297 | + if (!spare_disk && ev1 > ev2) |
|---|
| 1137 | 1298 | ret = 1; |
|---|
| 1138 | 1299 | else |
|---|
| 1139 | 1300 | ret = 0; |
|---|
| .. | .. |
|---|
| 1143 | 1304 | * (not needed for Linear and RAID0 as metadata doesn't |
|---|
| 1144 | 1305 | * record this size) |
|---|
| 1145 | 1306 | */ |
|---|
| 1146 | | - if (IS_ENABLED(CONFIG_LBDAF) && (u64)rdev->sectors >= (2ULL << 32) && |
|---|
| 1147 | | - sb->level >= 1) |
|---|
| 1307 | + if ((u64)rdev->sectors >= (2ULL << 32) && sb->level >= 1) |
|---|
| 1148 | 1308 | rdev->sectors = (sector_t)(2ULL << 32) - 2; |
|---|
| 1149 | 1309 | |
|---|
| 1150 | 1310 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
|---|
| .. | .. |
|---|
| 1444 | 1604 | /* Limit to 4TB as metadata cannot record more than that. |
|---|
| 1445 | 1605 | * 4TB == 2^32 KB, or 2*2^32 sectors. |
|---|
| 1446 | 1606 | */ |
|---|
| 1447 | | - if (IS_ENABLED(CONFIG_LBDAF) && (u64)num_sectors >= (2ULL << 32) && |
|---|
| 1448 | | - rdev->mddev->level >= 1) |
|---|
| 1607 | + if ((u64)num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) |
|---|
| 1449 | 1608 | num_sectors = (sector_t)(2ULL << 32) - 2; |
|---|
| 1450 | 1609 | do { |
|---|
| 1451 | 1610 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
|---|
| .. | .. |
|---|
| 1495 | 1654 | sector_t sectors; |
|---|
| 1496 | 1655 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
|---|
| 1497 | 1656 | int bmask; |
|---|
| 1657 | + bool spare_disk = true; |
|---|
| 1498 | 1658 | |
|---|
| 1499 | 1659 | /* |
|---|
| 1500 | 1660 | * Calculate the position of the superblock in 512byte sectors. |
|---|
| .. | .. |
|---|
| 1589 | 1749 | */ |
|---|
| 1590 | 1750 | s32 offset; |
|---|
| 1591 | 1751 | sector_t bb_sector; |
|---|
| 1592 | | - u64 *bbp; |
|---|
| 1752 | + __le64 *bbp; |
|---|
| 1593 | 1753 | int i; |
|---|
| 1594 | 1754 | int sectors = le16_to_cpu(sb->bblog_size); |
|---|
| 1595 | 1755 | if (sectors > (PAGE_SIZE / 512)) |
|---|
| .. | .. |
|---|
| 1601 | 1761 | if (!sync_page_io(rdev, bb_sector, sectors << 9, |
|---|
| 1602 | 1762 | rdev->bb_page, REQ_OP_READ, 0, true)) |
|---|
| 1603 | 1763 | return -EIO; |
|---|
| 1604 | | - bbp = (u64 *)page_address(rdev->bb_page); |
|---|
| 1764 | + bbp = (__le64 *)page_address(rdev->bb_page); |
|---|
| 1605 | 1765 | rdev->badblocks.shift = sb->bblog_shift; |
|---|
| 1606 | 1766 | for (i = 0 ; i < (sectors << (9-3)) ; i++, bbp++) { |
|---|
| 1607 | 1767 | u64 bb = le64_to_cpu(*bbp); |
|---|
| .. | .. |
|---|
| 1628 | 1788 | sb->level != 0) |
|---|
| 1629 | 1789 | return -EINVAL; |
|---|
| 1630 | 1790 | |
|---|
| 1791 | + /* not spare disk, or LEVEL_MULTIPATH */ |
|---|
| 1792 | + if (sb->level == cpu_to_le32(LEVEL_MULTIPATH) || |
|---|
| 1793 | + (rdev->desc_nr >= 0 && |
|---|
| 1794 | + rdev->desc_nr < le32_to_cpu(sb->max_dev) && |
|---|
| 1795 | + (le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX || |
|---|
| 1796 | + le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL))) |
|---|
| 1797 | + spare_disk = false; |
|---|
| 1798 | + |
|---|
| 1631 | 1799 | if (!refdev) { |
|---|
| 1632 | | - ret = 1; |
|---|
| 1800 | + if (!spare_disk) |
|---|
| 1801 | + ret = 1; |
|---|
| 1802 | + else |
|---|
| 1803 | + ret = 0; |
|---|
| 1633 | 1804 | } else { |
|---|
| 1634 | 1805 | __u64 ev1, ev2; |
|---|
| 1635 | 1806 | struct mdp_superblock_1 *refsb = page_address(refdev->sb_page); |
|---|
| .. | .. |
|---|
| 1646 | 1817 | ev1 = le64_to_cpu(sb->events); |
|---|
| 1647 | 1818 | ev2 = le64_to_cpu(refsb->events); |
|---|
| 1648 | 1819 | |
|---|
| 1649 | | - if (ev1 > ev2) |
|---|
| 1820 | + if (!spare_disk && ev1 > ev2) |
|---|
| 1650 | 1821 | ret = 1; |
|---|
| 1651 | 1822 | else |
|---|
| 1652 | 1823 | ret = 0; |
|---|
| .. | .. |
|---|
| 1928 | 2099 | md_error(mddev, rdev); |
|---|
| 1929 | 2100 | else { |
|---|
| 1930 | 2101 | struct badblocks *bb = &rdev->badblocks; |
|---|
| 1931 | | - u64 *bbp = (u64 *)page_address(rdev->bb_page); |
|---|
| 2102 | + __le64 *bbp = (__le64 *)page_address(rdev->bb_page); |
|---|
| 1932 | 2103 | u64 *p = bb->page; |
|---|
| 1933 | 2104 | sb->feature_map |= cpu_to_le32(MD_FEATURE_BAD_BLOCKS); |
|---|
| 1934 | 2105 | if (bb->changed) { |
|---|
| .. | .. |
|---|
| 2003 | 2174 | sb->sb_csum = calc_sb_1_csum(sb); |
|---|
| 2004 | 2175 | } |
|---|
| 2005 | 2176 | |
|---|
| 2177 | +static sector_t super_1_choose_bm_space(sector_t dev_size) |
|---|
| 2178 | +{ |
|---|
| 2179 | + sector_t bm_space; |
|---|
| 2180 | + |
|---|
| 2181 | + /* if the device is bigger than 8Gig, save 64k for bitmap |
|---|
| 2182 | + * usage, if bigger than 200Gig, save 128k |
|---|
| 2183 | + */ |
|---|
| 2184 | + if (dev_size < 64*2) |
|---|
| 2185 | + bm_space = 0; |
|---|
| 2186 | + else if (dev_size - 64*2 >= 200*1024*1024*2) |
|---|
| 2187 | + bm_space = 128*2; |
|---|
| 2188 | + else if (dev_size - 4*2 > 8*1024*1024*2) |
|---|
| 2189 | + bm_space = 64*2; |
|---|
| 2190 | + else |
|---|
| 2191 | + bm_space = 4*2; |
|---|
| 2192 | + return bm_space; |
|---|
| 2193 | +} |
|---|
| 2194 | + |
|---|
| 2006 | 2195 | static unsigned long long |
|---|
| 2007 | 2196 | super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) |
|---|
| 2008 | 2197 | { |
|---|
| .. | .. |
|---|
| 2023 | 2212 | return 0; |
|---|
| 2024 | 2213 | } else { |
|---|
| 2025 | 2214 | /* minor version 0; superblock after data */ |
|---|
| 2026 | | - sector_t sb_start; |
|---|
| 2027 | | - sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2; |
|---|
| 2215 | + sector_t sb_start, bm_space; |
|---|
| 2216 | + sector_t dev_size = i_size_read(rdev->bdev->bd_inode) >> 9; |
|---|
| 2217 | + |
|---|
| 2218 | + /* 8K is for superblock */ |
|---|
| 2219 | + sb_start = dev_size - 8*2; |
|---|
| 2028 | 2220 | sb_start &= ~(sector_t)(4*2 - 1); |
|---|
| 2029 | | - max_sectors = rdev->sectors + sb_start - rdev->sb_start; |
|---|
| 2221 | + |
|---|
| 2222 | + bm_space = super_1_choose_bm_space(dev_size); |
|---|
| 2223 | + |
|---|
| 2224 | + /* Space that can be used to store date needs to decrease |
|---|
| 2225 | + * superblock bitmap space and bad block space(4K) |
|---|
| 2226 | + */ |
|---|
| 2227 | + max_sectors = sb_start - bm_space - 4*2; |
|---|
| 2228 | + |
|---|
| 2030 | 2229 | if (!num_sectors || num_sectors > max_sectors) |
|---|
| 2031 | 2230 | num_sectors = max_sectors; |
|---|
| 2032 | 2231 | rdev->sb_start = sb_start; |
|---|
| .. | .. |
|---|
| 2124 | 2323 | test_bit(Journal, &rdev2->flags) || |
|---|
| 2125 | 2324 | rdev2->raid_disk == -1) |
|---|
| 2126 | 2325 | continue; |
|---|
| 2127 | | - if (rdev->bdev->bd_contains == |
|---|
| 2128 | | - rdev2->bdev->bd_contains) { |
|---|
| 2326 | + if (rdev->bdev->bd_disk == rdev2->bdev->bd_disk) { |
|---|
| 2129 | 2327 | rcu_read_unlock(); |
|---|
| 2130 | 2328 | return 1; |
|---|
| 2131 | 2329 | } |
|---|
| .. | .. |
|---|
| 2193 | 2391 | */ |
|---|
| 2194 | 2392 | int md_integrity_add_rdev(struct md_rdev *rdev, struct mddev *mddev) |
|---|
| 2195 | 2393 | { |
|---|
| 2196 | | - struct blk_integrity *bi_rdev; |
|---|
| 2197 | 2394 | struct blk_integrity *bi_mddev; |
|---|
| 2198 | 2395 | char name[BDEVNAME_SIZE]; |
|---|
| 2199 | 2396 | |
|---|
| 2200 | 2397 | if (!mddev->gendisk) |
|---|
| 2201 | 2398 | return 0; |
|---|
| 2202 | 2399 | |
|---|
| 2203 | | - bi_rdev = bdev_get_integrity(rdev->bdev); |
|---|
| 2204 | 2400 | bi_mddev = blk_get_integrity(mddev->gendisk); |
|---|
| 2205 | 2401 | |
|---|
| 2206 | 2402 | if (!bi_mddev) /* nothing to do */ |
|---|
| .. | .. |
|---|
| 2276 | 2472 | rdev->mddev = mddev; |
|---|
| 2277 | 2473 | pr_debug("md: bind<%s>\n", b); |
|---|
| 2278 | 2474 | |
|---|
| 2475 | + if (mddev->raid_disks) |
|---|
| 2476 | + mddev_create_serial_pool(mddev, rdev, false); |
|---|
| 2477 | + |
|---|
| 2279 | 2478 | if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b))) |
|---|
| 2280 | 2479 | goto fail; |
|---|
| 2281 | 2480 | |
|---|
| 2282 | 2481 | ko = &part_to_dev(rdev->bdev->bd_part)->kobj; |
|---|
| 2283 | | - if (sysfs_create_link(&rdev->kobj, ko, "block")) |
|---|
| 2284 | | - /* failure here is OK */; |
|---|
| 2482 | + /* failure here is OK */ |
|---|
| 2483 | + err = sysfs_create_link(&rdev->kobj, ko, "block"); |
|---|
| 2285 | 2484 | rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state"); |
|---|
| 2485 | + rdev->sysfs_unack_badblocks = |
|---|
| 2486 | + sysfs_get_dirent_safe(rdev->kobj.sd, "unacknowledged_bad_blocks"); |
|---|
| 2487 | + rdev->sysfs_badblocks = |
|---|
| 2488 | + sysfs_get_dirent_safe(rdev->kobj.sd, "bad_blocks"); |
|---|
| 2286 | 2489 | |
|---|
| 2287 | 2490 | list_add_rcu(&rdev->same_set, &mddev->disks); |
|---|
| 2288 | 2491 | bd_link_disk_holder(rdev->bdev, mddev->gendisk); |
|---|
| .. | .. |
|---|
| 2298 | 2501 | return err; |
|---|
| 2299 | 2502 | } |
|---|
| 2300 | 2503 | |
|---|
| 2301 | | -static void md_delayed_delete(struct work_struct *ws) |
|---|
| 2504 | +static void rdev_delayed_delete(struct work_struct *ws) |
|---|
| 2302 | 2505 | { |
|---|
| 2303 | 2506 | struct md_rdev *rdev = container_of(ws, struct md_rdev, del_work); |
|---|
| 2304 | 2507 | kobject_del(&rdev->kobj); |
|---|
| .. | .. |
|---|
| 2312 | 2515 | bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk); |
|---|
| 2313 | 2516 | list_del_rcu(&rdev->same_set); |
|---|
| 2314 | 2517 | pr_debug("md: unbind<%s>\n", bdevname(rdev->bdev,b)); |
|---|
| 2518 | + mddev_destroy_serial_pool(rdev->mddev, rdev, false); |
|---|
| 2315 | 2519 | rdev->mddev = NULL; |
|---|
| 2316 | 2520 | sysfs_remove_link(&rdev->kobj, "block"); |
|---|
| 2317 | 2521 | sysfs_put(rdev->sysfs_state); |
|---|
| 2522 | + sysfs_put(rdev->sysfs_unack_badblocks); |
|---|
| 2523 | + sysfs_put(rdev->sysfs_badblocks); |
|---|
| 2318 | 2524 | rdev->sysfs_state = NULL; |
|---|
| 2525 | + rdev->sysfs_unack_badblocks = NULL; |
|---|
| 2526 | + rdev->sysfs_badblocks = NULL; |
|---|
| 2319 | 2527 | rdev->badblocks.count = 0; |
|---|
| 2320 | 2528 | /* We need to delay this, otherwise we can deadlock when |
|---|
| 2321 | 2529 | * writing to 'remove' to "dev/state". We also need |
|---|
| 2322 | 2530 | * to delay it due to rcu usage. |
|---|
| 2323 | 2531 | */ |
|---|
| 2324 | 2532 | synchronize_rcu(); |
|---|
| 2325 | | - INIT_WORK(&rdev->del_work, md_delayed_delete); |
|---|
| 2533 | + INIT_WORK(&rdev->del_work, rdev_delayed_delete); |
|---|
| 2326 | 2534 | kobject_get(&rdev->kobj); |
|---|
| 2327 | | - queue_work(md_misc_wq, &rdev->del_work); |
|---|
| 2535 | + queue_work(md_rdev_misc_wq, &rdev->del_work); |
|---|
| 2328 | 2536 | } |
|---|
| 2329 | 2537 | |
|---|
| 2330 | 2538 | /* |
|---|
| .. | .. |
|---|
| 2336 | 2544 | { |
|---|
| 2337 | 2545 | int err = 0; |
|---|
| 2338 | 2546 | struct block_device *bdev; |
|---|
| 2339 | | - char b[BDEVNAME_SIZE]; |
|---|
| 2340 | 2547 | |
|---|
| 2341 | 2548 | bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
|---|
| 2342 | 2549 | shared ? (struct md_rdev *)lock_rdev : rdev); |
|---|
| 2343 | 2550 | if (IS_ERR(bdev)) { |
|---|
| 2344 | | - pr_warn("md: could not open %s.\n", __bdevname(dev, b)); |
|---|
| 2551 | + pr_warn("md: could not open device unknown-block(%u,%u).\n", |
|---|
| 2552 | + MAJOR(dev), MINOR(dev)); |
|---|
| 2345 | 2553 | return PTR_ERR(bdev); |
|---|
| 2346 | 2554 | } |
|---|
| 2347 | 2555 | rdev->bdev = bdev; |
|---|
| .. | .. |
|---|
| 2443 | 2651 | |
|---|
| 2444 | 2652 | static bool does_sb_need_changing(struct mddev *mddev) |
|---|
| 2445 | 2653 | { |
|---|
| 2446 | | - struct md_rdev *rdev; |
|---|
| 2654 | + struct md_rdev *rdev = NULL, *iter; |
|---|
| 2447 | 2655 | struct mdp_superblock_1 *sb; |
|---|
| 2448 | 2656 | int role; |
|---|
| 2449 | 2657 | |
|---|
| 2450 | 2658 | /* Find a good rdev */ |
|---|
| 2451 | | - rdev_for_each(rdev, mddev) |
|---|
| 2452 | | - if ((rdev->raid_disk >= 0) && !test_bit(Faulty, &rdev->flags)) |
|---|
| 2659 | + rdev_for_each(iter, mddev) |
|---|
| 2660 | + if ((iter->raid_disk >= 0) && !test_bit(Faulty, &iter->flags)) { |
|---|
| 2661 | + rdev = iter; |
|---|
| 2453 | 2662 | break; |
|---|
| 2663 | + } |
|---|
| 2454 | 2664 | |
|---|
| 2455 | 2665 | /* No good device found. */ |
|---|
| 2456 | 2666 | if (!rdev) |
|---|
| .. | .. |
|---|
| 2660 | 2870 | goto repeat; |
|---|
| 2661 | 2871 | wake_up(&mddev->sb_wait); |
|---|
| 2662 | 2872 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
|---|
| 2663 | | - sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
|---|
| 2873 | + sysfs_notify_dirent_safe(mddev->sysfs_completed); |
|---|
| 2664 | 2874 | |
|---|
| 2665 | 2875 | rdev_for_each(rdev, mddev) { |
|---|
| 2666 | 2876 | if (test_and_clear_bit(FaultRecorded, &rdev->flags)) |
|---|
| .. | .. |
|---|
| 2793 | 3003 | * -write_error - clears WriteErrorSeen |
|---|
| 2794 | 3004 | * {,-}failfast - set/clear FailFast |
|---|
| 2795 | 3005 | */ |
|---|
| 3006 | + |
|---|
| 3007 | + struct mddev *mddev = rdev->mddev; |
|---|
| 2796 | 3008 | int err = -EINVAL; |
|---|
| 3009 | + bool need_update_sb = false; |
|---|
| 3010 | + |
|---|
| 2797 | 3011 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { |
|---|
| 2798 | 3012 | md_error(rdev->mddev, rdev); |
|---|
| 2799 | 3013 | if (test_bit(Faulty, &rdev->flags)) |
|---|
| .. | .. |
|---|
| 2808 | 3022 | if (rdev->raid_disk >= 0) |
|---|
| 2809 | 3023 | err = -EBUSY; |
|---|
| 2810 | 3024 | else { |
|---|
| 2811 | | - struct mddev *mddev = rdev->mddev; |
|---|
| 2812 | 3025 | err = 0; |
|---|
| 2813 | 3026 | if (mddev_is_clustered(mddev)) |
|---|
| 2814 | 3027 | err = md_cluster_ops->remove_disk(mddev, rdev); |
|---|
| .. | .. |
|---|
| 2824 | 3037 | } |
|---|
| 2825 | 3038 | } else if (cmd_match(buf, "writemostly")) { |
|---|
| 2826 | 3039 | set_bit(WriteMostly, &rdev->flags); |
|---|
| 3040 | + mddev_create_serial_pool(rdev->mddev, rdev, false); |
|---|
| 3041 | + need_update_sb = true; |
|---|
| 2827 | 3042 | err = 0; |
|---|
| 2828 | 3043 | } else if (cmd_match(buf, "-writemostly")) { |
|---|
| 3044 | + mddev_destroy_serial_pool(rdev->mddev, rdev, false); |
|---|
| 2829 | 3045 | clear_bit(WriteMostly, &rdev->flags); |
|---|
| 3046 | + need_update_sb = true; |
|---|
| 2830 | 3047 | err = 0; |
|---|
| 2831 | 3048 | } else if (cmd_match(buf, "blocked")) { |
|---|
| 2832 | 3049 | set_bit(Blocked, &rdev->flags); |
|---|
| .. | .. |
|---|
| 2852 | 3069 | err = 0; |
|---|
| 2853 | 3070 | } else if (cmd_match(buf, "failfast")) { |
|---|
| 2854 | 3071 | set_bit(FailFast, &rdev->flags); |
|---|
| 3072 | + need_update_sb = true; |
|---|
| 2855 | 3073 | err = 0; |
|---|
| 2856 | 3074 | } else if (cmd_match(buf, "-failfast")) { |
|---|
| 2857 | 3075 | clear_bit(FailFast, &rdev->flags); |
|---|
| 3076 | + need_update_sb = true; |
|---|
| 2858 | 3077 | err = 0; |
|---|
| 2859 | 3078 | } else if (cmd_match(buf, "-insync") && rdev->raid_disk >= 0 && |
|---|
| 2860 | 3079 | !test_bit(Journal, &rdev->flags)) { |
|---|
| .. | .. |
|---|
| 2933 | 3152 | clear_bit(ExternalBbl, &rdev->flags); |
|---|
| 2934 | 3153 | err = 0; |
|---|
| 2935 | 3154 | } |
|---|
| 3155 | + if (need_update_sb) |
|---|
| 3156 | + md_update_sb(mddev, 1); |
|---|
| 2936 | 3157 | if (!err) |
|---|
| 2937 | 3158 | sysfs_notify_dirent_safe(rdev->sysfs_state); |
|---|
| 2938 | 3159 | return err ? err : len; |
|---|
| .. | .. |
|---|
| 2986 | 3207 | err = kstrtouint(buf, 10, (unsigned int *)&slot); |
|---|
| 2987 | 3208 | if (err < 0) |
|---|
| 2988 | 3209 | return err; |
|---|
| 3210 | + if (slot < 0) |
|---|
| 3211 | + /* overflow */ |
|---|
| 3212 | + return -ENOSPC; |
|---|
| 2989 | 3213 | } |
|---|
| 2990 | 3214 | if (rdev->mddev->pers && slot == -1) { |
|---|
| 2991 | 3215 | /* Setting 'slot' on an active array requires also |
|---|
| .. | .. |
|---|
| 3032 | 3256 | rdev->saved_raid_disk = -1; |
|---|
| 3033 | 3257 | clear_bit(In_sync, &rdev->flags); |
|---|
| 3034 | 3258 | clear_bit(Bitmap_sync, &rdev->flags); |
|---|
| 3035 | | - err = rdev->mddev->pers-> |
|---|
| 3036 | | - hot_add_disk(rdev->mddev, rdev); |
|---|
| 3259 | + err = rdev->mddev->pers->hot_add_disk(rdev->mddev, rdev); |
|---|
| 3037 | 3260 | if (err) { |
|---|
| 3038 | 3261 | rdev->raid_disk = -1; |
|---|
| 3039 | 3262 | return err; |
|---|
| 3040 | 3263 | } else |
|---|
| 3041 | 3264 | sysfs_notify_dirent_safe(rdev->sysfs_state); |
|---|
| 3042 | | - if (sysfs_link_rdev(rdev->mddev, rdev)) |
|---|
| 3043 | | - /* failure here is OK */; |
|---|
| 3265 | + /* failure here is OK */; |
|---|
| 3266 | + sysfs_link_rdev(rdev->mddev, rdev); |
|---|
| 3044 | 3267 | /* don't wakeup anyone, leave that to userspace. */ |
|---|
| 3045 | 3268 | } else { |
|---|
| 3046 | 3269 | if (slot >= rdev->mddev->raid_disks && |
|---|
| .. | .. |
|---|
| 3422 | 3645 | if (!entry->show) |
|---|
| 3423 | 3646 | return -EIO; |
|---|
| 3424 | 3647 | if (!rdev->mddev) |
|---|
| 3425 | | - return -EBUSY; |
|---|
| 3648 | + return -ENODEV; |
|---|
| 3426 | 3649 | return entry->show(rdev, page); |
|---|
| 3427 | 3650 | } |
|---|
| 3428 | 3651 | |
|---|
| .. | .. |
|---|
| 3439 | 3662 | return -EIO; |
|---|
| 3440 | 3663 | if (!capable(CAP_SYS_ADMIN)) |
|---|
| 3441 | 3664 | return -EACCES; |
|---|
| 3442 | | - rv = mddev ? mddev_lock(mddev): -EBUSY; |
|---|
| 3665 | + rv = mddev ? mddev_lock(mddev) : -ENODEV; |
|---|
| 3443 | 3666 | if (!rv) { |
|---|
| 3444 | 3667 | if (rdev->mddev == NULL) |
|---|
| 3445 | | - rv = -EBUSY; |
|---|
| 3668 | + rv = -ENODEV; |
|---|
| 3446 | 3669 | else |
|---|
| 3447 | 3670 | rv = entry->store(rdev, page, length); |
|---|
| 3448 | 3671 | mddev_unlock(mddev); |
|---|
| .. | .. |
|---|
| 3563 | 3786 | * Check a full RAID array for plausibility |
|---|
| 3564 | 3787 | */ |
|---|
| 3565 | 3788 | |
|---|
| 3566 | | -static void analyze_sbs(struct mddev *mddev) |
|---|
| 3789 | +static int analyze_sbs(struct mddev *mddev) |
|---|
| 3567 | 3790 | { |
|---|
| 3568 | 3791 | int i; |
|---|
| 3569 | 3792 | struct md_rdev *rdev, *freshest, *tmp; |
|---|
| .. | .. |
|---|
| 3583 | 3806 | bdevname(rdev->bdev,b)); |
|---|
| 3584 | 3807 | md_kick_rdev_from_array(rdev); |
|---|
| 3585 | 3808 | } |
|---|
| 3809 | + |
|---|
| 3810 | + /* Cannot find a valid fresh disk */ |
|---|
| 3811 | + if (!freshest) { |
|---|
| 3812 | + pr_warn("md: cannot find a valid disk\n"); |
|---|
| 3813 | + return -EINVAL; |
|---|
| 3814 | + } |
|---|
| 3586 | 3815 | |
|---|
| 3587 | 3816 | super_types[mddev->major_version]. |
|---|
| 3588 | 3817 | validate_super(mddev, freshest); |
|---|
| .. | .. |
|---|
| 3618 | 3847 | clear_bit(In_sync, &rdev->flags); |
|---|
| 3619 | 3848 | } |
|---|
| 3620 | 3849 | } |
|---|
| 3850 | + |
|---|
| 3851 | + return 0; |
|---|
| 3621 | 3852 | } |
|---|
| 3622 | 3853 | |
|---|
| 3623 | 3854 | /* Read a fixed-point number. |
|---|
| .. | .. |
|---|
| 3652 | 3883 | return -EINVAL; |
|---|
| 3653 | 3884 | if (decimals < 0) |
|---|
| 3654 | 3885 | decimals = 0; |
|---|
| 3655 | | - while (decimals < scale) { |
|---|
| 3656 | | - result *= 10; |
|---|
| 3657 | | - decimals ++; |
|---|
| 3658 | | - } |
|---|
| 3659 | | - *res = result; |
|---|
| 3886 | + *res = result * int_pow(10, scale - decimals); |
|---|
| 3660 | 3887 | return 0; |
|---|
| 3661 | 3888 | } |
|---|
| 3662 | 3889 | |
|---|
| 3663 | 3890 | static ssize_t |
|---|
| 3664 | 3891 | safe_delay_show(struct mddev *mddev, char *page) |
|---|
| 3665 | 3892 | { |
|---|
| 3666 | | - int msec = (mddev->safemode_delay*1000)/HZ; |
|---|
| 3667 | | - return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); |
|---|
| 3893 | + unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ; |
|---|
| 3894 | + |
|---|
| 3895 | + return sprintf(page, "%u.%03u\n", msec/1000, msec%1000); |
|---|
| 3668 | 3896 | } |
|---|
| 3669 | 3897 | static ssize_t |
|---|
| 3670 | 3898 | safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) |
|---|
| .. | .. |
|---|
| 3676 | 3904 | return -EINVAL; |
|---|
| 3677 | 3905 | } |
|---|
| 3678 | 3906 | |
|---|
| 3679 | | - if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) |
|---|
| 3907 | + if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) |
|---|
| 3680 | 3908 | return -EINVAL; |
|---|
| 3681 | 3909 | if (msec == 0) |
|---|
| 3682 | 3910 | mddev->safemode_delay = 0; |
|---|
| .. | .. |
|---|
| 3861 | 4089 | pr_warn("md: cannot register extra attributes for %s\n", |
|---|
| 3862 | 4090 | mdname(mddev)); |
|---|
| 3863 | 4091 | mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); |
|---|
| 4092 | + mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); |
|---|
| 4093 | + mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded"); |
|---|
| 3864 | 4094 | } |
|---|
| 3865 | 4095 | if (oldpers->sync_request != NULL && |
|---|
| 3866 | 4096 | pers->sync_request == NULL) { |
|---|
| .. | .. |
|---|
| 3908 | 4138 | mddev_resume(mddev); |
|---|
| 3909 | 4139 | if (!mddev->thread) |
|---|
| 3910 | 4140 | md_update_sb(mddev, 1); |
|---|
| 3911 | | - sysfs_notify(&mddev->kobj, NULL, "level"); |
|---|
| 4141 | + sysfs_notify_dirent_safe(mddev->sysfs_level); |
|---|
| 3912 | 4142 | md_new_event(mddev); |
|---|
| 3913 | 4143 | rv = len; |
|---|
| 3914 | 4144 | out_unlock: |
|---|
| .. | .. |
|---|
| 4019 | 4249 | } |
|---|
| 4020 | 4250 | static struct md_sysfs_entry md_raid_disks = |
|---|
| 4021 | 4251 | __ATTR(raid_disks, S_IRUGO|S_IWUSR, raid_disks_show, raid_disks_store); |
|---|
| 4252 | + |
|---|
| 4253 | +static ssize_t |
|---|
| 4254 | +uuid_show(struct mddev *mddev, char *page) |
|---|
| 4255 | +{ |
|---|
| 4256 | + return sprintf(page, "%pU\n", mddev->uuid); |
|---|
| 4257 | +} |
|---|
| 4258 | +static struct md_sysfs_entry md_uuid = |
|---|
| 4259 | +__ATTR(uuid, S_IRUGO, uuid_show, NULL); |
|---|
| 4022 | 4260 | |
|---|
| 4023 | 4261 | static ssize_t |
|---|
| 4024 | 4262 | chunk_size_show(struct mddev *mddev, char *page) |
|---|
| .. | .. |
|---|
| 4143 | 4381 | * active-idle |
|---|
| 4144 | 4382 | * like active, but no writes have been seen for a while (100msec). |
|---|
| 4145 | 4383 | * |
|---|
| 4384 | + * broken |
|---|
| 4385 | + * RAID0/LINEAR-only: same as clean, but array is missing a member. |
|---|
| 4386 | + * It's useful because RAID0/LINEAR mounted-arrays aren't stopped |
|---|
| 4387 | + * when a member is gone, so this state will at least alert the |
|---|
| 4388 | + * user that something is wrong. |
|---|
| 4146 | 4389 | */ |
|---|
| 4147 | 4390 | enum array_state { clear, inactive, suspended, readonly, read_auto, clean, active, |
|---|
| 4148 | | - write_pending, active_idle, bad_word}; |
|---|
| 4391 | + write_pending, active_idle, broken, bad_word}; |
|---|
| 4149 | 4392 | static char *array_states[] = { |
|---|
| 4150 | 4393 | "clear", "inactive", "suspended", "readonly", "read-auto", "clean", "active", |
|---|
| 4151 | | - "write-pending", "active-idle", NULL }; |
|---|
| 4394 | + "write-pending", "active-idle", "broken", NULL }; |
|---|
| 4152 | 4395 | |
|---|
| 4153 | 4396 | static int match_word(const char *word, char **list) |
|---|
| 4154 | 4397 | { |
|---|
| .. | .. |
|---|
| 4164 | 4407 | { |
|---|
| 4165 | 4408 | enum array_state st = inactive; |
|---|
| 4166 | 4409 | |
|---|
| 4167 | | - if (mddev->pers && !test_bit(MD_NOT_READY, &mddev->flags)) |
|---|
| 4410 | + if (mddev->pers && !test_bit(MD_NOT_READY, &mddev->flags)) { |
|---|
| 4168 | 4411 | switch(mddev->ro) { |
|---|
| 4169 | 4412 | case 1: |
|---|
| 4170 | 4413 | st = readonly; |
|---|
| .. | .. |
|---|
| 4184 | 4427 | st = active; |
|---|
| 4185 | 4428 | spin_unlock(&mddev->lock); |
|---|
| 4186 | 4429 | } |
|---|
| 4187 | | - else { |
|---|
| 4430 | + |
|---|
| 4431 | + if (test_bit(MD_BROKEN, &mddev->flags) && st == clean) |
|---|
| 4432 | + st = broken; |
|---|
| 4433 | + } else { |
|---|
| 4188 | 4434 | if (list_empty(&mddev->disks) && |
|---|
| 4189 | 4435 | mddev->raid_disks == 0 && |
|---|
| 4190 | 4436 | mddev->dev_sectors == 0) |
|---|
| .. | .. |
|---|
| 4197 | 4443 | |
|---|
| 4198 | 4444 | static int do_md_stop(struct mddev *mddev, int ro, struct block_device *bdev); |
|---|
| 4199 | 4445 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev); |
|---|
| 4200 | | -static int do_md_run(struct mddev *mddev); |
|---|
| 4201 | 4446 | static int restart_array(struct mddev *mddev); |
|---|
| 4202 | 4447 | |
|---|
| 4203 | 4448 | static ssize_t |
|---|
| .. | .. |
|---|
| 4298 | 4543 | break; |
|---|
| 4299 | 4544 | case write_pending: |
|---|
| 4300 | 4545 | case active_idle: |
|---|
| 4546 | + case broken: |
|---|
| 4301 | 4547 | /* these cannot be set */ |
|---|
| 4302 | 4548 | break; |
|---|
| 4303 | 4549 | } |
|---|
| .. | .. |
|---|
| 4328 | 4574 | rv = kstrtouint(buf, 10, &n); |
|---|
| 4329 | 4575 | if (rv < 0) |
|---|
| 4330 | 4576 | return rv; |
|---|
| 4577 | + if (n > INT_MAX) |
|---|
| 4578 | + return -EINVAL; |
|---|
| 4331 | 4579 | atomic_set(&mddev->max_corr_read_errors, n); |
|---|
| 4332 | 4580 | return len; |
|---|
| 4333 | 4581 | } |
|---|
| .. | .. |
|---|
| 4340 | 4588 | null_show(struct mddev *mddev, char *page) |
|---|
| 4341 | 4589 | { |
|---|
| 4342 | 4590 | return -EINVAL; |
|---|
| 4591 | +} |
|---|
| 4592 | + |
|---|
| 4593 | +/* need to ensure rdev_delayed_delete() has completed */ |
|---|
| 4594 | +static void flush_rdev_wq(struct mddev *mddev) |
|---|
| 4595 | +{ |
|---|
| 4596 | + struct md_rdev *rdev; |
|---|
| 4597 | + |
|---|
| 4598 | + rcu_read_lock(); |
|---|
| 4599 | + rdev_for_each_rcu(rdev, mddev) |
|---|
| 4600 | + if (work_pending(&rdev->del_work)) { |
|---|
| 4601 | + flush_workqueue(md_rdev_misc_wq); |
|---|
| 4602 | + break; |
|---|
| 4603 | + } |
|---|
| 4604 | + rcu_read_unlock(); |
|---|
| 4343 | 4605 | } |
|---|
| 4344 | 4606 | |
|---|
| 4345 | 4607 | static ssize_t |
|---|
| .. | .. |
|---|
| 4369 | 4631 | minor != MINOR(dev)) |
|---|
| 4370 | 4632 | return -EOVERFLOW; |
|---|
| 4371 | 4633 | |
|---|
| 4372 | | - flush_workqueue(md_misc_wq); |
|---|
| 4373 | | - |
|---|
| 4634 | + flush_rdev_wq(mddev); |
|---|
| 4374 | 4635 | err = mddev_lock(mddev); |
|---|
| 4375 | 4636 | if (err) |
|---|
| 4376 | 4637 | return err; |
|---|
| .. | .. |
|---|
| 4608 | 4869 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
|---|
| 4609 | 4870 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
|---|
| 4610 | 4871 | mddev_lock(mddev) == 0) { |
|---|
| 4611 | | - flush_workqueue(md_misc_wq); |
|---|
| 4872 | + if (work_pending(&mddev->del_work)) |
|---|
| 4873 | + flush_workqueue(md_misc_wq); |
|---|
| 4612 | 4874 | if (mddev->sync_thread) { |
|---|
| 4613 | 4875 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
|---|
| 4614 | 4876 | md_reap_sync_thread(mddev); |
|---|
| .. | .. |
|---|
| 4628 | 4890 | return -EINVAL; |
|---|
| 4629 | 4891 | err = mddev_lock(mddev); |
|---|
| 4630 | 4892 | if (!err) { |
|---|
| 4631 | | - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
|---|
| 4893 | + if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { |
|---|
| 4632 | 4894 | err = -EBUSY; |
|---|
| 4633 | | - else { |
|---|
| 4895 | + } else if (mddev->reshape_position == MaxSector || |
|---|
| 4896 | + mddev->pers->check_reshape == NULL || |
|---|
| 4897 | + mddev->pers->check_reshape(mddev)) { |
|---|
| 4634 | 4898 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
|---|
| 4635 | 4899 | err = mddev->pers->start_reshape(mddev); |
|---|
| 4900 | + } else { |
|---|
| 4901 | + /* |
|---|
| 4902 | + * If reshape is still in progress, and |
|---|
| 4903 | + * md_check_recovery() can continue to reshape, |
|---|
| 4904 | + * don't restart reshape because data can be |
|---|
| 4905 | + * corrupted for raid456. |
|---|
| 4906 | + */ |
|---|
| 4907 | + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
|---|
| 4636 | 4908 | } |
|---|
| 4637 | 4909 | mddev_unlock(mddev); |
|---|
| 4638 | 4910 | } |
|---|
| 4639 | 4911 | if (err) |
|---|
| 4640 | 4912 | return err; |
|---|
| 4641 | | - sysfs_notify(&mddev->kobj, NULL, "degraded"); |
|---|
| 4913 | + sysfs_notify_dirent_safe(mddev->sysfs_degraded); |
|---|
| 4642 | 4914 | } else { |
|---|
| 4643 | 4915 | if (cmd_match(page, "check")) |
|---|
| 4644 | 4916 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
|---|
| .. | .. |
|---|
| 5113 | 5385 | mddev->array_sectors = sectors; |
|---|
| 5114 | 5386 | if (mddev->pers) { |
|---|
| 5115 | 5387 | set_capacity(mddev->gendisk, mddev->array_sectors); |
|---|
| 5116 | | - revalidate_disk(mddev->gendisk); |
|---|
| 5388 | + revalidate_disk_size(mddev->gendisk, true); |
|---|
| 5117 | 5389 | } |
|---|
| 5118 | 5390 | } |
|---|
| 5119 | 5391 | mddev_unlock(mddev); |
|---|
| .. | .. |
|---|
| 5170 | 5442 | __ATTR(consistency_policy, S_IRUGO | S_IWUSR, consistency_policy_show, |
|---|
| 5171 | 5443 | consistency_policy_store); |
|---|
| 5172 | 5444 | |
|---|
| 5445 | +static ssize_t fail_last_dev_show(struct mddev *mddev, char *page) |
|---|
| 5446 | +{ |
|---|
| 5447 | + return sprintf(page, "%d\n", mddev->fail_last_dev); |
|---|
| 5448 | +} |
|---|
| 5449 | + |
|---|
| 5450 | +/* |
|---|
| 5451 | + * Setting fail_last_dev to true to allow last device to be forcibly removed |
|---|
| 5452 | + * from RAID1/RAID10. |
|---|
| 5453 | + */ |
|---|
| 5454 | +static ssize_t |
|---|
| 5455 | +fail_last_dev_store(struct mddev *mddev, const char *buf, size_t len) |
|---|
| 5456 | +{ |
|---|
| 5457 | + int ret; |
|---|
| 5458 | + bool value; |
|---|
| 5459 | + |
|---|
| 5460 | + ret = kstrtobool(buf, &value); |
|---|
| 5461 | + if (ret) |
|---|
| 5462 | + return ret; |
|---|
| 5463 | + |
|---|
| 5464 | + if (value != mddev->fail_last_dev) |
|---|
| 5465 | + mddev->fail_last_dev = value; |
|---|
| 5466 | + |
|---|
| 5467 | + return len; |
|---|
| 5468 | +} |
|---|
| 5469 | +static struct md_sysfs_entry md_fail_last_dev = |
|---|
| 5470 | +__ATTR(fail_last_dev, S_IRUGO | S_IWUSR, fail_last_dev_show, |
|---|
| 5471 | + fail_last_dev_store); |
|---|
| 5472 | + |
|---|
| 5473 | +static ssize_t serialize_policy_show(struct mddev *mddev, char *page) |
|---|
| 5474 | +{ |
|---|
| 5475 | + if (mddev->pers == NULL || (mddev->pers->level != 1)) |
|---|
| 5476 | + return sprintf(page, "n/a\n"); |
|---|
| 5477 | + else |
|---|
| 5478 | + return sprintf(page, "%d\n", mddev->serialize_policy); |
|---|
| 5479 | +} |
|---|
| 5480 | + |
|---|
| 5481 | +/* |
|---|
| 5482 | + * Setting serialize_policy to true to enforce write IO is not reordered |
|---|
| 5483 | + * for raid1. |
|---|
| 5484 | + */ |
|---|
| 5485 | +static ssize_t |
|---|
| 5486 | +serialize_policy_store(struct mddev *mddev, const char *buf, size_t len) |
|---|
| 5487 | +{ |
|---|
| 5488 | + int err; |
|---|
| 5489 | + bool value; |
|---|
| 5490 | + |
|---|
| 5491 | + err = kstrtobool(buf, &value); |
|---|
| 5492 | + if (err) |
|---|
| 5493 | + return err; |
|---|
| 5494 | + |
|---|
| 5495 | + if (value == mddev->serialize_policy) |
|---|
| 5496 | + return len; |
|---|
| 5497 | + |
|---|
| 5498 | + err = mddev_lock(mddev); |
|---|
| 5499 | + if (err) |
|---|
| 5500 | + return err; |
|---|
| 5501 | + if (mddev->pers == NULL || (mddev->pers->level != 1)) { |
|---|
| 5502 | + pr_err("md: serialize_policy is only effective for raid1\n"); |
|---|
| 5503 | + err = -EINVAL; |
|---|
| 5504 | + goto unlock; |
|---|
| 5505 | + } |
|---|
| 5506 | + |
|---|
| 5507 | + mddev_suspend(mddev); |
|---|
| 5508 | + if (value) |
|---|
| 5509 | + mddev_create_serial_pool(mddev, NULL, true); |
|---|
| 5510 | + else |
|---|
| 5511 | + mddev_destroy_serial_pool(mddev, NULL, true); |
|---|
| 5512 | + mddev->serialize_policy = value; |
|---|
| 5513 | + mddev_resume(mddev); |
|---|
| 5514 | +unlock: |
|---|
| 5515 | + mddev_unlock(mddev); |
|---|
| 5516 | + return err ?: len; |
|---|
| 5517 | +} |
|---|
| 5518 | + |
|---|
| 5519 | +static struct md_sysfs_entry md_serialize_policy = |
|---|
| 5520 | +__ATTR(serialize_policy, S_IRUGO | S_IWUSR, serialize_policy_show, |
|---|
| 5521 | + serialize_policy_store); |
|---|
| 5522 | + |
|---|
| 5523 | + |
|---|
| 5173 | 5524 | static struct attribute *md_default_attrs[] = { |
|---|
| 5174 | 5525 | &md_level.attr, |
|---|
| 5175 | 5526 | &md_layout.attr, |
|---|
| 5176 | 5527 | &md_raid_disks.attr, |
|---|
| 5528 | + &md_uuid.attr, |
|---|
| 5177 | 5529 | &md_chunk_size.attr, |
|---|
| 5178 | 5530 | &md_size.attr, |
|---|
| 5179 | 5531 | &md_resync_start.attr, |
|---|
| .. | .. |
|---|
| 5186 | 5538 | &md_array_size.attr, |
|---|
| 5187 | 5539 | &max_corr_read_errors.attr, |
|---|
| 5188 | 5540 | &md_consistency_policy.attr, |
|---|
| 5541 | + &md_fail_last_dev.attr, |
|---|
| 5542 | + &md_serialize_policy.attr, |
|---|
| 5189 | 5543 | NULL, |
|---|
| 5190 | 5544 | }; |
|---|
| 5191 | 5545 | |
|---|
| .. | .. |
|---|
| 5263 | 5617 | |
|---|
| 5264 | 5618 | if (mddev->sysfs_state) |
|---|
| 5265 | 5619 | sysfs_put(mddev->sysfs_state); |
|---|
| 5620 | + if (mddev->sysfs_level) |
|---|
| 5621 | + sysfs_put(mddev->sysfs_level); |
|---|
| 5266 | 5622 | |
|---|
| 5267 | 5623 | if (mddev->gendisk) |
|---|
| 5268 | 5624 | del_gendisk(mddev->gendisk); |
|---|
| .. | .. |
|---|
| 5304 | 5660 | { |
|---|
| 5305 | 5661 | if (mddev->writes_pending.percpu_count_ptr) |
|---|
| 5306 | 5662 | return 0; |
|---|
| 5307 | | - if (percpu_ref_init(&mddev->writes_pending, no_op, 0, GFP_KERNEL) < 0) |
|---|
| 5663 | + if (percpu_ref_init(&mddev->writes_pending, no_op, |
|---|
| 5664 | + PERCPU_REF_ALLOW_REINIT, GFP_KERNEL) < 0) |
|---|
| 5308 | 5665 | return -ENOMEM; |
|---|
| 5309 | 5666 | /* We want to start with the refcount at zero */ |
|---|
| 5310 | 5667 | percpu_ref_put(&mddev->writes_pending); |
|---|
| .. | .. |
|---|
| 5342 | 5699 | * completely removed (mddev_delayed_delete). |
|---|
| 5343 | 5700 | */ |
|---|
| 5344 | 5701 | flush_workqueue(md_misc_wq); |
|---|
| 5702 | + flush_workqueue(md_rdev_misc_wq); |
|---|
| 5345 | 5703 | |
|---|
| 5346 | 5704 | mutex_lock(&disks_mutex); |
|---|
| 5347 | 5705 | error = -EEXIST; |
|---|
| .. | .. |
|---|
| 5369 | 5727 | mddev->hold_active = UNTIL_STOP; |
|---|
| 5370 | 5728 | |
|---|
| 5371 | 5729 | error = -ENOMEM; |
|---|
| 5372 | | - mddev->queue = blk_alloc_queue(GFP_KERNEL); |
|---|
| 5730 | + mddev->queue = blk_alloc_queue(NUMA_NO_NODE); |
|---|
| 5373 | 5731 | if (!mddev->queue) |
|---|
| 5374 | 5732 | goto abort; |
|---|
| 5375 | | - mddev->queue->queuedata = mddev; |
|---|
| 5376 | 5733 | |
|---|
| 5377 | | - blk_queue_make_request(mddev->queue, md_make_request); |
|---|
| 5378 | 5734 | blk_set_stacking_limits(&mddev->queue->limits); |
|---|
| 5379 | 5735 | |
|---|
| 5380 | 5736 | disk = alloc_disk(1 << shift); |
|---|
| .. | .. |
|---|
| 5400 | 5756 | * remove it now. |
|---|
| 5401 | 5757 | */ |
|---|
| 5402 | 5758 | disk->flags |= GENHD_FL_EXT_DEVT; |
|---|
| 5759 | + disk->events |= DISK_EVENT_MEDIA_CHANGE; |
|---|
| 5403 | 5760 | mddev->gendisk = disk; |
|---|
| 5404 | 5761 | add_disk(disk); |
|---|
| 5405 | 5762 | |
|---|
| .. | .. |
|---|
| 5420 | 5777 | if (!error && mddev->kobj.sd) { |
|---|
| 5421 | 5778 | kobject_uevent(&mddev->kobj, KOBJ_ADD); |
|---|
| 5422 | 5779 | mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state"); |
|---|
| 5780 | + mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level"); |
|---|
| 5423 | 5781 | } |
|---|
| 5424 | 5782 | mddev_put(mddev); |
|---|
| 5425 | 5783 | return error; |
|---|
| .. | .. |
|---|
| 5496 | 5854 | if (!mddev->raid_disks) { |
|---|
| 5497 | 5855 | if (!mddev->persistent) |
|---|
| 5498 | 5856 | return -EINVAL; |
|---|
| 5499 | | - analyze_sbs(mddev); |
|---|
| 5857 | + err = analyze_sbs(mddev); |
|---|
| 5858 | + if (err) |
|---|
| 5859 | + return -EINVAL; |
|---|
| 5500 | 5860 | } |
|---|
| 5501 | 5861 | |
|---|
| 5502 | 5862 | if (mddev->level != LEVEL_NONE) |
|---|
| .. | .. |
|---|
| 5601 | 5961 | rdev_for_each(rdev, mddev) |
|---|
| 5602 | 5962 | rdev_for_each(rdev2, mddev) { |
|---|
| 5603 | 5963 | if (rdev < rdev2 && |
|---|
| 5604 | | - rdev->bdev->bd_contains == |
|---|
| 5605 | | - rdev2->bdev->bd_contains) { |
|---|
| 5964 | + rdev->bdev->bd_disk == |
|---|
| 5965 | + rdev2->bdev->bd_disk) { |
|---|
| 5606 | 5966 | pr_warn("%s: WARNING: %s appears to be on the same physical disk as %s.\n", |
|---|
| 5607 | 5967 | mdname(mddev), |
|---|
| 5608 | 5968 | bdevname(rdev->bdev,b), |
|---|
| .. | .. |
|---|
| 5649 | 6009 | mddev->bitmap = bitmap; |
|---|
| 5650 | 6010 | |
|---|
| 5651 | 6011 | } |
|---|
| 5652 | | - if (err) { |
|---|
| 5653 | | - mddev_detach(mddev); |
|---|
| 5654 | | - if (mddev->private) |
|---|
| 5655 | | - pers->free(mddev, mddev->private); |
|---|
| 5656 | | - mddev->private = NULL; |
|---|
| 5657 | | - module_put(pers->owner); |
|---|
| 5658 | | - md_bitmap_destroy(mddev); |
|---|
| 5659 | | - goto abort; |
|---|
| 6012 | + if (err) |
|---|
| 6013 | + goto bitmap_abort; |
|---|
| 6014 | + |
|---|
| 6015 | + if (mddev->bitmap_info.max_write_behind > 0) { |
|---|
| 6016 | + bool create_pool = false; |
|---|
| 6017 | + |
|---|
| 6018 | + rdev_for_each(rdev, mddev) { |
|---|
| 6019 | + if (test_bit(WriteMostly, &rdev->flags) && |
|---|
| 6020 | + rdev_init_serial(rdev)) |
|---|
| 6021 | + create_pool = true; |
|---|
| 6022 | + } |
|---|
| 6023 | + if (create_pool && mddev->serial_info_pool == NULL) { |
|---|
| 6024 | + mddev->serial_info_pool = |
|---|
| 6025 | + mempool_create_kmalloc_pool(NR_SERIAL_INFOS, |
|---|
| 6026 | + sizeof(struct serial_info)); |
|---|
| 6027 | + if (!mddev->serial_info_pool) { |
|---|
| 6028 | + err = -ENOMEM; |
|---|
| 6029 | + goto bitmap_abort; |
|---|
| 6030 | + } |
|---|
| 6031 | + } |
|---|
| 5660 | 6032 | } |
|---|
| 6033 | + |
|---|
| 5661 | 6034 | if (mddev->queue) { |
|---|
| 5662 | 6035 | bool nonrot = true; |
|---|
| 5663 | 6036 | |
|---|
| .. | .. |
|---|
| 5674 | 6047 | blk_queue_flag_set(QUEUE_FLAG_NONROT, mddev->queue); |
|---|
| 5675 | 6048 | else |
|---|
| 5676 | 6049 | blk_queue_flag_clear(QUEUE_FLAG_NONROT, mddev->queue); |
|---|
| 5677 | | - mddev->queue->backing_dev_info->congested_data = mddev; |
|---|
| 5678 | | - mddev->queue->backing_dev_info->congested_fn = md_congested; |
|---|
| 5679 | 6050 | } |
|---|
| 5680 | 6051 | if (pers->sync_request) { |
|---|
| 5681 | 6052 | if (mddev->kobj.sd && |
|---|
| .. | .. |
|---|
| 5683 | 6054 | pr_warn("md: cannot register extra attributes for %s\n", |
|---|
| 5684 | 6055 | mdname(mddev)); |
|---|
| 5685 | 6056 | mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action"); |
|---|
| 6057 | + mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed"); |
|---|
| 6058 | + mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded"); |
|---|
| 5686 | 6059 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ |
|---|
| 5687 | 6060 | mddev->ro = 0; |
|---|
| 5688 | 6061 | |
|---|
| .. | .. |
|---|
| 5692 | 6065 | if (mddev_is_clustered(mddev)) |
|---|
| 5693 | 6066 | mddev->safemode_delay = 0; |
|---|
| 5694 | 6067 | else |
|---|
| 5695 | | - mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ |
|---|
| 6068 | + mddev->safemode_delay = DEFAULT_SAFEMODE_DELAY; |
|---|
| 5696 | 6069 | mddev->in_sync = 1; |
|---|
| 5697 | 6070 | smp_wmb(); |
|---|
| 5698 | 6071 | spin_lock(&mddev->lock); |
|---|
| .. | .. |
|---|
| 5700 | 6073 | spin_unlock(&mddev->lock); |
|---|
| 5701 | 6074 | rdev_for_each(rdev, mddev) |
|---|
| 5702 | 6075 | if (rdev->raid_disk >= 0) |
|---|
| 5703 | | - if (sysfs_link_rdev(mddev, rdev)) |
|---|
| 5704 | | - /* failure here is OK */; |
|---|
| 6076 | + sysfs_link_rdev(mddev, rdev); /* failure here is OK */ |
|---|
| 5705 | 6077 | |
|---|
| 5706 | 6078 | if (mddev->degraded && !mddev->ro) |
|---|
| 5707 | 6079 | /* This ensures that recovering status is reported immediately |
|---|
| .. | .. |
|---|
| 5716 | 6088 | md_new_event(mddev); |
|---|
| 5717 | 6089 | return 0; |
|---|
| 5718 | 6090 | |
|---|
| 6091 | +bitmap_abort: |
|---|
| 6092 | + mddev_detach(mddev); |
|---|
| 6093 | + if (mddev->private) |
|---|
| 6094 | + pers->free(mddev, mddev->private); |
|---|
| 6095 | + mddev->private = NULL; |
|---|
| 6096 | + module_put(pers->owner); |
|---|
| 6097 | + md_bitmap_destroy(mddev); |
|---|
| 5719 | 6098 | abort: |
|---|
| 5720 | 6099 | bioset_exit(&mddev->bio_set); |
|---|
| 5721 | 6100 | bioset_exit(&mddev->sync_set); |
|---|
| .. | .. |
|---|
| 5723 | 6102 | } |
|---|
| 5724 | 6103 | EXPORT_SYMBOL_GPL(md_run); |
|---|
| 5725 | 6104 | |
|---|
| 5726 | | -static int do_md_run(struct mddev *mddev) |
|---|
| 6105 | +int do_md_run(struct mddev *mddev) |
|---|
| 5727 | 6106 | { |
|---|
| 5728 | 6107 | int err; |
|---|
| 5729 | 6108 | |
|---|
| .. | .. |
|---|
| 5747 | 6126 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
|---|
| 5748 | 6127 | |
|---|
| 5749 | 6128 | set_capacity(mddev->gendisk, mddev->array_sectors); |
|---|
| 5750 | | - revalidate_disk(mddev->gendisk); |
|---|
| 6129 | + revalidate_disk_size(mddev->gendisk, true); |
|---|
| 5751 | 6130 | clear_bit(MD_NOT_READY, &mddev->flags); |
|---|
| 5752 | 6131 | mddev->changed = 1; |
|---|
| 5753 | 6132 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); |
|---|
| 5754 | 6133 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
|---|
| 5755 | 6134 | sysfs_notify_dirent_safe(mddev->sysfs_action); |
|---|
| 5756 | | - sysfs_notify(&mddev->kobj, NULL, "degraded"); |
|---|
| 6135 | + sysfs_notify_dirent_safe(mddev->sysfs_degraded); |
|---|
| 5757 | 6136 | out: |
|---|
| 5758 | 6137 | clear_bit(MD_NOT_READY, &mddev->flags); |
|---|
| 5759 | 6138 | return err; |
|---|
| .. | .. |
|---|
| 5868 | 6247 | static void __md_stop_writes(struct mddev *mddev) |
|---|
| 5869 | 6248 | { |
|---|
| 5870 | 6249 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
|---|
| 5871 | | - flush_workqueue(md_misc_wq); |
|---|
| 6250 | + if (work_pending(&mddev->del_work)) |
|---|
| 6251 | + flush_workqueue(md_misc_wq); |
|---|
| 5872 | 6252 | if (mddev->sync_thread) { |
|---|
| 5873 | 6253 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
|---|
| 5874 | 6254 | md_reap_sync_thread(mddev); |
|---|
| .. | .. |
|---|
| 5890 | 6270 | mddev->in_sync = 1; |
|---|
| 5891 | 6271 | md_update_sb(mddev, 1); |
|---|
| 5892 | 6272 | } |
|---|
| 6273 | + /* disable policy to guarantee rdevs free resources for serialization */ |
|---|
| 6274 | + mddev->serialize_policy = 0; |
|---|
| 6275 | + mddev_destroy_serial_pool(mddev, NULL, true); |
|---|
| 5893 | 6276 | } |
|---|
| 5894 | 6277 | |
|---|
| 5895 | 6278 | void md_stop_writes(struct mddev *mddev) |
|---|
| .. | .. |
|---|
| 5918 | 6301 | md_bitmap_destroy(mddev); |
|---|
| 5919 | 6302 | mddev_detach(mddev); |
|---|
| 5920 | 6303 | /* Ensure ->event_work is done */ |
|---|
| 5921 | | - flush_workqueue(md_misc_wq); |
|---|
| 6304 | + if (mddev->event_work.func) |
|---|
| 6305 | + flush_workqueue(md_misc_wq); |
|---|
| 5922 | 6306 | spin_lock(&mddev->lock); |
|---|
| 5923 | 6307 | mddev->pers = NULL; |
|---|
| 5924 | 6308 | spin_unlock(&mddev->lock); |
|---|
| .. | .. |
|---|
| 5932 | 6316 | |
|---|
| 5933 | 6317 | void md_stop(struct mddev *mddev) |
|---|
| 5934 | 6318 | { |
|---|
| 6319 | + lockdep_assert_held(&mddev->reconfig_mutex); |
|---|
| 6320 | + |
|---|
| 5935 | 6321 | /* stop the array and free an attached data structures. |
|---|
| 5936 | 6322 | * This is called from dm-raid |
|---|
| 5937 | 6323 | */ |
|---|
| 6324 | + __md_stop_writes(mddev); |
|---|
| 5938 | 6325 | __md_stop(mddev); |
|---|
| 5939 | 6326 | bioset_exit(&mddev->bio_set); |
|---|
| 5940 | 6327 | bioset_exit(&mddev->sync_set); |
|---|
| .. | .. |
|---|
| 6049 | 6436 | |
|---|
| 6050 | 6437 | __md_stop_writes(mddev); |
|---|
| 6051 | 6438 | __md_stop(mddev); |
|---|
| 6052 | | - mddev->queue->backing_dev_info->congested_fn = NULL; |
|---|
| 6053 | 6439 | |
|---|
| 6054 | 6440 | /* tell userspace to handle 'inactive' */ |
|---|
| 6055 | 6441 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
|---|
| .. | .. |
|---|
| 6061 | 6447 | set_capacity(disk, 0); |
|---|
| 6062 | 6448 | mutex_unlock(&mddev->open_mutex); |
|---|
| 6063 | 6449 | mddev->changed = 1; |
|---|
| 6064 | | - revalidate_disk(disk); |
|---|
| 6450 | + revalidate_disk_size(disk, true); |
|---|
| 6065 | 6451 | |
|---|
| 6066 | 6452 | if (mddev->ro) |
|---|
| 6067 | 6453 | mddev->ro = 0; |
|---|
| .. | .. |
|---|
| 6352 | 6738 | return 0; |
|---|
| 6353 | 6739 | } |
|---|
| 6354 | 6740 | |
|---|
| 6355 | | -static int add_new_disk(struct mddev *mddev, mdu_disk_info_t *info) |
|---|
| 6741 | +int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info) |
|---|
| 6356 | 6742 | { |
|---|
| 6357 | 6743 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
|---|
| 6358 | 6744 | struct md_rdev *rdev; |
|---|
| .. | .. |
|---|
| 6398 | 6784 | } |
|---|
| 6399 | 6785 | |
|---|
| 6400 | 6786 | /* |
|---|
| 6401 | | - * add_new_disk can be used once the array is assembled |
|---|
| 6787 | + * md_add_new_disk can be used once the array is assembled |
|---|
| 6402 | 6788 | * to add "hot spares". They must already have a superblock |
|---|
| 6403 | 6789 | * written |
|---|
| 6404 | 6790 | */ |
|---|
| .. | .. |
|---|
| 6511 | 6897 | return err; |
|---|
| 6512 | 6898 | } |
|---|
| 6513 | 6899 | |
|---|
| 6514 | | - /* otherwise, add_new_disk is only allowed |
|---|
| 6900 | + /* otherwise, md_add_new_disk is only allowed |
|---|
| 6515 | 6901 | * for major_version==0 superblocks |
|---|
| 6516 | 6902 | */ |
|---|
| 6517 | 6903 | if (mddev->major_version != 0) { |
|---|
| .. | .. |
|---|
| 6758 | 7144 | } |
|---|
| 6759 | 7145 | |
|---|
| 6760 | 7146 | /* |
|---|
| 6761 | | - * set_array_info is used two different ways |
|---|
| 7147 | + * md_set_array_info is used two different ways |
|---|
| 6762 | 7148 | * The original usage is when creating a new array. |
|---|
| 6763 | 7149 | * In this usage, raid_disks is > 0 and it together with |
|---|
| 6764 | 7150 | * level, size, not_persistent,layout,chunksize determine the |
|---|
| .. | .. |
|---|
| 6770 | 7156 | * The minor and patch _version numbers are also kept incase the |
|---|
| 6771 | 7157 | * super_block handler wishes to interpret them. |
|---|
| 6772 | 7158 | */ |
|---|
| 6773 | | -static int set_array_info(struct mddev *mddev, mdu_array_info_t *info) |
|---|
| 7159 | +int md_set_array_info(struct mddev *mddev, struct mdu_array_info_s *info) |
|---|
| 6774 | 7160 | { |
|---|
| 6775 | | - |
|---|
| 6776 | 7161 | if (info->raid_disks == 0) { |
|---|
| 6777 | 7162 | /* just setting version number for superblock loading */ |
|---|
| 6778 | 7163 | if (info->major_version < 0 || |
|---|
| .. | .. |
|---|
| 6894 | 7279 | md_cluster_ops->update_size(mddev, old_dev_sectors); |
|---|
| 6895 | 7280 | else if (mddev->queue) { |
|---|
| 6896 | 7281 | set_capacity(mddev->gendisk, mddev->array_sectors); |
|---|
| 6897 | | - revalidate_disk(mddev->gendisk); |
|---|
| 7282 | + revalidate_disk_size(mddev->gendisk, true); |
|---|
| 6898 | 7283 | } |
|---|
| 6899 | 7284 | } |
|---|
| 6900 | 7285 | return rv; |
|---|
| .. | .. |
|---|
| 7061 | 7446 | |
|---|
| 7062 | 7447 | mddev->bitmap_info.nodes = 0; |
|---|
| 7063 | 7448 | md_cluster_ops->leave(mddev); |
|---|
| 7449 | + module_put(md_cluster_mod); |
|---|
| 7450 | + mddev->safemode_delay = DEFAULT_SAFEMODE_DELAY; |
|---|
| 7064 | 7451 | } |
|---|
| 7065 | 7452 | mddev_suspend(mddev); |
|---|
| 7066 | 7453 | md_bitmap_destroy(mddev); |
|---|
| .. | .. |
|---|
| 7121 | 7508 | case GET_DISK_INFO: |
|---|
| 7122 | 7509 | case HOT_ADD_DISK: |
|---|
| 7123 | 7510 | case HOT_REMOVE_DISK: |
|---|
| 7124 | | - case RAID_AUTORUN: |
|---|
| 7125 | 7511 | case RAID_VERSION: |
|---|
| 7126 | 7512 | case RESTART_ARRAY_RW: |
|---|
| 7127 | 7513 | case RUN_ARRAY: |
|---|
| .. | .. |
|---|
| 7167 | 7553 | case RAID_VERSION: |
|---|
| 7168 | 7554 | err = get_version(argp); |
|---|
| 7169 | 7555 | goto out; |
|---|
| 7170 | | - |
|---|
| 7171 | | -#ifndef MODULE |
|---|
| 7172 | | - case RAID_AUTORUN: |
|---|
| 7173 | | - err = 0; |
|---|
| 7174 | | - autostart_arrays(arg); |
|---|
| 7175 | | - goto out; |
|---|
| 7176 | | -#endif |
|---|
| 7177 | 7556 | default:; |
|---|
| 7178 | 7557 | } |
|---|
| 7179 | 7558 | |
|---|
| .. | .. |
|---|
| 7214 | 7593 | |
|---|
| 7215 | 7594 | } |
|---|
| 7216 | 7595 | |
|---|
| 7217 | | - if (cmd == ADD_NEW_DISK) |
|---|
| 7218 | | - /* need to ensure md_delayed_delete() has completed */ |
|---|
| 7219 | | - flush_workqueue(md_misc_wq); |
|---|
| 7596 | + if (cmd == ADD_NEW_DISK || cmd == HOT_ADD_DISK) |
|---|
| 7597 | + flush_rdev_wq(mddev); |
|---|
| 7220 | 7598 | |
|---|
| 7221 | 7599 | if (cmd == HOT_REMOVE_DISK) |
|---|
| 7222 | 7600 | /* need to ensure recovery thread has run */ |
|---|
| .. | .. |
|---|
| 7276 | 7654 | err = -EBUSY; |
|---|
| 7277 | 7655 | goto unlock; |
|---|
| 7278 | 7656 | } |
|---|
| 7279 | | - err = set_array_info(mddev, &info); |
|---|
| 7657 | + err = md_set_array_info(mddev, &info); |
|---|
| 7280 | 7658 | if (err) { |
|---|
| 7281 | 7659 | pr_warn("md: couldn't set array info. %d\n", err); |
|---|
| 7282 | 7660 | goto unlock; |
|---|
| .. | .. |
|---|
| 7330 | 7708 | /* Need to clear read-only for this */ |
|---|
| 7331 | 7709 | break; |
|---|
| 7332 | 7710 | else |
|---|
| 7333 | | - err = add_new_disk(mddev, &info); |
|---|
| 7711 | + err = md_add_new_disk(mddev, &info); |
|---|
| 7334 | 7712 | goto unlock; |
|---|
| 7335 | 7713 | } |
|---|
| 7336 | 7714 | break; |
|---|
| .. | .. |
|---|
| 7398 | 7776 | if (copy_from_user(&info, argp, sizeof(info))) |
|---|
| 7399 | 7777 | err = -EFAULT; |
|---|
| 7400 | 7778 | else |
|---|
| 7401 | | - err = add_new_disk(mddev, &info); |
|---|
| 7779 | + err = md_add_new_disk(mddev, &info); |
|---|
| 7402 | 7780 | goto unlock; |
|---|
| 7403 | 7781 | } |
|---|
| 7404 | 7782 | |
|---|
| .. | .. |
|---|
| 7493 | 7871 | atomic_inc(&mddev->openers); |
|---|
| 7494 | 7872 | mutex_unlock(&mddev->open_mutex); |
|---|
| 7495 | 7873 | |
|---|
| 7496 | | - check_disk_change(bdev); |
|---|
| 7874 | + bdev_check_media_change(bdev); |
|---|
| 7497 | 7875 | out: |
|---|
| 7498 | 7876 | if (err) |
|---|
| 7499 | 7877 | mddev_put(mddev); |
|---|
| .. | .. |
|---|
| 7509 | 7887 | mddev_put(mddev); |
|---|
| 7510 | 7888 | } |
|---|
| 7511 | 7889 | |
|---|
| 7512 | | -static int md_media_changed(struct gendisk *disk) |
|---|
| 7890 | +static unsigned int md_check_events(struct gendisk *disk, unsigned int clearing) |
|---|
| 7513 | 7891 | { |
|---|
| 7514 | 7892 | struct mddev *mddev = disk->private_data; |
|---|
| 7893 | + unsigned int ret = 0; |
|---|
| 7515 | 7894 | |
|---|
| 7516 | | - return mddev->changed; |
|---|
| 7517 | | -} |
|---|
| 7518 | | - |
|---|
| 7519 | | -static int md_revalidate(struct gendisk *disk) |
|---|
| 7520 | | -{ |
|---|
| 7521 | | - struct mddev *mddev = disk->private_data; |
|---|
| 7522 | | - |
|---|
| 7895 | + if (mddev->changed) |
|---|
| 7896 | + ret = DISK_EVENT_MEDIA_CHANGE; |
|---|
| 7523 | 7897 | mddev->changed = 0; |
|---|
| 7524 | | - return 0; |
|---|
| 7898 | + return ret; |
|---|
| 7525 | 7899 | } |
|---|
| 7526 | | -static const struct block_device_operations md_fops = |
|---|
| 7900 | + |
|---|
| 7901 | +const struct block_device_operations md_fops = |
|---|
| 7527 | 7902 | { |
|---|
| 7528 | 7903 | .owner = THIS_MODULE, |
|---|
| 7904 | + .submit_bio = md_submit_bio, |
|---|
| 7529 | 7905 | .open = md_open, |
|---|
| 7530 | 7906 | .release = md_release, |
|---|
| 7531 | 7907 | .ioctl = md_ioctl, |
|---|
| .. | .. |
|---|
| 7533 | 7909 | .compat_ioctl = md_compat_ioctl, |
|---|
| 7534 | 7910 | #endif |
|---|
| 7535 | 7911 | .getgeo = md_getgeo, |
|---|
| 7536 | | - .media_changed = md_media_changed, |
|---|
| 7537 | | - .revalidate_disk= md_revalidate, |
|---|
| 7912 | + .check_events = md_check_events, |
|---|
| 7538 | 7913 | }; |
|---|
| 7539 | 7914 | |
|---|
| 7540 | 7915 | static int md_thread(void *arg) |
|---|
| .. | .. |
|---|
| 7618 | 7993 | |
|---|
| 7619 | 7994 | void md_unregister_thread(struct md_thread **threadp) |
|---|
| 7620 | 7995 | { |
|---|
| 7621 | | - struct md_thread *thread = *threadp; |
|---|
| 7622 | | - if (!thread) |
|---|
| 7623 | | - return; |
|---|
| 7624 | | - pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); |
|---|
| 7625 | | - /* Locking ensures that mddev_unlock does not wake_up a |
|---|
| 7996 | + struct md_thread *thread; |
|---|
| 7997 | + |
|---|
| 7998 | + /* |
|---|
| 7999 | + * Locking ensures that mddev_unlock does not wake_up a |
|---|
| 7626 | 8000 | * non-existent thread |
|---|
| 7627 | 8001 | */ |
|---|
| 7628 | 8002 | spin_lock(&pers_lock); |
|---|
| 8003 | + thread = *threadp; |
|---|
| 8004 | + if (!thread) { |
|---|
| 8005 | + spin_unlock(&pers_lock); |
|---|
| 8006 | + return; |
|---|
| 8007 | + } |
|---|
| 7629 | 8008 | *threadp = NULL; |
|---|
| 7630 | 8009 | spin_unlock(&pers_lock); |
|---|
| 7631 | 8010 | |
|---|
| 8011 | + pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); |
|---|
| 7632 | 8012 | kthread_stop(thread->tsk); |
|---|
| 7633 | 8013 | kfree(thread); |
|---|
| 7634 | 8014 | } |
|---|
| .. | .. |
|---|
| 8006 | 8386 | return mask; |
|---|
| 8007 | 8387 | } |
|---|
| 8008 | 8388 | |
|---|
| 8009 | | -static const struct file_operations md_seq_fops = { |
|---|
| 8010 | | - .owner = THIS_MODULE, |
|---|
| 8011 | | - .open = md_seq_open, |
|---|
| 8012 | | - .read = seq_read, |
|---|
| 8013 | | - .llseek = seq_lseek, |
|---|
| 8014 | | - .release = seq_release, |
|---|
| 8015 | | - .poll = mdstat_poll, |
|---|
| 8389 | +static const struct proc_ops mdstat_proc_ops = { |
|---|
| 8390 | + .proc_open = md_seq_open, |
|---|
| 8391 | + .proc_read = seq_read, |
|---|
| 8392 | + .proc_lseek = seq_lseek, |
|---|
| 8393 | + .proc_release = seq_release, |
|---|
| 8394 | + .proc_poll = mdstat_poll, |
|---|
| 8016 | 8395 | }; |
|---|
| 8017 | 8396 | |
|---|
| 8018 | 8397 | int register_md_personality(struct md_personality *p) |
|---|
| .. | .. |
|---|
| 8063 | 8442 | |
|---|
| 8064 | 8443 | int md_setup_cluster(struct mddev *mddev, int nodes) |
|---|
| 8065 | 8444 | { |
|---|
| 8445 | + int ret; |
|---|
| 8066 | 8446 | if (!md_cluster_ops) |
|---|
| 8067 | 8447 | request_module("md-cluster"); |
|---|
| 8068 | 8448 | spin_lock(&pers_lock); |
|---|
| .. | .. |
|---|
| 8074 | 8454 | } |
|---|
| 8075 | 8455 | spin_unlock(&pers_lock); |
|---|
| 8076 | 8456 | |
|---|
| 8077 | | - return md_cluster_ops->join(mddev, nodes); |
|---|
| 8457 | + ret = md_cluster_ops->join(mddev, nodes); |
|---|
| 8458 | + if (!ret) |
|---|
| 8459 | + mddev->safemode_delay = 0; |
|---|
| 8460 | + return ret; |
|---|
| 8078 | 8461 | } |
|---|
| 8079 | 8462 | |
|---|
| 8080 | 8463 | void md_cluster_stop(struct mddev *mddev) |
|---|
| .. | .. |
|---|
| 8094 | 8477 | idle = 1; |
|---|
| 8095 | 8478 | rcu_read_lock(); |
|---|
| 8096 | 8479 | rdev_for_each_rcu(rdev, mddev) { |
|---|
| 8097 | | - struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; |
|---|
| 8480 | + struct gendisk *disk = rdev->bdev->bd_disk; |
|---|
| 8098 | 8481 | curr_events = (int)part_stat_read_accum(&disk->part0, sectors) - |
|---|
| 8099 | 8482 | atomic_read(&disk->sync_io); |
|---|
| 8100 | 8483 | /* sync IO will cause sync_io to increase before the disk_stats |
|---|
| .. | .. |
|---|
| 8273 | 8656 | { |
|---|
| 8274 | 8657 | struct mddev *mddev = thread->mddev; |
|---|
| 8275 | 8658 | struct mddev *mddev2; |
|---|
| 8276 | | - unsigned int currspeed = 0, |
|---|
| 8277 | | - window; |
|---|
| 8659 | + unsigned int currspeed = 0, window; |
|---|
| 8278 | 8660 | sector_t max_sectors,j, io_sectors, recovery_done; |
|---|
| 8279 | 8661 | unsigned long mark[SYNC_MARKS]; |
|---|
| 8280 | 8662 | unsigned long update_time; |
|---|
| .. | .. |
|---|
| 8331 | 8713 | * 0 == not engaged in resync at all |
|---|
| 8332 | 8714 | * 2 == checking that there is no conflict with another sync |
|---|
| 8333 | 8715 | * 1 == like 2, but have yielded to allow conflicting resync to |
|---|
| 8334 | | - * commense |
|---|
| 8716 | + * commence |
|---|
| 8335 | 8717 | * other == active in resync - this many blocks |
|---|
| 8336 | 8718 | * |
|---|
| 8337 | 8719 | * Before starting a resync we must have set curr_resync to |
|---|
| .. | .. |
|---|
| 8405 | 8787 | else if (!mddev->bitmap) |
|---|
| 8406 | 8788 | j = mddev->recovery_cp; |
|---|
| 8407 | 8789 | |
|---|
| 8408 | | - } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
|---|
| 8790 | + } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { |
|---|
| 8409 | 8791 | max_sectors = mddev->resync_max_sectors; |
|---|
| 8410 | | - else { |
|---|
| 8792 | + /* |
|---|
| 8793 | + * If the original node aborts reshaping then we continue the |
|---|
| 8794 | + * reshaping, so set j again to avoid restart reshape from the |
|---|
| 8795 | + * first beginning |
|---|
| 8796 | + */ |
|---|
| 8797 | + if (mddev_is_clustered(mddev) && |
|---|
| 8798 | + mddev->reshape_position != MaxSector) |
|---|
| 8799 | + j = mddev->reshape_position; |
|---|
| 8800 | + } else { |
|---|
| 8411 | 8801 | /* recovery follows the physical size of devices */ |
|---|
| 8412 | 8802 | max_sectors = mddev->dev_sectors; |
|---|
| 8413 | 8803 | j = MaxSector; |
|---|
| .. | .. |
|---|
| 8454 | 8844 | /* |
|---|
| 8455 | 8845 | * Tune reconstruction: |
|---|
| 8456 | 8846 | */ |
|---|
| 8457 | | - window = 32*(PAGE_SIZE/512); |
|---|
| 8847 | + window = 32 * (PAGE_SIZE / 512); |
|---|
| 8458 | 8848 | pr_debug("md: using %dk window, over a total of %lluk.\n", |
|---|
| 8459 | 8849 | window/2, (unsigned long long)max_sectors/2); |
|---|
| 8460 | 8850 | |
|---|
| .. | .. |
|---|
| 8468 | 8858 | } else |
|---|
| 8469 | 8859 | mddev->curr_resync = 3; /* no longer delayed */ |
|---|
| 8470 | 8860 | mddev->curr_resync_completed = j; |
|---|
| 8471 | | - sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
|---|
| 8861 | + sysfs_notify_dirent_safe(mddev->sysfs_completed); |
|---|
| 8472 | 8862 | md_new_event(mddev); |
|---|
| 8473 | 8863 | update_time = jiffies; |
|---|
| 8474 | 8864 | |
|---|
| .. | .. |
|---|
| 8496 | 8886 | mddev->recovery_cp = j; |
|---|
| 8497 | 8887 | update_time = jiffies; |
|---|
| 8498 | 8888 | set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags); |
|---|
| 8499 | | - sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
|---|
| 8889 | + sysfs_notify_dirent_safe(mddev->sysfs_completed); |
|---|
| 8500 | 8890 | } |
|---|
| 8501 | 8891 | |
|---|
| 8502 | 8892 | while (j >= mddev->resync_max && |
|---|
| .. | .. |
|---|
| 8603 | 8993 | !test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
|---|
| 8604 | 8994 | mddev->curr_resync > 3) { |
|---|
| 8605 | 8995 | mddev->curr_resync_completed = mddev->curr_resync; |
|---|
| 8606 | | - sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
|---|
| 8996 | + sysfs_notify_dirent_safe(mddev->sysfs_completed); |
|---|
| 8607 | 8997 | } |
|---|
| 8608 | 8998 | mddev->pers->sync_request(mddev, max_sectors, &skipped); |
|---|
| 8609 | 8999 | |
|---|
| .. | .. |
|---|
| 8658 | 9048 | mddev_lock_nointr(mddev); |
|---|
| 8659 | 9049 | md_set_array_sectors(mddev, mddev->pers->size(mddev, 0, 0)); |
|---|
| 8660 | 9050 | mddev_unlock(mddev); |
|---|
| 8661 | | - set_capacity(mddev->gendisk, mddev->array_sectors); |
|---|
| 8662 | | - revalidate_disk(mddev->gendisk); |
|---|
| 9051 | + if (!mddev_is_clustered(mddev)) { |
|---|
| 9052 | + set_capacity(mddev->gendisk, mddev->array_sectors); |
|---|
| 9053 | + revalidate_disk_size(mddev->gendisk, true); |
|---|
| 9054 | + } |
|---|
| 8663 | 9055 | } |
|---|
| 8664 | 9056 | |
|---|
| 8665 | 9057 | spin_lock(&mddev->lock); |
|---|
| .. | .. |
|---|
| 8731 | 9123 | } |
|---|
| 8732 | 9124 | |
|---|
| 8733 | 9125 | if (removed && mddev->kobj.sd) |
|---|
| 8734 | | - sysfs_notify(&mddev->kobj, NULL, "degraded"); |
|---|
| 9126 | + sysfs_notify_dirent_safe(mddev->sysfs_degraded); |
|---|
| 8735 | 9127 | |
|---|
| 8736 | 9128 | if (this && removed) |
|---|
| 8737 | 9129 | goto no_add; |
|---|
| .. | .. |
|---|
| 8758 | 9150 | |
|---|
| 8759 | 9151 | rdev->recovery_offset = 0; |
|---|
| 8760 | 9152 | } |
|---|
| 8761 | | - if (mddev->pers-> |
|---|
| 8762 | | - hot_add_disk(mddev, rdev) == 0) { |
|---|
| 8763 | | - if (sysfs_link_rdev(mddev, rdev)) |
|---|
| 8764 | | - /* failure here is OK */; |
|---|
| 9153 | + if (mddev->pers->hot_add_disk(mddev, rdev) == 0) { |
|---|
| 9154 | + /* failure here is OK */ |
|---|
| 9155 | + sysfs_link_rdev(mddev, rdev); |
|---|
| 8765 | 9156 | if (!test_bit(Journal, &rdev->flags)) |
|---|
| 8766 | 9157 | spares++; |
|---|
| 8767 | 9158 | md_new_event(mddev); |
|---|
| .. | .. |
|---|
| 9004 | 9395 | void md_reap_sync_thread(struct mddev *mddev) |
|---|
| 9005 | 9396 | { |
|---|
| 9006 | 9397 | struct md_rdev *rdev; |
|---|
| 9398 | + sector_t old_dev_sectors = mddev->dev_sectors; |
|---|
| 9399 | + bool is_reshaped = false; |
|---|
| 9007 | 9400 | |
|---|
| 9008 | 9401 | /* resync has finished, collect result */ |
|---|
| 9009 | 9402 | md_unregister_thread(&mddev->sync_thread); |
|---|
| .. | .. |
|---|
| 9013 | 9406 | /* success...*/ |
|---|
| 9014 | 9407 | /* activate any spares */ |
|---|
| 9015 | 9408 | if (mddev->pers->spare_active(mddev)) { |
|---|
| 9016 | | - sysfs_notify(&mddev->kobj, NULL, |
|---|
| 9017 | | - "degraded"); |
|---|
| 9409 | + sysfs_notify_dirent_safe(mddev->sysfs_degraded); |
|---|
| 9018 | 9410 | set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); |
|---|
| 9019 | 9411 | } |
|---|
| 9020 | 9412 | } |
|---|
| 9021 | 9413 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && |
|---|
| 9022 | | - mddev->pers->finish_reshape) |
|---|
| 9414 | + mddev->pers->finish_reshape) { |
|---|
| 9023 | 9415 | mddev->pers->finish_reshape(mddev); |
|---|
| 9416 | + if (mddev_is_clustered(mddev)) |
|---|
| 9417 | + is_reshaped = true; |
|---|
| 9418 | + } |
|---|
| 9024 | 9419 | |
|---|
| 9025 | 9420 | /* If array is no-longer degraded, then any saved_raid_disk |
|---|
| 9026 | 9421 | * information must be scrapped. |
|---|
| .. | .. |
|---|
| 9041 | 9436 | clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |
|---|
| 9042 | 9437 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); |
|---|
| 9043 | 9438 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
|---|
| 9439 | + /* |
|---|
| 9440 | + * We call md_cluster_ops->update_size here because sync_size could |
|---|
| 9441 | + * be changed by md_update_sb, and MD_RECOVERY_RESHAPE is cleared, |
|---|
| 9442 | + * so it is time to update size across cluster. |
|---|
| 9443 | + */ |
|---|
| 9444 | + if (mddev_is_clustered(mddev) && is_reshaped |
|---|
| 9445 | + && !test_bit(MD_CLOSING, &mddev->flags)) |
|---|
| 9446 | + md_cluster_ops->update_size(mddev, old_dev_sectors); |
|---|
| 9044 | 9447 | wake_up(&resync_wait); |
|---|
| 9045 | 9448 | /* flag recovery needed just to double check */ |
|---|
| 9046 | 9449 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
|---|
| 9450 | + sysfs_notify_dirent_safe(mddev->sysfs_completed); |
|---|
| 9047 | 9451 | sysfs_notify_dirent_safe(mddev->sysfs_action); |
|---|
| 9048 | 9452 | md_new_event(mddev); |
|---|
| 9049 | 9453 | if (mddev->event_work.func) |
|---|
| .. | .. |
|---|
| 9093 | 9497 | if (rv == 0) { |
|---|
| 9094 | 9498 | /* Make sure they get written out promptly */ |
|---|
| 9095 | 9499 | if (test_bit(ExternalBbl, &rdev->flags)) |
|---|
| 9096 | | - sysfs_notify(&rdev->kobj, NULL, |
|---|
| 9097 | | - "unacknowledged_bad_blocks"); |
|---|
| 9500 | + sysfs_notify_dirent_safe(rdev->sysfs_unack_badblocks); |
|---|
| 9098 | 9501 | sysfs_notify_dirent_safe(rdev->sysfs_state); |
|---|
| 9099 | 9502 | set_mask_bits(&mddev->sb_flags, 0, |
|---|
| 9100 | 9503 | BIT(MD_SB_CHANGE_CLEAN) | BIT(MD_SB_CHANGE_PENDING)); |
|---|
| .. | .. |
|---|
| 9115 | 9518 | s += rdev->data_offset; |
|---|
| 9116 | 9519 | rv = badblocks_clear(&rdev->badblocks, s, sectors); |
|---|
| 9117 | 9520 | if ((rv == 0) && test_bit(ExternalBbl, &rdev->flags)) |
|---|
| 9118 | | - sysfs_notify(&rdev->kobj, NULL, "bad_blocks"); |
|---|
| 9521 | + sysfs_notify_dirent_safe(rdev->sysfs_badblocks); |
|---|
| 9119 | 9522 | return rv; |
|---|
| 9120 | 9523 | } |
|---|
| 9121 | 9524 | EXPORT_SYMBOL_GPL(rdev_clear_badblocks); |
|---|
| .. | .. |
|---|
| 9159 | 9562 | { |
|---|
| 9160 | 9563 | pr_debug("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); |
|---|
| 9161 | 9564 | |
|---|
| 9162 | | - proc_create("mdstat", S_IRUGO, NULL, &md_seq_fops); |
|---|
| 9565 | + proc_create("mdstat", S_IRUGO, NULL, &mdstat_proc_ops); |
|---|
| 9163 | 9566 | } |
|---|
| 9164 | 9567 | |
|---|
| 9165 | 9568 | static int __init md_init(void) |
|---|
| .. | .. |
|---|
| 9173 | 9576 | md_misc_wq = alloc_workqueue("md_misc", 0, 0); |
|---|
| 9174 | 9577 | if (!md_misc_wq) |
|---|
| 9175 | 9578 | goto err_misc_wq; |
|---|
| 9579 | + |
|---|
| 9580 | + md_rdev_misc_wq = alloc_workqueue("md_rdev_misc", 0, 0); |
|---|
| 9581 | + if (!md_rdev_misc_wq) |
|---|
| 9582 | + goto err_rdev_misc_wq; |
|---|
| 9176 | 9583 | |
|---|
| 9177 | 9584 | if ((ret = register_blkdev(MD_MAJOR, "md")) < 0) |
|---|
| 9178 | 9585 | goto err_md; |
|---|
| .. | .. |
|---|
| 9195 | 9602 | err_mdp: |
|---|
| 9196 | 9603 | unregister_blkdev(MD_MAJOR, "md"); |
|---|
| 9197 | 9604 | err_md: |
|---|
| 9605 | + destroy_workqueue(md_rdev_misc_wq); |
|---|
| 9606 | +err_rdev_misc_wq: |
|---|
| 9198 | 9607 | destroy_workqueue(md_misc_wq); |
|---|
| 9199 | 9608 | err_misc_wq: |
|---|
| 9200 | 9609 | destroy_workqueue(md_wq); |
|---|
| .. | .. |
|---|
| 9240 | 9649 | } |
|---|
| 9241 | 9650 | |
|---|
| 9242 | 9651 | if (role != rdev2->raid_disk) { |
|---|
| 9243 | | - /* got activated */ |
|---|
| 9244 | | - if (rdev2->raid_disk == -1 && role != 0xffff) { |
|---|
| 9652 | + /* |
|---|
| 9653 | + * got activated except reshape is happening. |
|---|
| 9654 | + */ |
|---|
| 9655 | + if (rdev2->raid_disk == -1 && role != 0xffff && |
|---|
| 9656 | + !(le32_to_cpu(sb->feature_map) & |
|---|
| 9657 | + MD_FEATURE_RESHAPE_ACTIVE)) { |
|---|
| 9245 | 9658 | rdev2->saved_raid_disk = role; |
|---|
| 9246 | 9659 | ret = remove_and_add_spares(mddev, rdev2); |
|---|
| 9247 | 9660 | pr_info("Activated spare: %s\n", |
|---|
| .. | .. |
|---|
| 9250 | 9663 | * perform resync with the new activated disk */ |
|---|
| 9251 | 9664 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
|---|
| 9252 | 9665 | md_wakeup_thread(mddev->thread); |
|---|
| 9253 | | - |
|---|
| 9254 | 9666 | } |
|---|
| 9255 | 9667 | /* device faulty |
|---|
| 9256 | 9668 | * We just want to do the minimum to mark the disk |
|---|
| .. | .. |
|---|
| 9268 | 9680 | ret = update_raid_disks(mddev, le32_to_cpu(sb->raid_disks)); |
|---|
| 9269 | 9681 | if (ret) |
|---|
| 9270 | 9682 | pr_warn("md: updating array disks failed. %d\n", ret); |
|---|
| 9683 | + } |
|---|
| 9684 | + |
|---|
| 9685 | + /* |
|---|
| 9686 | + * Since mddev->delta_disks has already updated in update_raid_disks, |
|---|
| 9687 | + * so it is time to check reshape. |
|---|
| 9688 | + */ |
|---|
| 9689 | + if (test_bit(MD_RESYNCING_REMOTE, &mddev->recovery) && |
|---|
| 9690 | + (le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { |
|---|
| 9691 | + /* |
|---|
| 9692 | + * reshape is happening in the remote node, we need to |
|---|
| 9693 | + * update reshape_position and call start_reshape. |
|---|
| 9694 | + */ |
|---|
| 9695 | + mddev->reshape_position = le64_to_cpu(sb->reshape_position); |
|---|
| 9696 | + if (mddev->pers->update_reshape_pos) |
|---|
| 9697 | + mddev->pers->update_reshape_pos(mddev); |
|---|
| 9698 | + if (mddev->pers->start_reshape) |
|---|
| 9699 | + mddev->pers->start_reshape(mddev); |
|---|
| 9700 | + } else if (test_bit(MD_RESYNCING_REMOTE, &mddev->recovery) && |
|---|
| 9701 | + mddev->reshape_position != MaxSector && |
|---|
| 9702 | + !(le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { |
|---|
| 9703 | + /* reshape is just done in another node. */ |
|---|
| 9704 | + mddev->reshape_position = MaxSector; |
|---|
| 9705 | + if (mddev->pers->update_reshape_pos) |
|---|
| 9706 | + mddev->pers->update_reshape_pos(mddev); |
|---|
| 9271 | 9707 | } |
|---|
| 9272 | 9708 | |
|---|
| 9273 | 9709 | /* Finally set the event to be up to date */ |
|---|
| .. | .. |
|---|
| 9315 | 9751 | if (rdev->recovery_offset == MaxSector && |
|---|
| 9316 | 9752 | !test_bit(In_sync, &rdev->flags) && |
|---|
| 9317 | 9753 | mddev->pers->spare_active(mddev)) |
|---|
| 9318 | | - sysfs_notify(&mddev->kobj, NULL, "degraded"); |
|---|
| 9754 | + sysfs_notify_dirent_safe(mddev->sysfs_degraded); |
|---|
| 9319 | 9755 | |
|---|
| 9320 | 9756 | put_page(swapout); |
|---|
| 9321 | 9757 | return 0; |
|---|
| .. | .. |
|---|
| 9323 | 9759 | |
|---|
| 9324 | 9760 | void md_reload_sb(struct mddev *mddev, int nr) |
|---|
| 9325 | 9761 | { |
|---|
| 9326 | | - struct md_rdev *rdev; |
|---|
| 9762 | + struct md_rdev *rdev = NULL, *iter; |
|---|
| 9327 | 9763 | int err; |
|---|
| 9328 | 9764 | |
|---|
| 9329 | 9765 | /* Find the rdev */ |
|---|
| 9330 | | - rdev_for_each_rcu(rdev, mddev) { |
|---|
| 9331 | | - if (rdev->desc_nr == nr) |
|---|
| 9766 | + rdev_for_each_rcu(iter, mddev) { |
|---|
| 9767 | + if (iter->desc_nr == nr) { |
|---|
| 9768 | + rdev = iter; |
|---|
| 9332 | 9769 | break; |
|---|
| 9770 | + } |
|---|
| 9333 | 9771 | } |
|---|
| 9334 | 9772 | |
|---|
| 9335 | | - if (!rdev || rdev->desc_nr != nr) { |
|---|
| 9773 | + if (!rdev) { |
|---|
| 9336 | 9774 | pr_warn("%s: %d Could not find rdev with nr %d\n", __func__, __LINE__, nr); |
|---|
| 9337 | 9775 | return; |
|---|
| 9338 | 9776 | } |
|---|
| .. | .. |
|---|
| 9378 | 9816 | } |
|---|
| 9379 | 9817 | } |
|---|
| 9380 | 9818 | |
|---|
| 9381 | | -static void autostart_arrays(int part) |
|---|
| 9819 | +void md_autostart_arrays(int part) |
|---|
| 9382 | 9820 | { |
|---|
| 9383 | 9821 | struct md_rdev *rdev; |
|---|
| 9384 | 9822 | struct detected_devices_node *node_detected_dev; |
|---|
| .. | .. |
|---|
| 9457 | 9895 | * destroy_workqueue() below will wait for that to complete. |
|---|
| 9458 | 9896 | */ |
|---|
| 9459 | 9897 | } |
|---|
| 9898 | + destroy_workqueue(md_rdev_misc_wq); |
|---|
| 9460 | 9899 | destroy_workqueue(md_misc_wq); |
|---|
| 9461 | 9900 | destroy_workqueue(md_wq); |
|---|
| 9462 | 9901 | } |
|---|
| .. | .. |
|---|
| 9466 | 9905 | |
|---|
| 9467 | 9906 | static int get_ro(char *buffer, const struct kernel_param *kp) |
|---|
| 9468 | 9907 | { |
|---|
| 9469 | | - return sprintf(buffer, "%d", start_readonly); |
|---|
| 9908 | + return sprintf(buffer, "%d\n", start_readonly); |
|---|
| 9470 | 9909 | } |
|---|
| 9471 | 9910 | static int set_ro(const char *val, const struct kernel_param *kp) |
|---|
| 9472 | 9911 | { |
|---|