From 8be3bfa1fa9fc8310e5672ce0a1248d390cdfe34 Mon Sep 17 00:00:00 2001 From: Dinesh K Garg Date: Thu, 30 Oct 2014 10:38:14 -0700 Subject: [PATCH] md: dm-req-crypt Recalculate nr_phys_segments Recalculate nr_phys_segments after pages are allocated for write requests. Move _req_crypt_io_pool allocation and de-allocation to ctr and dtr instead of driver init and exit. Change-Id: I8576dce1f7c9bc39dcc975762562fb84a349bba7 Acked-by: Baranidharan Muthukumaran Signed-off-by: Dinesh K Garg --- block/blk.h | 1 - drivers/md/dm-req-crypt.c | 19 ++++++++++++++----- include/linux/blkdev.h | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/block/blk.h b/block/blk.h index b3bdeb36f361..4e6aae4a139c 100644 --- a/block/blk.h +++ b/block/blk.h @@ -138,7 +138,6 @@ int attempt_back_merge(struct request_queue *q, struct request *rq); int attempt_front_merge(struct request_queue *q, struct request *rq); int blk_attempt_req_merge(struct request_queue *q, struct request *rq, struct request *next); -void blk_recalc_rq_segments(struct request *rq); void blk_rq_set_mixed_merge(struct request *rq); bool blk_rq_merge_ok(struct request *rq, struct bio *bio); int blk_try_merge(struct request *rq, struct bio *bio); diff --git a/drivers/md/dm-req-crypt.c b/drivers/md/dm-req-crypt.c index 478d35eafd35..0e0683574fcf 100644 --- a/drivers/md/dm-req-crypt.c +++ b/drivers/md/dm-req-crypt.c @@ -605,6 +605,11 @@ static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io) blk_queue_bounce(clone->q, &bio_src); } + /* + * Recalculate the phy_segments as we allocate new pages + * This is used by storage driver to fill the sg list. + */ + blk_recalc_rq_segments(clone); ablkcipher_req_alloc_failure: if (req) @@ -867,6 +872,8 @@ static void req_crypt_dtr(struct dm_target *ti) destroy_workqueue(req_crypt_queue); req_crypt_queue = NULL; } + + kmem_cache_destroy(_req_crypt_io_pool); if (dev) { dm_put_device(ti, dev); dev = NULL; @@ -936,6 +943,12 @@ static int req_crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) is_fde_enabled = true; /* backward compatible */ } + _req_crypt_io_pool = KMEM_CACHE(req_dm_crypt_io, 0); + if (!_req_crypt_io_pool) { + err = DM_REQ_CRYPT_ERROR; + goto ctr_exit; + } + req_crypt_queue = alloc_workqueue("req_cryptd", WQ_UNBOUND | WQ_CPU_INTENSIVE | @@ -1060,14 +1073,11 @@ static int __init req_dm_crypt_init(void) { int r; - _req_crypt_io_pool = KMEM_CACHE(req_dm_crypt_io, 0); - if (!_req_crypt_io_pool) - return -ENOMEM; r = dm_register_target(&req_crypt_target); if (r < 0) { DMERR("register failed %d", r); - kmem_cache_destroy(_req_crypt_io_pool); + return r; } DMINFO("dm-req-crypt successfully initalized.\n"); @@ -1077,7 +1087,6 @@ static int __init req_dm_crypt_init(void) static void __exit req_dm_crypt_exit(void) { - kmem_cache_destroy(_req_crypt_io_pool); dm_unregister_target(&req_crypt_target); } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3bf81c1b4121..4571f510a535 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -765,7 +765,7 @@ extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, struct scsi_ioctl_command __user *); extern void blk_queue_bio(struct request_queue *q, struct bio *bio); - +extern void blk_recalc_rq_segments(struct request *rq); /* * A queue has just exitted congestion. Note this in the global counter of * congested queues, and wake up anyone who was waiting for requests to be