Commit cd15fb64 authored by Mike Snitzer's avatar Mike Snitzer

Revert "dm mirror: use all available legs on multiple failures"

This reverts commit 12a7cf5b.

This commit apparently attempted to fix an issue that didn't really
exist, furthermore: this commit is the source of deadlocks and crashes
seen in multiple cases related to failing the primary mirror dev while
syncing.
Reported-by: default avatarJonathan Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 2ad50606
...@@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list) ...@@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)
struct dm_raid1_bio_record { struct dm_raid1_bio_record {
struct mirror *m; struct mirror *m;
/* if details->bi_bdev == NULL, details were not saved */
struct dm_bio_details details; struct dm_bio_details details;
region_t write_region; region_t write_region;
}; };
...@@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio) ...@@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
struct dm_raid1_bio_record *bio_record = struct dm_raid1_bio_record *bio_record =
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
bio_record->details.bi_bdev = NULL;
if (rw == WRITE) { if (rw == WRITE) {
/* Save region for mirror_end_io() handler */ /* Save region for mirror_end_io() handler */
bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
...@@ -1256,12 +1259,22 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) ...@@ -1256,12 +1259,22 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
} }
if (error == -EOPNOTSUPP) if (error == -EOPNOTSUPP)
return error; goto out;
if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD)) if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
return error; goto out;
if (unlikely(error)) { if (unlikely(error)) {
if (!bio_record->details.bi_bdev) {
/*
* There wasn't enough memory to record necessary
* information for a retry or there was no other
* mirror in-sync.
*/
DMERR_LIMIT("Mirror read failed.");
return -EIO;
}
m = bio_record->m; m = bio_record->m;
DMERR("Mirror read failed from %s. Trying alternative device.", DMERR("Mirror read failed from %s. Trying alternative device.",
...@@ -1277,6 +1290,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) ...@@ -1277,6 +1290,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
bd = &bio_record->details; bd = &bio_record->details;
dm_bio_restore(bd, bio); dm_bio_restore(bd, bio);
bio_record->details.bi_bdev = NULL;
bio->bi_error = 0; bio->bi_error = 0;
queue_bio(ms, bio, rw); queue_bio(ms, bio, rw);
...@@ -1285,6 +1299,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) ...@@ -1285,6 +1299,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
DMERR("All replicated volumes dead, failing I/O"); DMERR("All replicated volumes dead, failing I/O");
} }
out:
bio_record->details.bi_bdev = NULL;
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment