<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;

Add an asynchronous destruction option to kcopyd_client_destroy().
Return code indicates whether destruction was delayed.

Signed-off-by: Milan Broz &lt;mbroz@redhat.com&gt;
---

 drivers/md/dm-raid1.c |    2 +-
 drivers/md/dm-snap.c  |    9 +++++----
 drivers/md/kcopyd.c   |    8 +++++++-
 drivers/md/kcopyd.h   |    2 +-
 4 files changed, 14 insertions(+), 7 deletions(-)

Index: linux-2.6.21/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.21.orig/drivers/md/dm-raid1.c	2007-05-02 19:48:20.000000000 +0100
+++ linux-2.6.21/drivers/md/dm-raid1.c	2007-05-03 17:21:06.000000000 +0100
@@ -1167,7 +1167,7 @@ static void mirror_dtr(struct dm_target 
 	struct mirror_set *ms = (struct mirror_set *) ti-&gt;private;
 
 	flush_workqueue(ms-&gt;kmirrord_wq);
-	kcopyd_client_destroy(ms-&gt;kcopyd_client);
+	kcopyd_client_destroy(ms-&gt;kcopyd_client, 0);
 	destroy_workqueue(ms-&gt;kmirrord_wq);
 	free_context(ms, ti, ms-&gt;nr_mirrors);
 }
Index: linux-2.6.21/drivers/md/dm-snap.c
===================================================================
--- linux-2.6.21.orig/drivers/md/dm-snap.c	2007-05-01 17:41:13.000000000 +0100
+++ linux-2.6.21/drivers/md/dm-snap.c	2007-05-03 17:21:06.000000000 +0100
@@ -544,7 +544,7 @@ static int snapshot_ctr(struct dm_target
 	return 0;
 
  bad6:
-	kcopyd_client_destroy(s-&gt;kcopyd_client);
+	kcopyd_client_destroy(s-&gt;kcopyd_client, 0);
 
  bad5:
 	s-&gt;store.destroy(&amp;s-&gt;store);
@@ -566,7 +566,7 @@ static int snapshot_ctr(struct dm_target
 
 static void __free_exceptions(struct dm_snapshot *s)
 {
-	kcopyd_client_destroy(s-&gt;kcopyd_client);
+	kcopyd_client_destroy(s-&gt;kcopyd_client, 0);
 	s-&gt;kcopyd_client = NULL;
 
 	exit_exception_table(&amp;s-&gt;pending, pending_cache);
@@ -700,8 +700,9 @@ static void pending_complete(struct pend
 	struct bio *snapshot_bios = NULL;
 	int error = 0;
 
-	if (!success) {
-		/* Read/write error - snapshot is unusable */
+	if (!success || !s-&gt;valid) {
+		/* Read/write error or deferred kcopyd
+		 * on invalidated snapshot - snapshot is unusable */
 		down_write(&amp;s-&gt;lock);
 		__invalidate_snapshot(s, -EIO);
 		error = 1;
Index: linux-2.6.21/drivers/md/kcopyd.c
===================================================================
--- linux-2.6.21.orig/drivers/md/kcopyd.c	2007-05-01 18:01:32.000000000 +0100
+++ linux-2.6.21/drivers/md/kcopyd.c	2007-05-03 17:21:06.000000000 +0100
@@ -694,8 +694,12 @@ int kcopyd_client_create(unsigned int nr
 	return 0;
 }
 
-void kcopyd_client_destroy(struct kcopyd_client *kc)
+int kcopyd_client_destroy(struct kcopyd_client *kc, unsigned async)
 {
+	/* Return immediately if there is still work in progress. */
+	if (async &amp;&amp; atomic_read(&amp;kc-&gt;nr_jobs))
+		return 1;
+
 	/* Wait for completion of all jobs submitted by this client. */
 	wait_event(kc-&gt;destroyq, !atomic_read(&amp;kc-&gt;nr_jobs));
 
@@ -704,6 +708,8 @@ void kcopyd_client_destroy(struct kcopyd
 	client_del(kc);
 	kfree(kc);
 	kcopyd_exit();
+
+	return 0;
 }
 
 EXPORT_SYMBOL(kcopyd_client_create);
Index: linux-2.6.21/drivers/md/kcopyd.h
===================================================================
--- linux-2.6.21.orig/drivers/md/kcopyd.h	2007-05-01 17:41:13.000000000 +0100
+++ linux-2.6.21/drivers/md/kcopyd.h	2007-05-03 17:21:06.000000000 +0100
@@ -23,7 +23,7 @@
  */
 struct kcopyd_client;
 int kcopyd_client_create(unsigned int num_pages, struct kcopyd_client **result);
-void kcopyd_client_destroy(struct kcopyd_client *kc);
+int kcopyd_client_destroy(struct kcopyd_client *kc, unsigned async);
 
 /*
  * Submit a copy job to kcopyd.  This is built on top of the
</pre></body></html>