diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index faf3d8912979..1de17da34a95 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1020,7 +1020,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1020 | /* | 1020 | /* |
1021 | * if recovery is running, make sure it aborts. | 1021 | * if recovery is running, make sure it aborts. |
1022 | */ | 1022 | */ |
1023 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 1023 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1024 | } | 1024 | } |
1025 | set_bit(Faulty, &rdev->flags); | 1025 | set_bit(Faulty, &rdev->flags); |
1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1026 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
@@ -1171,6 +1171,14 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
1171 | err = -EBUSY; | 1171 | err = -EBUSY; |
1172 | goto abort; | 1172 | goto abort; |
1173 | } | 1173 | } |
1174 | /* Only remove faulty devices in recovery | ||
1175 | * is not possible. | ||
1176 | */ | ||
1177 | if (!test_bit(Faulty, &rdev->flags) && | ||
1178 | enough(conf)) { | ||
1179 | err = -EBUSY; | ||
1180 | goto abort; | ||
1181 | } | ||
1174 | p->rdev = NULL; | 1182 | p->rdev = NULL; |
1175 | synchronize_rcu(); | 1183 | synchronize_rcu(); |
1176 | if (atomic_read(&rdev->nr_pending)) { | 1184 | if (atomic_read(&rdev->nr_pending)) { |
@@ -1237,6 +1245,7 @@ static void end_sync_write(struct bio *bio, int error) | |||
1237 | 1245 | ||
1238 | if (!uptodate) | 1246 | if (!uptodate) |
1239 | md_error(mddev, conf->mirrors[d].rdev); | 1247 | md_error(mddev, conf->mirrors[d].rdev); |
1248 | |||
1240 | update_head_pos(i, r10_bio); | 1249 | update_head_pos(i, r10_bio); |
1241 | 1250 | ||
1242 | while (atomic_dec_and_test(&r10_bio->remaining)) { | 1251 | while (atomic_dec_and_test(&r10_bio->remaining)) { |
@@ -1844,7 +1853,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1844 | if (rb2) | 1853 | if (rb2) |
1845 | atomic_dec(&rb2->remaining); | 1854 | atomic_dec(&rb2->remaining); |
1846 | r10_bio = rb2; | 1855 | r10_bio = rb2; |
1847 | if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) | 1856 | if (!test_and_set_bit(MD_RECOVERY_INTR, |
1857 | &mddev->recovery)) | ||
1848 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", | 1858 | printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", |
1849 | mdname(mddev)); | 1859 | mdname(mddev)); |
1850 | break; | 1860 | break; |
@@ -2082,6 +2092,9 @@ static int run(mddev_t *mddev) | |||
2082 | goto out_free_conf; | 2092 | goto out_free_conf; |
2083 | } | 2093 | } |
2084 | 2094 | ||
2095 | spin_lock_init(&conf->device_lock); | ||
2096 | mddev->queue->queue_lock = &conf->device_lock; | ||
2097 | |||
2085 | rdev_for_each(rdev, tmp, mddev) { | 2098 | rdev_for_each(rdev, tmp, mddev) { |
2086 | disk_idx = rdev->raid_disk; | 2099 | disk_idx = rdev->raid_disk; |
2087 | if (disk_idx >= mddev->raid_disks | 2100 | if (disk_idx >= mddev->raid_disks |
@@ -2103,7 +2116,6 @@ static int run(mddev_t *mddev) | |||
2103 | 2116 | ||
2104 | disk->head_position = 0; | 2117 | disk->head_position = 0; |
2105 | } | 2118 | } |
2106 | spin_lock_init(&conf->device_lock); | ||
2107 | INIT_LIST_HEAD(&conf->retry_list); | 2119 | INIT_LIST_HEAD(&conf->retry_list); |
2108 | 2120 | ||
2109 | spin_lock_init(&conf->resync_lock); | 2121 | spin_lock_init(&conf->resync_lock); |