diff options
author | Mike Snitzer <snitzer@redhat.com> | 2017-06-15 08:39:15 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2017-06-15 08:39:15 -0400 |
commit | cd15fb64ee56192760ad5c1e2ad97a65e735b18b (patch) | |
tree | 971d9033cab38cf860c72d081e57922416ca5b21 | |
parent | 2ad50606f847a902303a5364b7cad64bdd6246f6 (diff) |
Revert "dm mirror: use all available legs on multiple failures"
This reverts commit 12a7cf5ba6c776a2621d8972c7d42e8d3d959d20.
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>
-rw-r--r-- | drivers/md/dm-raid1.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index e61c45047c25..4da8858856fb 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -145,6 +145,7 @@ static void dispatch_bios(void *context, struct bio_list *bio_list) | |||
145 | 145 | ||
146 | struct dm_raid1_bio_record { | 146 | struct dm_raid1_bio_record { |
147 | struct mirror *m; | 147 | struct mirror *m; |
148 | /* if details->bi_bdev == NULL, details were not saved */ | ||
148 | struct dm_bio_details details; | 149 | struct dm_bio_details details; |
149 | region_t write_region; | 150 | region_t write_region; |
150 | }; | 151 | }; |
@@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio) | |||
1198 | struct dm_raid1_bio_record *bio_record = | 1199 | struct dm_raid1_bio_record *bio_record = |
1199 | dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); | 1200 | dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); |
1200 | 1201 | ||
1202 | bio_record->details.bi_bdev = NULL; | ||
1203 | |||
1201 | if (rw == WRITE) { | 1204 | if (rw == WRITE) { |
1202 | /* Save region for mirror_end_io() handler */ | 1205 | /* Save region for mirror_end_io() handler */ |
1203 | bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); | 1206 | 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 | } | 1259 | } |
1257 | 1260 | ||
1258 | if (error == -EOPNOTSUPP) | 1261 | if (error == -EOPNOTSUPP) |
1259 | return error; | 1262 | goto out; |
1260 | 1263 | ||
1261 | if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD)) | 1264 | if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD)) |
1262 | return error; | 1265 | goto out; |
1263 | 1266 | ||
1264 | if (unlikely(error)) { | 1267 | if (unlikely(error)) { |
1268 | if (!bio_record->details.bi_bdev) { | ||
1269 | /* | ||
1270 | * There wasn't enough memory to record necessary | ||
1271 | * information for a retry or there was no other | ||
1272 | * mirror in-sync. | ||
1273 | */ | ||
1274 | DMERR_LIMIT("Mirror read failed."); | ||
1275 | return -EIO; | ||
1276 | } | ||
1277 | |||
1265 | m = bio_record->m; | 1278 | m = bio_record->m; |
1266 | 1279 | ||
1267 | DMERR("Mirror read failed from %s. Trying alternative device.", | 1280 | 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 | bd = &bio_record->details; | 1290 | bd = &bio_record->details; |
1278 | 1291 | ||
1279 | dm_bio_restore(bd, bio); | 1292 | dm_bio_restore(bd, bio); |
1293 | bio_record->details.bi_bdev = NULL; | ||
1280 | bio->bi_error = 0; | 1294 | bio->bi_error = 0; |
1281 | 1295 | ||
1282 | queue_bio(ms, bio, rw); | 1296 | queue_bio(ms, bio, rw); |
@@ -1285,6 +1299,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) | |||
1285 | DMERR("All replicated volumes dead, failing I/O"); | 1299 | DMERR("All replicated volumes dead, failing I/O"); |
1286 | } | 1300 | } |
1287 | 1301 | ||
1302 | out: | ||
1303 | bio_record->details.bi_bdev = NULL; | ||
1304 | |||
1288 | return error; | 1305 | return error; |
1289 | } | 1306 | } |
1290 | 1307 | ||