diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-crypt.c | 16 |
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 | ||
339 | static int crypt_convert_block(struct crypt_config *cc, | 338 | static 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 | } |