aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 262ed1816695..f6018f5961de 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -333,7 +333,6 @@ static void crypt_convert_init(struct crypt_config *cc,
333 ctx->idx_out = bio_out ? bio_out->bi_idx : 0; 333 ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
334 ctx->sector = sector + cc->iv_offset; 334 ctx->sector = sector + cc->iv_offset;
335 init_completion(&ctx->restart); 335 init_completion(&ctx->restart);
336 atomic_set(&ctx->pending, 1);
337} 336}
338 337
339static int crypt_convert_block(struct crypt_config *cc, 338static int crypt_convert_block(struct crypt_config *cc,
@@ -408,6 +407,8 @@ static int crypt_convert(struct crypt_config *cc,
408{ 407{
409 int r; 408 int r;
410 409
410 atomic_set(&ctx->pending, 1);
411
411 while(ctx->idx_in < ctx->bio_in->bi_vcnt && 412 while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
412 ctx->idx_out < ctx->bio_out->bi_vcnt) { 413 ctx->idx_out < ctx->bio_out->bi_vcnt) {
413 414
@@ -694,6 +695,7 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
694{ 695{
695 struct crypt_config *cc = io->target->private; 696 struct crypt_config *cc = io->target->private;
696 struct bio *clone; 697 struct bio *clone;
698 int crypt_finished;
697 unsigned remaining = io->base_bio->bi_size; 699 unsigned remaining = io->base_bio->bi_size;
698 int r; 700 int r;
699 701
@@ -721,19 +723,23 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
721 723
722 crypt_inc_pending(io); 724 crypt_inc_pending(io);
723 r = crypt_convert(cc, &io->ctx); 725 r = crypt_convert(cc, &io->ctx);
726 crypt_finished = atomic_dec_and_test(&io->ctx.pending);
724 727
725 if (atomic_dec_and_test(&io->ctx.pending)) { 728 /* Encryption was already finished, submit io now */
726 /* processed, no running async crypto */ 729 if (crypt_finished) {
727 kcryptd_crypt_write_io_submit(io, r, 0); 730 kcryptd_crypt_write_io_submit(io, r, 0);
731
732 /*
733 * If there was an error, do not try next fragments.
734 * For async, error is processed in async handler.
735 */
728 if (unlikely(r < 0)) 736 if (unlikely(r < 0))
729 break; 737 break;
730 } 738 }
731 739
732 /* out of memory -> run queues */ 740 /* out of memory -> run queues */
733 if (unlikely(remaining)) { 741 if (unlikely(remaining)) {
734 /* wait for async crypto then reinitialize pending */
735 wait_event(cc->writeq, !atomic_read(&io->ctx.pending)); 742 wait_event(cc->writeq, !atomic_read(&io->ctx.pending));
736 atomic_set(&io->ctx.pending, 1);
737 congestion_wait(WRITE, HZ/100); 743 congestion_wait(WRITE, HZ/100);
738 } 744 }
739 } 745 }