提交 93517374 编写于 作者: L Linus Torvalds

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
...@@ -1084,6 +1084,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) ...@@ -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->split_io = dm_rh_get_region_size(ms->rh);
ti->num_flush_requests = 1; ti->num_flush_requests = 1;
ti->num_discard_requests = 1; ti->num_discard_requests = 1;
ti->discard_zeroes_data_unsupported = 1;
ms->kmirrord_wq = alloc_workqueue("kmirrord", ms->kmirrord_wq = alloc_workqueue("kmirrord",
WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
...@@ -1214,7 +1215,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, ...@@ -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. * We need to dec pending if this was a write.
*/ */
if (rw == 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); dm_rh_dec(ms->rh, map_context->ll);
return error; return error;
} }
......
...@@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) ...@@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
return; return;
} }
if (bio->bi_rw & REQ_DISCARD)
return;
/* We must inform the log that the sync count has changed. */ /* We must inform the log that the sync count has changed. */
log->type->set_region_sync(log, region, 0); 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) ...@@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
struct bio *bio; struct bio *bio;
for (bio = bios->head; bio; bio = bio->bi_next) { for (bio = bios->head; bio; bio = bio->bi_next) {
if (bio->bi_rw & REQ_FLUSH) if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))
continue; continue;
rh_inc(rh, dm_rh_bio_to_region(rh, bio)); 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) ...@@ -1245,7 +1245,10 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
cell_release_singleton(cell, bio); cell_release_singleton(cell, bio);
cell_release_singleton(cell2, 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; break;
...@@ -2628,6 +2631,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -2628,6 +2631,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
if (tc->pool->pf.discard_enabled) { if (tc->pool->pf.discard_enabled) {
ti->discards_supported = 1; ti->discards_supported = 1;
ti->num_discard_requests = 1; ti->num_discard_requests = 1;
ti->discard_zeroes_data_unsupported = 1;
} }
dm_put(pool_md); dm_put(pool_md);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册