aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 2ea3eb99c91f..c45bd0e59dcc 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -406,11 +406,17 @@ static int crypt_convert_block(struct crypt_config *cc,
406 ctx->sector); 406 ctx->sector);
407} 407}
408 408
409static void kcryptd_async_done(struct crypto_async_request *async_req,
410 int error);
409static void crypt_alloc_req(struct crypt_config *cc, 411static void crypt_alloc_req(struct crypt_config *cc,
410 struct convert_context *ctx) 412 struct convert_context *ctx)
411{ 413{
412 if (!cc->req) 414 if (!cc->req)
413 cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); 415 cc->req = mempool_alloc(cc->req_pool, GFP_NOIO);
416 ablkcipher_request_set_tfm(cc->req, cc->tfm);
417 ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG |
418 CRYPTO_TFM_REQ_MAY_SLEEP,
419 kcryptd_async_done, ctx);
414} 420}
415 421
416/* 422/*
@@ -615,6 +621,9 @@ static void kcryptd_io_read(struct dm_crypt_io *io)
615 621
616static void kcryptd_io_write(struct dm_crypt_io *io) 622static void kcryptd_io_write(struct dm_crypt_io *io)
617{ 623{
624 struct bio *clone = io->ctx.bio_out;
625
626 generic_make_request(clone);
618} 627}
619 628
620static void kcryptd_io(struct work_struct *work) 629static void kcryptd_io(struct work_struct *work)
@@ -635,7 +644,8 @@ static void kcryptd_queue_io(struct dm_crypt_io *io)
635 queue_work(cc->io_queue, &io->work); 644 queue_work(cc->io_queue, &io->work);
636} 645}
637 646
638static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int error) 647static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
648 int error, int async)
639{ 649{
640 struct bio *clone = io->ctx.bio_out; 650 struct bio *clone = io->ctx.bio_out;
641 struct crypt_config *cc = io->target->private; 651 struct crypt_config *cc = io->target->private;
@@ -653,8 +663,12 @@ static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int error)
653 clone->bi_sector = cc->start + io->sector; 663 clone->bi_sector = cc->start + io->sector;
654 io->sector += bio_sectors(clone); 664 io->sector += bio_sectors(clone);
655 665
656 atomic_inc(&io->pending); 666 if (async)
657 generic_make_request(clone); 667 kcryptd_queue_io(io);
668 else {
669 atomic_inc(&io->pending);
670 generic_make_request(clone);
671 }
658} 672}
659 673
660static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io) 674static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
@@ -682,7 +696,7 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
682 696
683 r = crypt_convert(cc, &io->ctx); 697 r = crypt_convert(cc, &io->ctx);
684 698
685 kcryptd_crypt_write_io_submit(io, r); 699 kcryptd_crypt_write_io_submit(io, r, 0);
686 if (unlikely(r < 0)) 700 if (unlikely(r < 0))
687 return; 701 return;
688 702
@@ -728,6 +742,29 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
728 kcryptd_crypt_read_done(io, r); 742 kcryptd_crypt_read_done(io, r);
729} 743}
730 744
745static void kcryptd_async_done(struct crypto_async_request *async_req,
746 int error)
747{
748 struct convert_context *ctx = async_req->data;
749 struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx);
750 struct crypt_config *cc = io->target->private;
751
752 if (error == -EINPROGRESS) {
753 complete(&ctx->restart);
754 return;
755 }
756
757 mempool_free(ablkcipher_request_cast(async_req), cc->req_pool);
758
759 if (!atomic_dec_and_test(&ctx->pending))
760 return;
761
762 if (bio_data_dir(io->base_bio) == READ)
763 kcryptd_crypt_read_done(io, error);
764 else
765 kcryptd_crypt_write_io_submit(io, error, 1);
766}
767
731static void kcryptd_crypt(struct work_struct *work) 768static void kcryptd_crypt(struct work_struct *work)
732{ 769{
733 struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work); 770 struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);