diff options
Diffstat (limited to 'drivers/md/multipath.c')
-rw-r--r-- | drivers/md/multipath.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 02547124aa83..3535c23af288 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -186,6 +186,7 @@ static int multipath_congested(void *data, int bits) | |||
186 | static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) | 186 | static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) |
187 | { | 187 | { |
188 | multipath_conf_t *conf = mddev->private; | 188 | multipath_conf_t *conf = mddev->private; |
189 | char b[BDEVNAME_SIZE]; | ||
189 | 190 | ||
190 | if (conf->raid_disks - mddev->degraded <= 1) { | 191 | if (conf->raid_disks - mddev->degraded <= 1) { |
191 | /* | 192 | /* |
@@ -194,26 +195,27 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) | |||
194 | * which has just failed. | 195 | * which has just failed. |
195 | */ | 196 | */ |
196 | printk(KERN_ALERT | 197 | printk(KERN_ALERT |
197 | "multipath: only one IO path left and IO error.\n"); | 198 | "multipath: only one IO path left and IO error.\n"); |
198 | /* leave it active... it's all we have */ | 199 | /* leave it active... it's all we have */ |
199 | } else { | 200 | return; |
200 | /* | 201 | } |
201 | * Mark disk as unusable | 202 | /* |
202 | */ | 203 | * Mark disk as unusable |
203 | if (!test_bit(Faulty, &rdev->flags)) { | 204 | */ |
204 | char b[BDEVNAME_SIZE]; | 205 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
205 | clear_bit(In_sync, &rdev->flags); | 206 | unsigned long flags; |
206 | set_bit(Faulty, &rdev->flags); | 207 | spin_lock_irqsave(&conf->device_lock, flags); |
207 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 208 | mddev->degraded++; |
208 | mddev->degraded++; | 209 | spin_unlock_irqrestore(&conf->device_lock, flags); |
209 | printk(KERN_ALERT "multipath: IO failure on %s," | ||
210 | " disabling IO path.\n" | ||
211 | "multipath: Operation continuing" | ||
212 | " on %d IO paths.\n", | ||
213 | bdevname (rdev->bdev,b), | ||
214 | conf->raid_disks - mddev->degraded); | ||
215 | } | ||
216 | } | 210 | } |
211 | set_bit(Faulty, &rdev->flags); | ||
212 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
213 | printk(KERN_ALERT "multipath: IO failure on %s," | ||
214 | " disabling IO path.\n" | ||
215 | "multipath: Operation continuing" | ||
216 | " on %d IO paths.\n", | ||
217 | bdevname(rdev->bdev, b), | ||
218 | conf->raid_disks - mddev->degraded); | ||
217 | } | 219 | } |
218 | 220 | ||
219 | static void print_multipath_conf (multipath_conf_t *conf) | 221 | static void print_multipath_conf (multipath_conf_t *conf) |
@@ -273,9 +275,11 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
273 | PAGE_CACHE_SIZE - 1); | 275 | PAGE_CACHE_SIZE - 1); |
274 | } | 276 | } |
275 | 277 | ||
278 | spin_lock_irq(&conf->device_lock); | ||
276 | mddev->degraded--; | 279 | mddev->degraded--; |
277 | rdev->raid_disk = path; | 280 | rdev->raid_disk = path; |
278 | set_bit(In_sync, &rdev->flags); | 281 | set_bit(In_sync, &rdev->flags); |
282 | spin_unlock_irq(&conf->device_lock); | ||
279 | rcu_assign_pointer(p->rdev, rdev); | 283 | rcu_assign_pointer(p->rdev, rdev); |
280 | err = 0; | 284 | err = 0; |
281 | md_integrity_add_rdev(rdev, mddev); | 285 | md_integrity_add_rdev(rdev, mddev); |