<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From: Milan Broz &lt;mbroz@redhat.com&gt;

dm-crypt: Use crypto ablkcipher interface
Prepare completion for async crypto request.

Signed-off-by: Herbert Xu &lt;herbert@gondor.apana.org.au&gt;
Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
---
 drivers/md/dm-crypt.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+)

Index: linux-2.6.24/drivers/md/dm-crypt.c
===================================================================
--- linux-2.6.24.orig/drivers/md/dm-crypt.c	2008-02-07 13:48:36.000000000 +0000
+++ linux-2.6.24/drivers/md/dm-crypt.c	2008-02-07 13:48:37.000000000 +0000
@@ -6,6 +6,7 @@
  * This file is released under the GPL.
  */
 
+#include &lt;linux/completion.h&gt;
 #include &lt;linux/err.h&gt;
 #include &lt;linux/module.h&gt;
 #include &lt;linux/init.h&gt;
@@ -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 cr
 	ctx-&gt;idx_in = bio_in ? bio_in-&gt;bi_idx : 0;
 	ctx-&gt;idx_out = bio_out ? bio_out-&gt;bi_idx : 0;
 	ctx-&gt;sector = sector + cc-&gt;iv_offset;
+	init_completion(&amp;ctx-&gt;restart);
+	/*
+	 * Crypto operation can be asynchronous,
+	 * ctx-&gt;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(&amp;ctx-&gt;pending, 2);
 }
 
 static int crypt_convert_block(struct crypt_config *cc,
@@ -418,6 +430,15 @@ static int crypt_convert(struct crypt_co
 		ctx-&gt;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, &amp;ctx-&gt;pending))
+		return -EINPROGRESS;
+
 	return r;
 }
 
</pre></body></html>