From: Mikulas Patocka <[email-masked]>

Change dm_unregister_target to return void and use BUG() for error
reporting.

dm_unregister_target can only fail because of programming bug in the
target driver. It can't fail because of user's behavior or disk errors.

This patch changes unregister_target to return void and use BUG if
someone tries to unregister non-registered target or unregister target
that is in use.

This patch removes code duplication (testing of error codes in all dm
targets) and reports bugs in just one place, in dm_unregister_target. In
some target drivers, these return codes were ignored, which could lead
to a situation where bugs could be missed.

Signed-off-by: Mikulas Patocka <[email-masked]>
Signed-off-by: Alasdair G Kergon <[email-masked]>
---
 drivers/md/dm-crypt.c         |    6 +-----
 drivers/md/dm-delay.c         |    6 +-----
 drivers/md/dm-linear.c        |    5 +----
 drivers/md/dm-mpath.c         |    6 +-----
 drivers/md/dm-raid1.c         |    6 +-----
 drivers/md/dm-snap.c          |   11 ++---------
 drivers/md/dm-stripe.c        |    4 +---
 drivers/md/dm-target.c        |   15 +++++++--------
 drivers/md/dm-zero.c          |    5 +----
 include/linux/device-mapper.h |    6 ++++--
 10 files changed, 20 insertions(+), 50 deletions(-)

Index: linux-2.6.28/drivers/md/dm-crypt.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-crypt.c	2009-01-05 18:15:50.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-crypt.c	2009-01-05 18:18:16.000000000 +0000
@@ -1322,11 +1322,7 @@ static int __init dm_crypt_init(void)
 
 static void __exit dm_crypt_exit(void)
 {
-	int r = dm_unregister_target(&crypt_target);
-
-	if (r < 0)
-		DMERR("unregister failed %d", r);
-
+	dm_unregister_target(&crypt_target);
 	kmem_cache_destroy(_crypt_io_pool);
 }
 
Index: linux-2.6.28/drivers/md/dm-delay.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-delay.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-delay.c	2009-01-05 18:18:16.000000000 +0000
@@ -364,11 +364,7 @@ bad_queue:
 
 static void __exit dm_delay_exit(void)
 {
-	int r = dm_unregister_target(&delay_target);
-
-	if (r < 0)
-		DMERR("unregister failed %d", r);
-
+	dm_unregister_target(&delay_target);
 	kmem_cache_destroy(delayed_cache);
 	destroy_workqueue(kdelayd_wq);
 }
Index: linux-2.6.28/drivers/md/dm-linear.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-linear.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-linear.c	2009-01-05 18:26:43.000000000 +0000
@@ -156,8 +156,5 @@ int __init dm_linear_init(void)
 
 void dm_linear_exit(void)
 {
-	int r = dm_unregister_target(&linear_target);
-
-	if (r < 0)
-		DMERR("unregister failed %d", r);
+	dm_unregister_target(&linear_target);
 }
Index: linux-2.6.28/drivers/md/dm-mpath.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-mpath.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-mpath.c	2009-01-05 18:26:43.000000000 +0000
@@ -1495,14 +1495,10 @@ static int __init dm_multipath_init(void
 
 static void __exit dm_multipath_exit(void)
 {
-	int r;
-
 	destroy_workqueue(kmpath_handlerd);
 	destroy_workqueue(kmultipathd);
 
-	r = dm_unregister_target(&multipath_target);
-	if (r < 0)
-		DMERR("target unregister failed %d", r);
+	dm_unregister_target(&multipath_target);
 	kmem_cache_destroy(_mpio_cache);
 }
 
Index: linux-2.6.28/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-raid1.c	2009-01-05 18:18:14.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-raid1.c	2009-01-05 18:26:44.000000000 +0000
@@ -1300,11 +1300,7 @@ static int __init dm_mirror_init(void)
 
 static void __exit dm_mirror_exit(void)
 {
-	int r;
-
-	r = dm_unregister_target(&mirror_target);
-	if (r < 0)
-		DMERR("unregister failed %d", r);
+	dm_unregister_target(&mirror_target);
 }
 
 /* Module hooks */
Index: linux-2.6.28/drivers/md/dm-snap.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-snap.c	2009-01-05 18:18:10.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-snap.c	2009-01-05 18:26:42.000000000 +0000
@@ -1470,17 +1470,10 @@ static int __init dm_snapshot_init(void)
 
 static void __exit dm_snapshot_exit(void)
 {
-	int r;
-
 	destroy_workqueue(ksnapd);
 
-	r = dm_unregister_target(&snapshot_target);
-	if (r)
-		DMERR("snapshot unregister failed %d", r);
-
-	r = dm_unregister_target(&origin_target);
-	if (r)
-		DMERR("origin unregister failed %d", r);
+	dm_unregister_target(&snapshot_target);
+	dm_unregister_target(&origin_target);
 
 	exit_origin_hash();
 	kmem_cache_destroy(pending_cache);
Index: linux-2.6.28/drivers/md/dm-stripe.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-stripe.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-stripe.c	2009-01-05 18:18:16.000000000 +0000
@@ -337,9 +337,7 @@ int __init dm_stripe_init(void)
 
 void dm_stripe_exit(void)
 {
-	if (dm_unregister_target(&stripe_target))
-		DMWARN("target unregistration failed");
-
+	dm_unregister_target(&stripe_target);
 	destroy_workqueue(kstriped);
 
 	return;
Index: linux-2.6.28/drivers/md/dm-target.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-target.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-target.c	2009-01-05 18:26:43.000000000 +0000
@@ -130,26 +130,26 @@ int dm_register_target(struct target_typ
 	return rv;
 }
 
-int dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *t)
 {
 	struct tt_internal *ti;
 
 	down_write(&_lock);
 	if (!(ti = __find_target_type(t->name))) {
-		up_write(&_lock);
-		return -EINVAL;
+		DMCRIT("Unregistering unrecognised target: %s", t->name);
+		BUG();
 	}
 
 	if (ti->use) {
-		up_write(&_lock);
-		return -ETXTBSY;
+		DMCRIT("Attempt to unregister target still in use: %s",
+		       t->name);
+		BUG();
 	}
 
 	list_del(&ti->list);
 	kfree(ti);
 
 	up_write(&_lock);
-	return 0;
 }
 
 /*
@@ -187,8 +187,7 @@ int __init dm_target_init(void)
 
 void dm_target_exit(void)
 {
-	if (dm_unregister_target(&error_target))
-		DMWARN("error target unregistration failed");
+	dm_unregister_target(&error_target);
 }
 
 EXPORT_SYMBOL(dm_register_target);
Index: linux-2.6.28/drivers/md/dm-zero.c
===================================================================
--- linux-2.6.28.orig/drivers/md/dm-zero.c	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/drivers/md/dm-zero.c	2009-01-05 18:18:16.000000000 +0000
@@ -69,10 +69,7 @@ static int __init dm_zero_init(void)
 
 static void __exit dm_zero_exit(void)
 {
-	int r = dm_unregister_target(&zero_target);
-
-	if (r < 0)
-		DMERR("unregister failed %d", r);
+	dm_unregister_target(&zero_target);
 }
 
 module_init(dm_zero_init)
Index: linux-2.6.28/include/linux/device-mapper.h
===================================================================
--- linux-2.6.28.orig/include/linux/device-mapper.h	2009-01-05 17:40:35.000000000 +0000
+++ linux-2.6.28/include/linux/device-mapper.h	2009-01-05 18:27:27.000000000 +0000
@@ -157,8 +157,7 @@ struct dm_target {
 };
 
 int dm_register_target(struct target_type *t);
-int dm_unregister_target(struct target_type *t);
-
+void dm_unregister_target(struct target_type *t);
 
 /*-----------------------------------------------------------------
  * Functions for creating and manipulating mapped devices.
@@ -276,6 +275,9 @@ void *dm_vcalloc(unsigned long nmemb, un
  *---------------------------------------------------------------*/
 #define DM_NAME "device-mapper"
 
+#define DMCRIT(f, arg...) \
+	printk(KERN_CRIT DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+
 #define DMERR(f, arg...) \
 	printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
 #define DMERR_LIMIT(f, arg...) \