diff options
author | NeilBrown <neilb@suse.de> | 2011-05-11 00:38:44 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-05-11 00:38:44 -0400 |
commit | 6f8d0c77cef5849433dd7beb0bd97e573cc4a6a3 (patch) | |
tree | 42d3a4438d035dfd792758c40cbd39317166b1c8 /drivers/md | |
parent | 92f861a72a273ed038c1e22ff9775456353e3009 (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')
-rw-r--r-- | drivers/md/multipath.c | 40 | ||||
-rw-r--r-- | drivers/md/raid5.c | 38 |
2 files changed, 40 insertions, 38 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); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 49bf5f891435..51af7f3bfe52 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1700,27 +1700,25 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1700 | raid5_conf_t *conf = mddev->private; | 1700 | raid5_conf_t *conf = mddev->private; |
1701 | pr_debug("raid456: error called\n"); | 1701 | pr_debug("raid456: error called\n"); |
1702 | 1702 | ||
1703 | if (!test_bit(Faulty, &rdev->flags)) { | 1703 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
1704 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 1704 | unsigned long flags; |
1705 | if (test_and_clear_bit(In_sync, &rdev->flags)) { | 1705 | spin_lock_irqsave(&conf->device_lock, flags); |
1706 | unsigned long flags; | 1706 | mddev->degraded++; |
1707 | spin_lock_irqsave(&conf->device_lock, flags); | 1707 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1708 | mddev->degraded++; | 1708 | /* |
1709 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1709 | * if recovery was running, make sure it aborts. |
1710 | /* | 1710 | */ |
1711 | * if recovery was running, make sure it aborts. | 1711 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
1712 | */ | ||
1713 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | ||
1714 | } | ||
1715 | set_bit(Faulty, &rdev->flags); | ||
1716 | printk(KERN_ALERT | ||
1717 | "md/raid:%s: Disk failure on %s, disabling device.\n" | ||
1718 | "md/raid:%s: Operation continuing on %d devices.\n", | ||
1719 | mdname(mddev), | ||
1720 | bdevname(rdev->bdev, b), | ||
1721 | mdname(mddev), | ||
1722 | conf->raid_disks - mddev->degraded); | ||
1723 | } | 1712 | } |
1713 | set_bit(Faulty, &rdev->flags); | ||
1714 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
1715 | printk(KERN_ALERT | ||
1716 | "md/raid:%s: Disk failure on %s, disabling device.\n" | ||
1717 | "md/raid:%s: Operation continuing on %d devices.\n", | ||
1718 | mdname(mddev), | ||
1719 | bdevname(rdev->bdev, b), | ||
1720 | mdname(mddev), | ||
1721 | conf->raid_disks - mddev->degraded); | ||
1724 | } | 1722 | } |
1725 | 1723 | ||
1726 | /* | 1724 | /* |