Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-4.12/dm-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:

- a revert of a DM mirror commit that has proven to make the code prone
to crash

- a DM io reference count fix that resolves a NULL pointer seen when
issuing discards to a DM mirror target's device whose mirror legs do
not all support discards

- a couple DM integrity fixes

* tag 'for-4.12/dm-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm io: fix duplicate bio completion due to missing ref count
dm integrity: fix to not disable/enable interrupts from interrupt context
Revert "dm mirror: use all available legs on multiple failures"
dm integrity: reject mappings too large for device

+31 -6
+10 -2
drivers/md/dm-integrity.c
··· 1105 1105 static void submit_flush_bio(struct dm_integrity_c *ic, struct dm_integrity_io *dio) 1106 1106 { 1107 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 1111 bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); 1110 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 1115 queue_work(ic->commit_wq, &ic->commit_work); 1113 1116 } 1114 1117 ··· 3041 3038 r = calculate_device_limits(ic); 3042 3039 if (r) { 3043 3040 ti->error = "The device is too small"; 3041 + goto bad; 3042 + } 3043 + if (ti->len > ic->provided_data_sectors) { 3044 + r = -EINVAL; 3045 + ti->error = "Not enough provided sectors for requested mapping size"; 3044 3046 goto bad; 3045 3047 } 3046 3048
+2 -2
drivers/md/dm-io.c
··· 317 317 else if (op == REQ_OP_WRITE_SAME) 318 318 special_cmd_max_sectors = q->limits.max_write_same_sectors; 319 319 if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES || 320 - op == REQ_OP_WRITE_SAME) && 321 - special_cmd_max_sectors == 0) { 320 + op == REQ_OP_WRITE_SAME) && special_cmd_max_sectors == 0) { 321 + atomic_inc(&io->count); 322 322 dec_count(io, region, -EOPNOTSUPP); 323 323 return; 324 324 }
+19 -2
drivers/md/dm-raid1.c
··· 145 145 146 146 struct dm_raid1_bio_record { 147 147 struct mirror *m; 148 + /* if details->bi_bdev == NULL, details were not saved */ 148 149 struct dm_bio_details details; 149 150 region_t write_region; 150 151 }; ··· 1199 1198 struct dm_raid1_bio_record *bio_record = 1200 1199 dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); 1201 1200 1201 + bio_record->details.bi_bdev = NULL; 1202 + 1202 1203 if (rw == WRITE) { 1203 1204 /* Save region for mirror_end_io() handler */ 1204 1205 bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); ··· 1259 1256 } 1260 1257 1261 1258 if (error == -EOPNOTSUPP) 1262 - return error; 1259 + goto out; 1263 1260 1264 1261 if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD)) 1265 - return error; 1262 + goto out; 1266 1263 1267 1264 if (unlikely(error)) { 1265 + if (!bio_record->details.bi_bdev) { 1266 + /* 1267 + * There wasn't enough memory to record necessary 1268 + * information for a retry or there was no other 1269 + * mirror in-sync. 1270 + */ 1271 + DMERR_LIMIT("Mirror read failed."); 1272 + return -EIO; 1273 + } 1274 + 1268 1275 m = bio_record->m; 1269 1276 1270 1277 DMERR("Mirror read failed from %s. Trying alternative device.", ··· 1290 1277 bd = &bio_record->details; 1291 1278 1292 1279 dm_bio_restore(bd, bio); 1280 + bio_record->details.bi_bdev = NULL; 1293 1281 bio->bi_error = 0; 1294 1282 1295 1283 queue_bio(ms, bio, rw); ··· 1298 1284 } 1299 1285 DMERR("All replicated volumes dead, failing I/O"); 1300 1286 } 1287 + 1288 + out: 1289 + bio_record->details.bi_bdev = NULL; 1301 1290 1302 1291 return error; 1303 1292 }