aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-integrity.c12
-rw-r--r--drivers/md/dm-io.c4
-rw-r--r--drivers/md/dm-raid1.c21
3 files changed, 31 insertions, 6 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 7910bfe50da4..93b181088168 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -1105,10 +1105,13 @@ static void schedule_autocommit(struct dm_integrity_c *ic)
1105static void submit_flush_bio(struct dm_integrity_c *ic, struct dm_integrity_io *dio) 1105static void submit_flush_bio(struct dm_integrity_c *ic, struct dm_integrity_io *dio)
1106{ 1106{
1107 struct bio *bio; 1107 struct bio *bio;
1108 spin_lock_irq(&ic->endio_wait.lock); 1108 unsigned long flags;
1109
1110 spin_lock_irqsave(&ic->endio_wait.lock, flags);
1109 bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); 1111 bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io));
1110 bio_list_add(&ic->flush_bio_list, bio); 1112 bio_list_add(&ic->flush_bio_list, bio);
1111 spin_unlock_irq(&ic->endio_wait.lock); 1113 spin_unlock_irqrestore(&ic->endio_wait.lock, flags);
1114
1112 queue_work(ic->commit_wq, &ic->commit_work); 1115 queue_work(ic->commit_wq, &ic->commit_work);
1113} 1116}
1114 1117
@@ -3040,6 +3043,11 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
3040 ti->error = "The device is too small"; 3043 ti->error = "The device is too small";
3041 goto bad; 3044 goto bad;
3042 } 3045 }
3046 if (ti->len > ic->provided_data_sectors) {
3047 r = -EINVAL;
3048 ti->error = "Not enough provided sectors for requested mapping size";
3049 goto bad;
3050 }
3043 3051
3044 if (!buffer_sectors) 3052 if (!buffer_sectors)
3045 buffer_sectors = 1; 3053 buffer_sectors = 1;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 3702e502466d..8d5ca30f6551 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -317,8 +317,8 @@ static void do_region(int op, int op_flags, unsigned region,
317 else if (op == REQ_OP_WRITE_SAME) 317 else if (op == REQ_OP_WRITE_SAME)
318 special_cmd_max_sectors = q->limits.max_write_same_sectors; 318 special_cmd_max_sectors = q->limits.max_write_same_sectors;
319 if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES || 319 if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES ||
320 op == REQ_OP_WRITE_SAME) && 320 op == REQ_OP_WRITE_SAME) && special_cmd_max_sectors == 0) {
321 special_cmd_max_sectors == 0) { 321 atomic_inc(&io->count);
322 dec_count(io, region, -EOPNOTSUPP); 322 dec_count(io, region, -EOPNOTSUPP);
323 return; 323 return;
324 } 324 }
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
146struct dm_raid1_bio_record { 146struct 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
1302out:
1303 bio_record->details.bi_bdev = NULL;
1304
1288 return error; 1305 return error;
1289} 1306}
1290 1307