diff options
author | Milan Broz <mbroz@redhat.com> | 2008-02-08 05:11:09 +0300 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2008-02-08 05:11:09 +0300 |
commit | 43d6903482eec168b727bc4bf76a9f415257d862 (patch) | |
tree | cc0f5d3621c052376d2f6cff85af87002e4df344 /drivers/md/dm-crypt.c | |
parent | ddd42edfd8ec44595b1501318512bc29a36f015f (diff) | |
download | linux-43d6903482eec168b727bc4bf76a9f415257d862.tar.xz |
dm crypt: add completion for async
dm-crypt: Use crypto ablkcipher interface
Prepare completion for async crypto request.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r-- | drivers/md/dm-crypt.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 79316580c780..2ea3eb99c91f 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -6,6 +6,7 @@ * This file is released under the GPL. */ +#include <linux/completion.h> #include <linux/err.h> #include <linux/module.h> #include <linux/init.h> @@ -31,6 +32,7 @@ * context holding the current state of a multi-part conversion */ struct convert_context { + struct completion restart; struct bio *bio_in; struct bio *bio_out; unsigned int offset_in; @@ -38,6 +40,7 @@ struct convert_context { unsigned int idx_in; unsigned int idx_out; sector_t sector; + atomic_t pending; }; /* @@ -359,6 +362,15 @@ static void crypt_convert_init(struct crypt_config *cc, ctx->idx_in = bio_in ? bio_in->bi_idx : 0; ctx->idx_out = bio_out ? bio_out->bi_idx : 0; ctx->sector = sector + cc->iv_offset; + init_completion(&ctx->restart); + /* + * Crypto operation can be asynchronous, + * ctx->pending is increased after request submission. + * We need to ensure that we don't call the crypt finish + * operation before pending got incremented + * (dependent on crypt submission return code). + */ + atomic_set(&ctx->pending, 2); } static int crypt_convert_block(struct crypt_config *cc, @@ -418,6 +430,15 @@ static int crypt_convert(struct crypt_config *cc, ctx->sector++; } + /* + * If there are pending crypto operation run async + * code. Otherwise process return code synchronously. + * The step of 2 ensures that async finish doesn't + * call crypto finish too early. + */ + if (atomic_sub_return(2, &ctx->pending)) + return -EINPROGRESS; + return r; } |