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 35bda49796f..bfefd079a95 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; |
