Skip to content

Commit

Permalink
Revert "dm mirror: use all available legs on multiple failures"
Browse files Browse the repository at this point in the history
This reverts commit 12a7cf5.

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: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
  • Loading branch information
Mike Snitzer committed Jun 15, 2017
1 parent 2ad5060 commit cd15fb6
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list)

struct dm_raid1_bio_record {
struct mirror *m;
/* if details->bi_bdev == NULL, details were not saved */
struct dm_bio_details details;
region_t write_region;
};
Expand Down Expand Up @@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
struct dm_raid1_bio_record *bio_record =
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));

bio_record->details.bi_bdev = NULL;

if (rw == WRITE) {
/* Save region for mirror_end_io() handler */
bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
Expand Down Expand Up @@ -1256,12 +1259,22 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
}

if (error == -EOPNOTSUPP)
return error;
goto out;

if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
return error;
goto out;

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;

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

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

queue_bio(ms, bio, rw);
Expand All @@ -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");
}

out:
bio_record->details.bi_bdev = NULL;

return error;
}

Expand Down

0 comments on commit cd15fb6

Please sign in to comment.