Commit 2b6f0090 authored by Boris Brezillon's avatar Boris Brezillon

mtd: Check add_mtd_device() ret code

add_mtd_device() can fail. We should always check its return value
and gracefully handle the failure case. Fix the call sites where this
not done (in mtdpart.c) and add a __must_check attribute to the
prototype to avoid this kind of mistakes.
Signed-off-by: default avatarBoris Brezillon <bbrezillon@kernel.org>
parent 19e16fb4
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
extern struct mutex mtd_table_mutex; extern struct mutex mtd_table_mutex;
struct mtd_info *__mtd_next_device(int i); struct mtd_info *__mtd_next_device(int i);
int add_mtd_device(struct mtd_info *mtd); int __must_check add_mtd_device(struct mtd_info *mtd);
int del_mtd_device(struct mtd_info *mtd); int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *); int del_mtd_partitions(struct mtd_info *);
......
...@@ -618,10 +618,22 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, ...@@ -618,10 +618,22 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
list_add(&new->list, &mtd_partitions); list_add(&new->list, &mtd_partitions);
mutex_unlock(&mtd_partitions_mutex); mutex_unlock(&mtd_partitions_mutex);
add_mtd_device(&new->mtd); ret = add_mtd_device(&new->mtd);
if (ret)
goto err_remove_part;
mtd_add_partition_attrs(new); mtd_add_partition_attrs(new);
return 0;
err_remove_part:
mutex_lock(&mtd_partitions_mutex);
list_del(&new->list);
mutex_unlock(&mtd_partitions_mutex);
free_partition(new);
pr_info("%s:%i\n", __func__, __LINE__);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(mtd_add_partition); EXPORT_SYMBOL_GPL(mtd_add_partition);
...@@ -712,22 +724,31 @@ int add_mtd_partitions(struct mtd_info *master, ...@@ -712,22 +724,31 @@ int add_mtd_partitions(struct mtd_info *master,
{ {
struct mtd_part *slave; struct mtd_part *slave;
uint64_t cur_offset = 0; uint64_t cur_offset = 0;
int i; int i, ret;
printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
for (i = 0; i < nbparts; i++) { for (i = 0; i < nbparts; i++) {
slave = allocate_partition(master, parts + i, i, cur_offset); slave = allocate_partition(master, parts + i, i, cur_offset);
if (IS_ERR(slave)) { if (IS_ERR(slave)) {
del_mtd_partitions(master); ret = PTR_ERR(slave);
return PTR_ERR(slave); goto err_del_partitions;
} }
mutex_lock(&mtd_partitions_mutex); mutex_lock(&mtd_partitions_mutex);
list_add(&slave->list, &mtd_partitions); list_add(&slave->list, &mtd_partitions);
mutex_unlock(&mtd_partitions_mutex); mutex_unlock(&mtd_partitions_mutex);
add_mtd_device(&slave->mtd); ret = add_mtd_device(&slave->mtd);
if (ret) {
mutex_lock(&mtd_partitions_mutex);
list_del(&slave->list);
mutex_unlock(&mtd_partitions_mutex);
free_partition(slave);
goto err_del_partitions;
}
mtd_add_partition_attrs(slave); mtd_add_partition_attrs(slave);
/* Look for subpartitions */ /* Look for subpartitions */
parse_mtd_partitions(&slave->mtd, parts[i].types, NULL); parse_mtd_partitions(&slave->mtd, parts[i].types, NULL);
...@@ -736,6 +757,11 @@ int add_mtd_partitions(struct mtd_info *master, ...@@ -736,6 +757,11 @@ int add_mtd_partitions(struct mtd_info *master,
} }
return 0; return 0;
err_del_partitions:
del_mtd_partitions(master);
return ret;
} }
static DEFINE_SPINLOCK(part_parser_lock); static DEFINE_SPINLOCK(part_parser_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment