diff options
| -rw-r--r-- | drivers/md/raid5.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2ae63c5b1c25..e5795d39d418 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -5086,36 +5086,42 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
| 5086 | struct r5conf *conf = mddev->private; | 5086 | struct r5conf *conf = mddev->private; |
| 5087 | int err = 0; | 5087 | int err = 0; |
| 5088 | int number = rdev->raid_disk; | 5088 | int number = rdev->raid_disk; |
| 5089 | struct md_rdev **rdevp; | ||
| 5089 | struct disk_info *p = conf->disks + number; | 5090 | struct disk_info *p = conf->disks + number; |
| 5090 | 5091 | ||
| 5091 | print_raid5_conf(conf); | 5092 | print_raid5_conf(conf); |
| 5092 | if (rdev == p->rdev) { | 5093 | if (rdev == p->rdev) |
| 5093 | if (number >= conf->raid_disks && | 5094 | rdevp = &p->rdev; |
| 5094 | conf->reshape_progress == MaxSector) | 5095 | else if (rdev == p->replacement) |
| 5095 | clear_bit(In_sync, &rdev->flags); | 5096 | rdevp = &p->replacement; |
| 5097 | else | ||
| 5098 | return 0; | ||
| 5096 | 5099 | ||
| 5097 | if (test_bit(In_sync, &rdev->flags) || | 5100 | if (number >= conf->raid_disks && |
| 5098 | atomic_read(&rdev->nr_pending)) { | 5101 | conf->reshape_progress == MaxSector) |
| 5099 | err = -EBUSY; | 5102 | clear_bit(In_sync, &rdev->flags); |
| 5100 | goto abort; | 5103 | |
| 5101 | } | 5104 | if (test_bit(In_sync, &rdev->flags) || |
| 5102 | /* Only remove non-faulty devices if recovery | 5105 | atomic_read(&rdev->nr_pending)) { |
| 5103 | * isn't possible. | 5106 | err = -EBUSY; |
| 5104 | */ | 5107 | goto abort; |
| 5105 | if (!test_bit(Faulty, &rdev->flags) && | 5108 | } |
| 5106 | mddev->recovery_disabled != conf->recovery_disabled && | 5109 | /* Only remove non-faulty devices if recovery |
| 5107 | !has_failed(conf) && | 5110 | * isn't possible. |
| 5108 | number < conf->raid_disks) { | 5111 | */ |
| 5109 | err = -EBUSY; | 5112 | if (!test_bit(Faulty, &rdev->flags) && |
| 5110 | goto abort; | 5113 | mddev->recovery_disabled != conf->recovery_disabled && |
| 5111 | } | 5114 | !has_failed(conf) && |
| 5112 | p->rdev = NULL; | 5115 | number < conf->raid_disks) { |
| 5113 | synchronize_rcu(); | 5116 | err = -EBUSY; |
| 5114 | if (atomic_read(&rdev->nr_pending)) { | 5117 | goto abort; |
| 5115 | /* lost the race, try later */ | 5118 | } |
| 5116 | err = -EBUSY; | 5119 | *rdevp = NULL; |
| 5117 | p->rdev = rdev; | 5120 | synchronize_rcu(); |
| 5118 | } | 5121 | if (atomic_read(&rdev->nr_pending)) { |
| 5122 | /* lost the race, try later */ | ||
| 5123 | err = -EBUSY; | ||
| 5124 | *rdevp = rdev; | ||
| 5119 | } | 5125 | } |
| 5120 | abort: | 5126 | abort: |
| 5121 | 5127 | ||
