change (struct target_type).use to be an atomic_t.
--- diff/drivers/md/dm-target.c	2002-11-05 14:23:13.000000000 +0000
+++ source/drivers/md/dm-target.c	2002-12-12 16:51:01.000000000 +0000
@@ -14,7 +14,7 @@
 	struct target_type tt;
 
 	struct list_head list;
-	long use;
+	atomic_t use_count;
 };
 
 static LIST_HEAD(_targets);
@@ -45,9 +45,18 @@
 	ti = __find_target_type(name);
 
 	if (ti) {
-		if (ti->use == 0 && ti->tt.module)
-			__MOD_INC_USE_COUNT(ti->tt.module);
-		ti->use++;
+		if (!atomic_read(&ti->use_count)) {
+			read_unlock(&_lock);
+			write_lock(&_lock);
+
+			if (!atomic_read(&ti->use_count) && ti->tt.module)
+				__MOD_INC_USE_COUNT(ti->tt.module);
+
+			write_unlock(&_lock);
+			read_lock(&_lock);
+		}
+
+		atomic_inc(&ti->use_count);
 	}
 	read_unlock(&_lock);
 
@@ -85,14 +94,11 @@
 	struct tt_internal *ti = (struct tt_internal *) t;
 
 	read_lock(&_lock);
-	if (--ti->use == 0 && ti->tt.module)
+
+	if (atomic_dec_and_test(&ti->use_count) && ti->tt.module)
 		__MOD_DEC_USE_COUNT(ti->tt.module);
 
-	if (ti->use < 0)
-		BUG();
 	read_unlock(&_lock);
-
-	return;
 }
 
 static struct tt_internal *alloc_target(struct target_type *t)
@@ -135,7 +141,7 @@
 		return -EINVAL;
 	}
 
-	if (ti->use) {
+	if (atomic_read(&ti->use_count)) {
 		write_unlock(&_lock);
 		return -ETXTBSY;
 	}