diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-20 14:51:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-20 14:51:22 -0400 |
| commit | 935173744abe86278074ad8f131c1932276b1ac1 (patch) | |
| tree | 636ddb34b7b16fba57fb8e0e85f4e81c0d045c7f | |
| parent | ce9f8d6b39b0d8f62092477b8d96a835860fb45a (diff) | |
| parent | 7c8d3a42fe1c58a7e8fd3f6a013e7d7b474ff931 (diff) | |
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
| -rw-r--r-- | drivers/md/dm-raid1.c | 3 | ||||
| -rw-r--r-- | drivers/md/dm-region-hash.c | 5 | ||||
| -rw-r--r-- | drivers/md/dm-thin.c | 6 |
3 files changed, 11 insertions, 3 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d039de8322f0..b58b7a33914a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
| @@ -1084,6 +1084,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
| 1084 | ti->split_io = dm_rh_get_region_size(ms->rh); | 1084 | ti->split_io = dm_rh_get_region_size(ms->rh); |
| 1085 | ti->num_flush_requests = 1; | 1085 | ti->num_flush_requests = 1; |
| 1086 | ti->num_discard_requests = 1; | 1086 | ti->num_discard_requests = 1; |
| 1087 | ti->discard_zeroes_data_unsupported = 1; | ||
| 1087 | 1088 | ||
| 1088 | ms->kmirrord_wq = alloc_workqueue("kmirrord", | 1089 | ms->kmirrord_wq = alloc_workqueue("kmirrord", |
| 1089 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); | 1090 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); |
| @@ -1214,7 +1215,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
| 1214 | * We need to dec pending if this was a write. | 1215 | * We need to dec pending if this was a write. |
| 1215 | */ | 1216 | */ |
| 1216 | if (rw == WRITE) { | 1217 | if (rw == WRITE) { |
| 1217 | if (!(bio->bi_rw & REQ_FLUSH)) | 1218 | if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) |
| 1218 | dm_rh_dec(ms->rh, map_context->ll); | 1219 | dm_rh_dec(ms->rh, map_context->ll); |
| 1219 | return error; | 1220 | return error; |
| 1220 | } | 1221 | } |
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 7771ed212182..69732e03eb34 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c | |||
| @@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) | |||
| 404 | return; | 404 | return; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | if (bio->bi_rw & REQ_DISCARD) | ||
| 408 | return; | ||
| 409 | |||
| 407 | /* We must inform the log that the sync count has changed. */ | 410 | /* We must inform the log that the sync count has changed. */ |
| 408 | log->type->set_region_sync(log, region, 0); | 411 | log->type->set_region_sync(log, region, 0); |
| 409 | 412 | ||
| @@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) | |||
| 524 | struct bio *bio; | 527 | struct bio *bio; |
| 525 | 528 | ||
| 526 | for (bio = bios->head; bio; bio = bio->bi_next) { | 529 | for (bio = bios->head; bio; bio = bio->bi_next) { |
| 527 | if (bio->bi_rw & REQ_FLUSH) | 530 | if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) |
| 528 | continue; | 531 | continue; |
| 529 | rh_inc(rh, dm_rh_bio_to_region(rh, bio)); | 532 | rh_inc(rh, dm_rh_bio_to_region(rh, bio)); |
| 530 | } | 533 | } |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ce59824fb414..68694da0d21d 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
| @@ -1245,7 +1245,10 @@ static void process_discard(struct thin_c *tc, struct bio *bio) | |||
| 1245 | 1245 | ||
| 1246 | cell_release_singleton(cell, bio); | 1246 | cell_release_singleton(cell, bio); |
| 1247 | cell_release_singleton(cell2, bio); | 1247 | cell_release_singleton(cell2, bio); |
| 1248 | remap_and_issue(tc, bio, lookup_result.block); | 1248 | if ((!lookup_result.shared) && pool->pf.discard_passdown) |
| 1249 | remap_and_issue(tc, bio, lookup_result.block); | ||
| 1250 | else | ||
| 1251 | bio_endio(bio, 0); | ||
| 1249 | } | 1252 | } |
| 1250 | break; | 1253 | break; |
| 1251 | 1254 | ||
| @@ -2628,6 +2631,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
| 2628 | if (tc->pool->pf.discard_enabled) { | 2631 | if (tc->pool->pf.discard_enabled) { |
| 2629 | ti->discards_supported = 1; | 2632 | ti->discards_supported = 1; |
| 2630 | ti->num_discard_requests = 1; | 2633 | ti->num_discard_requests = 1; |
| 2634 | ti->discard_zeroes_data_unsupported = 1; | ||
| 2631 | } | 2635 | } |
| 2632 | 2636 | ||
| 2633 | dm_put(pool_md); | 2637 | dm_put(pool_md); |
