diff options
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r-- | drivers/md/dm-crypt.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 35bda49796fb..bfefd079a955 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -60,6 +60,7 @@ struct dm_crypt_io { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct dm_crypt_request { | 62 | struct dm_crypt_request { |
63 | struct convert_context *ctx; | ||
63 | struct scatterlist sg_in; | 64 | struct scatterlist sg_in; |
64 | struct scatterlist sg_out; | 65 | struct scatterlist sg_out; |
65 | }; | 66 | }; |
@@ -335,6 +336,18 @@ static void crypt_convert_init(struct crypt_config *cc, | |||
335 | init_completion(&ctx->restart); | 336 | init_completion(&ctx->restart); |
336 | } | 337 | } |
337 | 338 | ||
339 | static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc, | ||
340 | struct ablkcipher_request *req) | ||
341 | { | ||
342 | return (struct dm_crypt_request *)((char *)req + cc->dmreq_start); | ||
343 | } | ||
344 | |||
345 | static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc, | ||
346 | struct dm_crypt_request *dmreq) | ||
347 | { | ||
348 | return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start); | ||
349 | } | ||
350 | |||
338 | static int crypt_convert_block(struct crypt_config *cc, | 351 | static int crypt_convert_block(struct crypt_config *cc, |
339 | struct convert_context *ctx, | 352 | struct convert_context *ctx, |
340 | struct ablkcipher_request *req) | 353 | struct ablkcipher_request *req) |
@@ -345,10 +358,11 @@ static int crypt_convert_block(struct crypt_config *cc, | |||
345 | u8 *iv; | 358 | u8 *iv; |
346 | int r = 0; | 359 | int r = 0; |
347 | 360 | ||
348 | dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start); | 361 | dmreq = dmreq_of_req(cc, req); |
349 | iv = (u8 *)ALIGN((unsigned long)(dmreq + 1), | 362 | iv = (u8 *)ALIGN((unsigned long)(dmreq + 1), |
350 | crypto_ablkcipher_alignmask(cc->tfm) + 1); | 363 | crypto_ablkcipher_alignmask(cc->tfm) + 1); |
351 | 364 | ||
365 | dmreq->ctx = ctx; | ||
352 | sg_init_table(&dmreq->sg_in, 1); | 366 | sg_init_table(&dmreq->sg_in, 1); |
353 | sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, | 367 | sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, |
354 | bv_in->bv_offset + ctx->offset_in); | 368 | bv_in->bv_offset + ctx->offset_in); |
@@ -395,8 +409,9 @@ static void crypt_alloc_req(struct crypt_config *cc, | |||
395 | cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); | 409 | cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); |
396 | ablkcipher_request_set_tfm(cc->req, cc->tfm); | 410 | ablkcipher_request_set_tfm(cc->req, cc->tfm); |
397 | ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG | | 411 | ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG | |
398 | CRYPTO_TFM_REQ_MAY_SLEEP, | 412 | CRYPTO_TFM_REQ_MAY_SLEEP, |
399 | kcryptd_async_done, ctx); | 413 | kcryptd_async_done, |
414 | dmreq_of_req(cc, cc->req)); | ||
400 | } | 415 | } |
401 | 416 | ||
402 | /* | 417 | /* |
@@ -553,19 +568,22 @@ static void crypt_inc_pending(struct dm_crypt_io *io) | |||
553 | static void crypt_dec_pending(struct dm_crypt_io *io) | 568 | static void crypt_dec_pending(struct dm_crypt_io *io) |
554 | { | 569 | { |
555 | struct crypt_config *cc = io->target->private; | 570 | struct crypt_config *cc = io->target->private; |
571 | struct bio *base_bio = io->base_bio; | ||
572 | struct dm_crypt_io *base_io = io->base_io; | ||
573 | int error = io->error; | ||
556 | 574 | ||
557 | if (!atomic_dec_and_test(&io->pending)) | 575 | if (!atomic_dec_and_test(&io->pending)) |
558 | return; | 576 | return; |
559 | 577 | ||
560 | if (likely(!io->base_io)) | 578 | mempool_free(io, cc->io_pool); |
561 | bio_endio(io->base_bio, io->error); | 579 | |
580 | if (likely(!base_io)) | ||
581 | bio_endio(base_bio, error); | ||
562 | else { | 582 | else { |
563 | if (io->error && !io->base_io->error) | 583 | if (error && !base_io->error) |
564 | io->base_io->error = io->error; | 584 | base_io->error = error; |
565 | crypt_dec_pending(io->base_io); | 585 | crypt_dec_pending(base_io); |
566 | } | 586 | } |
567 | |||
568 | mempool_free(io, cc->io_pool); | ||
569 | } | 587 | } |
570 | 588 | ||
571 | /* | 589 | /* |
@@ -821,7 +839,8 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io) | |||
821 | static void kcryptd_async_done(struct crypto_async_request *async_req, | 839 | static void kcryptd_async_done(struct crypto_async_request *async_req, |
822 | int error) | 840 | int error) |
823 | { | 841 | { |
824 | struct convert_context *ctx = async_req->data; | 842 | struct dm_crypt_request *dmreq = async_req->data; |
843 | struct convert_context *ctx = dmreq->ctx; | ||
825 | struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); | 844 | struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); |
826 | struct crypt_config *cc = io->target->private; | 845 | struct crypt_config *cc = io->target->private; |
827 | 846 | ||
@@ -830,7 +849,7 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, | |||
830 | return; | 849 | return; |
831 | } | 850 | } |
832 | 851 | ||
833 | mempool_free(ablkcipher_request_cast(async_req), cc->req_pool); | 852 | mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); |
834 | 853 | ||
835 | if (!atomic_dec_and_test(&ctx->pending)) | 854 | if (!atomic_dec_and_test(&ctx->pending)) |
836 | return; | 855 | return; |