summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-02-06 15:06:47 +1100
committerNeilBrown <neilb@suse.de>2009-02-06 15:06:47 +1100
commit4706b349f4a8312d31b3d0cf61fe721699356920 (patch)
tree86c0ee896722e45e324a97b704c0419fbb968d4a /drivers
parenteda58a85ec3fc05855a26654d97a2b53f0e715b9 (diff)
downloadlinux-4706b349f4a8312d31b3d0cf61fe721699356920.tar.gz
md: Allow read error in a single drive raid1 to be passed up.
If a raid1 only has a single working device and gets a read error, 
we choose to simply return that error up to the filesystem (or whatever)
rather than failing the whole array.

However the codes doesn't quite do that.  We attempt a readbalance
which allocates the same drive, so we retry the read - indefinitely. 

Instead:  If read_balance in the error case chooses the same drive that just
failed, treat it as a failure and don't retry.

Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid1.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 7b4f5f7155d8..01e3cffd03b8 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1640,7 +1640,8 @@ static void raid1d(mddev_t *mddev)
 			}
 
 			bio = r1_bio->bios[r1_bio->read_disk];
-			if ((disk=read_balance(conf, r1_bio)) == -1) {
+			if ((disk=read_balance(conf, r1_bio)) == -1 ||
+			    disk == r1_bio->read_disk) {
 				printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
 				       " read error for block %llu\n",
 				       bdevname(bio->bi_bdev,b),