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