Skip to content

Commit 12a7cf5

Browse files
mauelshasnitm
authored andcommitted
dm mirror: use all available legs on multiple failures
When any leg(s) have failed, any read will cause a new operational default leg to be selected and the read is resubmitted to it. If that new default leg fails the read too, no other still accessible legs are used to resubmit the read again -- thus failing the io. Fix by allowing the read to get resubmitted until all operational legs have been exhausted. Also, remove any details.bi_dev use as a flag. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent dcb2ff5 commit 12a7cf5

File tree

1 file changed

+2
-19
lines changed

1 file changed

+2
-19
lines changed

drivers/md/dm-raid1.c

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)
145145

146146
struct dm_raid1_bio_record {
147147
struct mirror *m;
148-
/* if details->bi_bdev == NULL, details were not saved */
149148
struct dm_bio_details details;
150149
region_t write_region;
151150
};
@@ -1200,8 +1199,6 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
12001199
struct dm_raid1_bio_record *bio_record =
12011200
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
12021201

1203-
bio_record->details.bi_bdev = NULL;
1204-
12051202
if (rw == WRITE) {
12061203
/* Save region for mirror_end_io() handler */
12071204
bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
@@ -1260,22 +1257,12 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
12601257
}
12611258

12621259
if (error == -EOPNOTSUPP)
1263-
goto out;
1260+
return error;
12641261

12651262
if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
1266-
goto out;
1263+
return error;
12671264

12681265
if (unlikely(error)) {
1269-
if (!bio_record->details.bi_bdev) {
1270-
/*
1271-
* There wasn't enough memory to record necessary
1272-
* information for a retry or there was no other
1273-
* mirror in-sync.
1274-
*/
1275-
DMERR_LIMIT("Mirror read failed.");
1276-
return -EIO;
1277-
}
1278-
12791266
m = bio_record->m;
12801267

12811268
DMERR("Mirror read failed from %s. Trying alternative device.",
@@ -1291,7 +1278,6 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
12911278
bd = &bio_record->details;
12921279

12931280
dm_bio_restore(bd, bio);
1294-
bio_record->details.bi_bdev = NULL;
12951281
bio->bi_error = 0;
12961282

12971283
queue_bio(ms, bio, rw);
@@ -1300,9 +1286,6 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
13001286
DMERR("All replicated volumes dead, failing I/O");
13011287
}
13021288

1303-
out:
1304-
bio_record->details.bi_bdev = NULL;
1305-
13061289
return error;
13071290
}
13081291

0 commit comments

Comments
 (0)