aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/multipath.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-05-11 00:38:44 -0400
committerNeilBrown <neilb@suse.de>2011-05-11 00:38:44 -0400
commit6f8d0c77cef5849433dd7beb0bd97e573cc4a6a3 (patch)
tree42d3a4438d035dfd792758c40cbd39317166b1c8 /drivers/md/multipath.c
parent92f861a72a273ed038c1e22ff9775456353e3009 (diff)
md: make error_handler functions more uniform and correct.
- there is no need to test_bit Faulty, as that was already done in md_error which is the only caller of these functions. - MD_CHANGE_DEVS should be set *after* faulty is set to ensure metadata is updated correctly. - spinlock should be held while updating ->degraded. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/multipath.c')
-rw-r--r--drivers/md/multipath.c40
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)
186static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev) 186static 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
219static void print_multipath_conf (multipath_conf_t *conf) 221static 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);