Browse Source

dm table: fix missing dm_put_target_type() in dm_table_add_target()

dm_get_target_type() was previously called so any error returned from
dm_table_add_target() must first call dm_put_target_type().  Otherwise
the DM target module's reference count will leak and the associated
kernel module will be unable to be removed.

Also, leverage the fact that r is already -EINVAL and remove an extra
newline.

Fixes: 36a0456 ("dm table: add immutable feature")
Fixes: cc6cbe1 ("dm table: add always writeable feature")
Fixes: 3791e2f ("dm table: add singleton feature")
Cc: stable@vger.kernel.org # 3.2+
Signed-off-by: tang.junhui <tang.junhui@zte.com.cn>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
tang.junhui 8 năm trước cách đây
mục cha
commit
dafa724bf5
1 tập tin đã thay đổi với 9 bổ sung15 xóa
  1. 9 15
      drivers/md/dm-table.c

+ 9 - 15
drivers/md/dm-table.c

@@ -695,37 +695,32 @@ int dm_table_add_target(struct dm_table *t, const char *type,
 
 
 	tgt->type = dm_get_target_type(type);
 	tgt->type = dm_get_target_type(type);
 	if (!tgt->type) {
 	if (!tgt->type) {
-		DMERR("%s: %s: unknown target type", dm_device_name(t->md),
-		      type);
+		DMERR("%s: %s: unknown target type", dm_device_name(t->md), type);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	if (dm_target_needs_singleton(tgt->type)) {
 	if (dm_target_needs_singleton(tgt->type)) {
 		if (t->num_targets) {
 		if (t->num_targets) {
-			DMERR("%s: target type %s must appear alone in table",
-			      dm_device_name(t->md), type);
-			return -EINVAL;
+			tgt->error = "singleton target type must appear alone in table";
+			goto bad;
 		}
 		}
 		t->singleton = true;
 		t->singleton = true;
 	}
 	}
 
 
 	if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) {
 	if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) {
-		DMERR("%s: target type %s may not be included in read-only tables",
-		      dm_device_name(t->md), type);
-		return -EINVAL;
+		tgt->error = "target type may not be included in a read-only table";
+		goto bad;
 	}
 	}
 
 
 	if (t->immutable_target_type) {
 	if (t->immutable_target_type) {
 		if (t->immutable_target_type != tgt->type) {
 		if (t->immutable_target_type != tgt->type) {
-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
-			      dm_device_name(t->md), t->immutable_target_type->name);
-			return -EINVAL;
+			tgt->error = "immutable target type cannot be mixed with other target types";
+			goto bad;
 		}
 		}
 	} else if (dm_target_is_immutable(tgt->type)) {
 	} else if (dm_target_is_immutable(tgt->type)) {
 		if (t->num_targets) {
 		if (t->num_targets) {
-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
-			      dm_device_name(t->md), tgt->type->name);
-			return -EINVAL;
+			tgt->error = "immutable target type cannot be mixed with other target types";
+			goto bad;
 		}
 		}
 		t->immutable_target_type = tgt->type;
 		t->immutable_target_type = tgt->type;
 	}
 	}
@@ -740,7 +735,6 @@ int dm_table_add_target(struct dm_table *t, const char *type,
 	 */
 	 */
 	if (!adjoin(t, tgt)) {
 	if (!adjoin(t, tgt)) {
 		tgt->error = "Gap in table";
 		tgt->error = "Gap in table";
-		r = -EINVAL;
 		goto bad;
 		goto bad;
 	}
 	}