.. | .. |
---|
555 | 555 | struct md_rdev *rdev = bio->bi_private; |
---|
556 | 556 | struct mddev *mddev = rdev->mddev; |
---|
557 | 557 | |
---|
| 558 | + bio_put(bio); |
---|
| 559 | + |
---|
558 | 560 | rdev_dec_pending(rdev, mddev); |
---|
559 | 561 | |
---|
560 | 562 | if (atomic_dec_and_test(&mddev->flush_pending)) { |
---|
561 | 563 | /* The pre-request flush has finished */ |
---|
562 | 564 | queue_work(md_wq, &mddev->flush_work); |
---|
563 | 565 | } |
---|
564 | | - bio_put(bio); |
---|
565 | 566 | } |
---|
566 | 567 | |
---|
567 | 568 | static void md_submit_flush_data(struct work_struct *ws); |
---|
.. | .. |
---|
966 | 967 | } else |
---|
967 | 968 | clear_bit(LastDev, &rdev->flags); |
---|
968 | 969 | |
---|
| 970 | + bio_put(bio); |
---|
| 971 | + |
---|
| 972 | + rdev_dec_pending(rdev, mddev); |
---|
| 973 | + |
---|
969 | 974 | if (atomic_dec_and_test(&mddev->pending_writes)) |
---|
970 | 975 | wake_up(&mddev->sb_wait); |
---|
971 | | - rdev_dec_pending(rdev, mddev); |
---|
972 | | - bio_put(bio); |
---|
973 | 976 | } |
---|
974 | 977 | |
---|
975 | 978 | void md_super_write(struct mddev *mddev, struct md_rdev *rdev, |
---|
.. | .. |
---|
3204 | 3207 | err = kstrtouint(buf, 10, (unsigned int *)&slot); |
---|
3205 | 3208 | if (err < 0) |
---|
3206 | 3209 | return err; |
---|
| 3210 | + if (slot < 0) |
---|
| 3211 | + /* overflow */ |
---|
| 3212 | + return -ENOSPC; |
---|
3207 | 3213 | } |
---|
3208 | 3214 | if (rdev->mddev->pers && slot == -1) { |
---|
3209 | 3215 | /* Setting 'slot' on an active array requires also |
---|
.. | .. |
---|
3884 | 3890 | static ssize_t |
---|
3885 | 3891 | safe_delay_show(struct mddev *mddev, char *page) |
---|
3886 | 3892 | { |
---|
3887 | | - int msec = (mddev->safemode_delay*1000)/HZ; |
---|
3888 | | - 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); |
---|
3889 | 3896 | } |
---|
3890 | 3897 | static ssize_t |
---|
3891 | 3898 | safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) |
---|
.. | .. |
---|
3897 | 3904 | return -EINVAL; |
---|
3898 | 3905 | } |
---|
3899 | 3906 | |
---|
3900 | | - if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) |
---|
| 3907 | + if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) |
---|
3901 | 3908 | return -EINVAL; |
---|
3902 | 3909 | if (msec == 0) |
---|
3903 | 3910 | mddev->safemode_delay = 0; |
---|
.. | .. |
---|
4567 | 4574 | rv = kstrtouint(buf, 10, &n); |
---|
4568 | 4575 | if (rv < 0) |
---|
4569 | 4576 | return rv; |
---|
| 4577 | + if (n > INT_MAX) |
---|
| 4578 | + return -EINVAL; |
---|
4570 | 4579 | atomic_set(&mddev->max_corr_read_errors, n); |
---|
4571 | 4580 | return len; |
---|
4572 | 4581 | } |
---|
.. | .. |
---|
4881 | 4890 | return -EINVAL; |
---|
4882 | 4891 | err = mddev_lock(mddev); |
---|
4883 | 4892 | if (!err) { |
---|
4884 | | - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
---|
| 4893 | + if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { |
---|
4885 | 4894 | err = -EBUSY; |
---|
4886 | | - else { |
---|
| 4895 | + } else if (mddev->reshape_position == MaxSector || |
---|
| 4896 | + mddev->pers->check_reshape == NULL || |
---|
| 4897 | + mddev->pers->check_reshape(mddev)) { |
---|
4887 | 4898 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
---|
4888 | 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); |
---|
4889 | 4908 | } |
---|
4890 | 4909 | mddev_unlock(mddev); |
---|
4891 | 4910 | } |
---|
.. | .. |
---|
5680 | 5699 | * completely removed (mddev_delayed_delete). |
---|
5681 | 5700 | */ |
---|
5682 | 5701 | flush_workqueue(md_misc_wq); |
---|
| 5702 | + flush_workqueue(md_rdev_misc_wq); |
---|
5683 | 5703 | |
---|
5684 | 5704 | mutex_lock(&disks_mutex); |
---|
5685 | 5705 | error = -EEXIST; |
---|
.. | .. |
---|
6296 | 6316 | |
---|
6297 | 6317 | void md_stop(struct mddev *mddev) |
---|
6298 | 6318 | { |
---|
| 6319 | + lockdep_assert_held(&mddev->reconfig_mutex); |
---|
| 6320 | + |
---|
6299 | 6321 | /* stop the array and free an attached data structures. |
---|
6300 | 6322 | * This is called from dm-raid |
---|
6301 | 6323 | */ |
---|