diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 807095f4c793..61aacab424cf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -314,8 +314,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) | |||
314 | */ | 314 | */ |
315 | void mddev_suspend(struct mddev *mddev) | 315 | void mddev_suspend(struct mddev *mddev) |
316 | { | 316 | { |
317 | BUG_ON(mddev->suspended); | 317 | if (mddev->suspended++) |
318 | mddev->suspended = 1; | 318 | return; |
319 | synchronize_rcu(); | 319 | synchronize_rcu(); |
320 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); | 320 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); |
321 | mddev->pers->quiesce(mddev, 1); | 321 | mddev->pers->quiesce(mddev, 1); |
@@ -326,7 +326,8 @@ EXPORT_SYMBOL_GPL(mddev_suspend); | |||
326 | 326 | ||
327 | void mddev_resume(struct mddev *mddev) | 327 | void mddev_resume(struct mddev *mddev) |
328 | { | 328 | { |
329 | mddev->suspended = 0; | 329 | if (--mddev->suspended) |
330 | return; | ||
330 | wake_up(&mddev->sb_wait); | 331 | wake_up(&mddev->sb_wait); |
331 | mddev->pers->quiesce(mddev, 0); | 332 | mddev->pers->quiesce(mddev, 0); |
332 | 333 | ||
@@ -1652,7 +1653,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1652 | rdev->journal_tail = le64_to_cpu(sb->journal_tail); | 1653 | rdev->journal_tail = le64_to_cpu(sb->journal_tail); |
1653 | if (mddev->recovery_cp == MaxSector) | 1654 | if (mddev->recovery_cp == MaxSector) |
1654 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); | 1655 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); |
1655 | rdev->raid_disk = mddev->raid_disks; | 1656 | rdev->raid_disk = 0; |
1656 | break; | 1657 | break; |
1657 | default: | 1658 | default: |
1658 | rdev->saved_raid_disk = role; | 1659 | rdev->saved_raid_disk = role; |
@@ -2773,6 +2774,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2773 | /* Activating a spare .. or possibly reactivating | 2774 | /* Activating a spare .. or possibly reactivating |
2774 | * if we ever get bitmaps working here. | 2775 | * if we ever get bitmaps working here. |
2775 | */ | 2776 | */ |
2777 | int err; | ||
2776 | 2778 | ||
2777 | if (rdev->raid_disk != -1) | 2779 | if (rdev->raid_disk != -1) |
2778 | return -EBUSY; | 2780 | return -EBUSY; |
@@ -2794,9 +2796,15 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2794 | rdev->saved_raid_disk = -1; | 2796 | rdev->saved_raid_disk = -1; |
2795 | clear_bit(In_sync, &rdev->flags); | 2797 | clear_bit(In_sync, &rdev->flags); |
2796 | clear_bit(Bitmap_sync, &rdev->flags); | 2798 | clear_bit(Bitmap_sync, &rdev->flags); |
2797 | remove_and_add_spares(rdev->mddev, rdev); | 2799 | err = rdev->mddev->pers-> |
2798 | if (rdev->raid_disk == -1) | 2800 | hot_add_disk(rdev->mddev, rdev); |
2799 | return -EBUSY; | 2801 | if (err) { |
2802 | rdev->raid_disk = -1; | ||
2803 | return err; | ||
2804 | } else | ||
2805 | sysfs_notify_dirent_safe(rdev->sysfs_state); | ||
2806 | if (sysfs_link_rdev(rdev->mddev, rdev)) | ||
2807 | /* failure here is OK */; | ||
2800 | /* don't wakeup anyone, leave that to userspace. */ | 2808 | /* don't wakeup anyone, leave that to userspace. */ |
2801 | } else { | 2809 | } else { |
2802 | if (slot >= rdev->mddev->raid_disks && | 2810 | if (slot >= rdev->mddev->raid_disks && |
@@ -4318,8 +4326,7 @@ action_store(struct mddev *mddev, const char *page, size_t len) | |||
4318 | } | 4326 | } |
4319 | mddev_unlock(mddev); | 4327 | mddev_unlock(mddev); |
4320 | } | 4328 | } |
4321 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | 4329 | } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
4322 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | ||
4323 | return -EBUSY; | 4330 | return -EBUSY; |
4324 | else if (cmd_match(page, "resync")) | 4331 | else if (cmd_match(page, "resync")) |
4325 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 4332 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
@@ -4332,8 +4339,12 @@ action_store(struct mddev *mddev, const char *page, size_t len) | |||
4332 | return -EINVAL; | 4339 | return -EINVAL; |
4333 | err = mddev_lock(mddev); | 4340 | err = mddev_lock(mddev); |
4334 | if (!err) { | 4341 | if (!err) { |
4335 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | 4342 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
4336 | err = mddev->pers->start_reshape(mddev); | 4343 | err = -EBUSY; |
4344 | else { | ||
4345 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | ||
4346 | err = mddev->pers->start_reshape(mddev); | ||
4347 | } | ||
4337 | mddev_unlock(mddev); | 4348 | mddev_unlock(mddev); |
4338 | } | 4349 | } |
4339 | if (err) | 4350 | if (err) |