Skip to content

Commit cd15fb6

Browse files
committed
Revert "dm mirror: use all available legs on multiple failures"
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>
1 parent 2ad5060 commit cd15fb6

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

drivers/md/dm-raid1.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ 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 */
148149
struct dm_bio_details details;
149150
region_t write_region;
150151
};
@@ -1198,6 +1199,8 @@ static int mirror_map(struct dm_target *ti, struct bio *bio)
11981199
struct dm_raid1_bio_record *bio_record =
11991200
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
12001201

1202+
bio_record->details.bi_bdev = NULL;
1203+
12011204
if (rw == WRITE) {
12021205
/* Save region for mirror_end_io() handler */
12031206
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)
12561259
}
12571260

12581261
if (error == -EOPNOTSUPP)
1259-
return error;
1262+
goto out;
12601263

12611264
if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
1262-
return error;
1265+
goto out;
12631266

12641267
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+
12651278
m = bio_record->m;
12661279

12671280
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)
12771290
bd = &bio_record->details;
12781291

12791292
dm_bio_restore(bd, bio);
1293+
bio_record->details.bi_bdev = NULL;
12801294
bio->bi_error = 0;
12811295

12821296
queue_bio(ms, bio, rw);
@@ -1285,6 +1299,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
12851299
DMERR("All replicated volumes dead, failing I/O");
12861300
}
12871301

1302+
out:
1303+
bio_record->details.bi_bdev = NULL;
1304+
12881305
return error;
12891306
}
12901307

0 commit comments

Comments
 (0)