diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2020-05-25 11:58:49 +0300 |
---|---|---|
committer | Miquel Raynal <miquel.raynal@bootlin.com> | 2020-05-31 11:53:40 +0300 |
commit | 73f2b68c51f4f6c3dbe621d263d6fd32526f2faf (patch) | |
tree | 9d2061c218a122ff1894052cfa64f7d83a392f36 /drivers/mtd | |
parent | dc2733dea2be78e03df1fbb5816b59d852b2291c (diff) | |
download | linux-73f2b68c51f4f6c3dbe621d263d6fd32526f2faf.tar.xz |
mtd: rawnand: nandsim: Manage lists on error in ns_init_module()
Lists are filled with calls to ns_parse_weakblocks(),
ns_parse_weakpages() and ns_parse_gravepages(). Handle them in the
error path, all at the same time.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200525085851.17682-16-miquel.raynal@bootlin.com
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/raw/nandsim.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 8ffd68321175..4492b9a9962e 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -2273,6 +2273,7 @@ static const struct nand_controller_ops ns_controller_ops = { */ static int __init ns_init_module(void) { + struct list_head *pos, *n; struct nand_chip *chip; struct nandsim *ns; int ret; @@ -2340,11 +2341,11 @@ static int __init ns_init_module(void) ret = ns_parse_weakpages(); if (ret) - goto error; + goto free_wb_list; ret = ns_parse_gravepages(); if (ret) - goto error; + goto free_wp_list; nand_controller_init(&ns->base); ns->base.ops = &ns_controller_ops; @@ -2353,7 +2354,7 @@ static int __init ns_init_module(void) ret = nand_scan(chip, 1); if (ret) { NS_ERR("Could not scan NAND Simulator device\n"); - goto error; + goto free_gp_list; } if (overridesize) { @@ -2412,9 +2413,23 @@ free_ebw: kfree(erase_block_wear); cleanup_nand: nand_cleanup(chip); +free_gp_list: + list_for_each_safe(pos, n, &grave_pages) { + list_del(pos); + kfree(list_entry(pos, struct grave_page, list)); + } +free_wp_list: + list_for_each_safe(pos, n, &weak_pages) { + list_del(pos); + kfree(list_entry(pos, struct weak_page, list)); + } +free_wb_list: + list_for_each_safe(pos, n, &weak_blocks) { + list_del(pos); + kfree(list_entry(pos, struct weak_block, list)); + } error: kfree(ns); - ns_free_lists(); return ret; } |