aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorDan Ehrenberg <dehrenberg@chromium.org>2014-12-19 11:27:18 -0800
committerRichard Weinberger <richard@nod.at>2015-02-12 23:29:25 +0100
commit1440061be128180a3846480d8b8bd24233edcd2f (patch)
tree11eb08dcccd6ac008c935568bf6d32827c3b5122 /drivers/mtd
parentUBIFS: return -EINVAL if log head is empty (diff)
downloadlinux-dev-1440061be128180a3846480d8b8bd24233edcd2f.tar.xz
linux-dev-1440061be128180a3846480d8b8bd24233edcd2f.zip
UBI: block: Continue creating ubiblocks after an initialization error
If one ubi volume is corrupted but another is not, it should be possible to initialize that ubiblock from a kernel commandline which includes both of them. This patch changes the error handling behavior in initializing ubiblock to ensure that all parameters are attempted even if one fails. If there is a failure, it is logged on dmesg. It also makes error messages more descriptive by including the name of the UBI volume that failed. Tested: Formatted ubi volume /dev/ubi5_0 in a corrupt way and dev/ubi3_0 properly and included "ubi.block=5,0 ubi.block=3,0" on the kernel command line. At boot, I see the following in the console: [ 21.082420] UBI error: ubiblock_create_from_param: block: can't open volume on ubi5_0, err=-19 [ 21.084268] UBI: ubiblock3_0 created from ubi3:0(rootfs) Signed-off-by: Dan Ehrenberg <dehrenberg@chromium.org> Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/block.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 995e61c38f24..d82c63ae7c21 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -577,22 +577,28 @@ open_volume_desc(const char *name, int ubi_num, int vol_id)
return ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
}
-static int __init ubiblock_create_from_param(void)
+static void __init ubiblock_create_from_param(void)
{
- int i, ret;
+ int i, ret = 0;
struct ubiblock_param *p;
struct ubi_volume_desc *desc;
struct ubi_volume_info vi;
+ /*
+ * If there is an error creating one of the ubiblocks, continue on to
+ * create the following ubiblocks. This helps in a circumstance where
+ * the kernel command-line specifies multiple block devices and some
+ * may be broken, but we still want the working ones to come up.
+ */
for (i = 0; i < ubiblock_devs; i++) {
p = &ubiblock_param[i];
desc = open_volume_desc(p->name, p->ubi_num, p->vol_id);
if (IS_ERR(desc)) {
- pr_err("UBI: block: can't open volume, err=%ld\n",
- PTR_ERR(desc));
- ret = PTR_ERR(desc);
- break;
+ pr_err(
+ "UBI: block: can't open volume on ubi%d_%d, err=%ld",
+ p->ubi_num, p->vol_id, PTR_ERR(desc));
+ continue;
}
ubi_get_volume_info(desc, &vi);
@@ -600,12 +606,12 @@ static int __init ubiblock_create_from_param(void)
ret = ubiblock_create(&vi);
if (ret) {
- pr_err("UBI: block: can't add '%s' volume, err=%d\n",
- vi.name, ret);
- break;
+ pr_err(
+ "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d",
+ vi.name, p->ubi_num, p->vol_id, ret);
+ continue;
}
}
- return ret;
}
static void ubiblock_remove_all(void)
@@ -631,10 +637,12 @@ int __init ubiblock_init(void)
if (ubiblock_major < 0)
return ubiblock_major;
- /* Attach block devices from 'block=' module param */
- ret = ubiblock_create_from_param();
- if (ret)
- goto err_remove;
+ /*
+ * Attach block devices from 'block=' module param.
+ * Even if one block device in the param list fails to come up,
+ * still allow the module to load and leave any others up.
+ */
+ ubiblock_create_from_param();
/*
* Block devices are only created upon user requests, so we ignore
@@ -647,7 +655,6 @@ int __init ubiblock_init(void)
err_unreg:
unregister_blkdev(ubiblock_major, "ubiblock");
-err_remove:
ubiblock_remove_all();
return ret;
}