forked from Minki/linux
Three fixes for device-mapper discard processing:
- avoid a crash in dm-raid1 when discards coincide with mirror recovery; - avoid discarding shared data that's still needed in dm-thin; - don't guarantee that discarded blocks will be wiped in dm-raid1. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJQCV8qAAoJEK2W1qbAHj1niSAP/2K0RkgWvL0hwuaM+us0oh29 XFou6Tb9pH+//QfKOJuClHeSfZFoHYuevvJPtwTqPlHGONE2YXeBtVmyp0k+BS69 xoaQy+OoZFrEbhxyJFrg+lDcxVGRtvo7x9zegeRf++o/skRfRgAjzyLkI8bk4t3v c3vSDTVBikJXlTxa+J7EQpeW29DBiky+tIHQQx0+98u2VSlaFFP6MdLr1ROeq7yF +z3kEXk6qzwL9ZHTWuVCvhi7bw4i18UTrH0wxZuUXWRpz+Va5h7w+/zcQbau6D/s K+BmlAW/fxzZOW4guFU6pCLlVGU4BsJxUXT55UaP4Dx9UuV59EtIPsDb8/Y/pGMX t9xnC4GmSOjw52pW2VR2gUJwG/c5mJ9g/mdP6twQzcC4JJ+CYg4Q5lH88qzDqceS VCrW681nIKIVoja5n1adv6gbZax8hlR/z8ElXrqELDmXk7nKBLOLdDVSXzZ9ceX1 RnvtAZE/zrxcslKHw52Sd37c8YRer/fgx3kQxhXd1nb096DgiWvE/taD/ixjWHQX Eu1KrQIelvw63/BNNTKYRF7xS0dGKsGNaXWln7cMONG28CnrWG/8f+mp+KG73x5e Fc8yCONHNbqmf95yx1N0MgfYlZFjBBw0+BtqmR7QVcnG3r4SaSug+F72SPb5nN/B ZBmwNcSBaaC952+5pMZa =gbLp -----END PGP SIGNATURE----- Merge tag 'dm-3.5-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm Pull device-mapper discard fixes from Alasdair G Kergon: - avoid a crash in dm-raid1 when discards coincide with mirror recovery; - avoid discarding shared data that's still needed in dm-thin; - don't guarantee that discarded blocks will be wiped in dm-raid1. * tag 'dm-3.5-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm: dm raid1: set discard_zeroes_data_unsupported dm thin: do not send discards to shared blocks dm raid1: fix crash with mirror recovery and discard
This commit is contained in:
commit
935173744a
@ -1084,6 +1084,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||
ti->split_io = dm_rh_get_region_size(ms->rh);
|
||||
ti->num_flush_requests = 1;
|
||||
ti->num_discard_requests = 1;
|
||||
ti->discard_zeroes_data_unsupported = 1;
|
||||
|
||||
ms->kmirrord_wq = alloc_workqueue("kmirrord",
|
||||
WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
|
||||
@ -1214,7 +1215,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
|
||||
* We need to dec pending if this was a write.
|
||||
*/
|
||||
if (rw == WRITE) {
|
||||
if (!(bio->bi_rw & REQ_FLUSH))
|
||||
if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)))
|
||||
dm_rh_dec(ms->rh, map_context->ll);
|
||||
return error;
|
||||
}
|
||||
|
@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
|
||||
return;
|
||||
}
|
||||
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
return;
|
||||
|
||||
/* We must inform the log that the sync count has changed. */
|
||||
log->type->set_region_sync(log, region, 0);
|
||||
|
||||
@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
|
||||
struct bio *bio;
|
||||
|
||||
for (bio = bios->head; bio; bio = bio->bi_next) {
|
||||
if (bio->bi_rw & REQ_FLUSH)
|
||||
if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))
|
||||
continue;
|
||||
rh_inc(rh, dm_rh_bio_to_region(rh, bio));
|
||||
}
|
||||
|
@ -1245,7 +1245,10 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
|
||||
|
||||
cell_release_singleton(cell, bio);
|
||||
cell_release_singleton(cell2, bio);
|
||||
remap_and_issue(tc, bio, lookup_result.block);
|
||||
if ((!lookup_result.shared) && pool->pf.discard_passdown)
|
||||
remap_and_issue(tc, bio, lookup_result.block);
|
||||
else
|
||||
bio_endio(bio, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2628,6 +2631,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||
if (tc->pool->pf.discard_enabled) {
|
||||
ti->discards_supported = 1;
|
||||
ti->num_discard_requests = 1;
|
||||
ti->discard_zeroes_data_unsupported = 1;
|
||||
}
|
||||
|
||||
dm_put(pool_md);
|
||||
|
Loading…
Reference in New Issue
Block a user