GIT b5f4e24f3df2547c78b709c4adf058ae2f906e80 git://git.infradead.org/~dedekind/ubi-2.6.git#master commit Author: Artem Bityutskiy Date: Tue Aug 7 23:34:20 2007 +0300 UBI: use linux print_hex_dump(), not home-grown one Signed-off-by: Artem Bityutskiy commit 410c017bee9c0bb6a663ea9f70e486de6c2f9dea Author: Jesper Juhl Date: Sat Aug 4 01:25:26 2007 +0200 UBI: don't use array index before testing if it is negative I can't find anything guaranteeing that 'ubi_num' cannot be <0 in drivers/mtd/ubi/kapi.c::ubi_open_volume(), and in fact the code even tests for that and errors out if so. Unfortunately the test for "ubi_num < 0" happens after we've already used 'ubi_num' as an array index - bad thing to do if it is negative. This patch moves the test earlier in the function and then moves the indexing using that variable after the check. A bit safer :-) Signed-off-by: Jesper Juhl Signed-off-by: Artem Bityutskiy commit 39d207b7fc2cf6b5503d0252a76c1f40ece0a883 Author: Artem Bityutskiy Date: Sun Jul 22 22:32:51 2007 +0300 UBI: add more prints I hit those situations and found out lack of print messages. Add more prints when erase problems occur. Signed-off-by: Artem Bityutskiy commit 74785684ec60bacda8f9ce01481c9f3a4249274b Author: Artem Bityutskiy Date: Sun Jul 22 15:25:02 2007 +0300 UBI: fix sparse warnings Fix "symbol shadows an earlier one" warnings. Although they are harmless but it does not hurt to fix them and make sparse happy. Signed-off-by: Artem Bityutskiy commit c4e348144cdfbbdf330e7065757c5013f86b9b81 Author: Florin Malita Date: Thu Jul 19 15:22:41 2007 -0400 UBI: fix leak in ubi_scan_erase_peb Coverity (1769) found the following problem: if the erase counter overflow check triggers, ec_hdr is leaked. Moving the allocation after the overflow check should take care of it. Signed-off-by: Florin Malita Signed-off-by: Artem Bityutskiy drivers/mtd/ubi/debug.c | 37 +------------------------ drivers/mtd/ubi/debug.h | 2 - drivers/mtd/ubi/io.c | 7 +++-- drivers/mtd/ubi/kapi.c | 9 +++++- drivers/mtd/ubi/scan.c | 24 ++++++++-------- drivers/mtd/ubi/vmt.c | 70 +++++++++++++++++++++++++---------------------- drivers/mtd/ubi/wl.c | 1 + 7 files changed, 64 insertions(+), 86 deletions(-) diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 310341e..7851374 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ub dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); dbg_msg("erase counter header hexdump:"); - ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, + (void *)ec_hdr, UBI_EC_HDR_SIZE, 1); } /** @@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct dbg_msg("the 1st 16 characters of the name: %s", nm); } -#define BYTES_PER_LINE 32 - -/** - * ubi_dbg_hexdump - dump a buffer. - * @ptr: the buffer to dump - * @size: buffer size which must be multiple of 4 bytes - */ -void ubi_dbg_hexdump(const void *ptr, int size) -{ - int i, k = 0, rows, columns; - const uint8_t *p = ptr; - - size = ALIGN(size, 4); - rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE; - for (i = 0; i < rows; i++) { - int j; - - cond_resched(); - columns = min(size - k, BYTES_PER_LINE) / 4; - if (columns == 0) - break; - printk(KERN_DEBUG "%5d: ", i * BYTES_PER_LINE); - for (j = 0; j < columns; j++) { - int n, N; - - N = size - k > 4 ? 4 : size - k; - for (n = 0; n < N; n++) - printk("%02x", p[k++]); - printk(" "); - } - printk("\n"); - } -} - #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ff8f395..467722e 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const stru void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); -void ubi_dbg_hexdump(const void *buf, int size); #else @@ -72,7 +71,6 @@ #define ubi_dbg_dump_vtbl_record(r, idx) #define ubi_dbg_dump_sv(sv) ({}) #define ubi_dbg_dump_seb(seb, type) ({}) #define ubi_dbg_dump_mkvol_req(req) ({}) -#define ubi_dbg_hexdump(buf, size) ({}) #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index b0d8f4c..9284763 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -430,13 +430,16 @@ static int torture_peb(const struct ubi_ err = patt_count; out: - if (err == UBI_IO_BITFLIPS || err == -EBADMSG) + if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { /* * If a bit-flip or data integrity error was detected, the test * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ + ubi_err("read problems on freshly erased PEB %d, must be bad", + pnum); err = -EIO; + } vfree(buf); return err; } @@ -1249,7 +1252,7 @@ static int paranoid_check_all_ff(const s fail: ubi_err("paranoid check failed for PEB %d", pnum); dbg_msg("hex dump of the %d-%d region", offset, offset + len); - ubi_dbg_hexdump(buf, len); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); err = 1; error: ubi_dbg_dump_stack(); diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 4a458e8..03c774f 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -99,16 +99,21 @@ struct ubi_volume_desc *ubi_open_volume( { int err; struct ubi_volume_desc *desc; - struct ubi_device *ubi = ubi_devices[ubi_num]; + struct ubi_device *ubi; struct ubi_volume *vol; dbg_msg("open device %d volume %d, mode %d", ubi_num, vol_id, mode); err = -ENODEV; + if (ubi_num < 0) + return ERR_PTR(err); + + ubi = ubi_devices[ubi_num]; + if (!try_module_get(THIS_MODULE)) return ERR_PTR(err); - if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || !ubi) + if (ubi_num >= UBI_MAX_DEVICES || !ubi) goto out_put; err = -EINVAL; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 94ee549..18c347b 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -266,7 +266,7 @@ static int compare_lebs(const struct ubi void *buf; int len, err, second_is_newer, bitflips = 0, corrupted = 0; uint32_t data_crc, crc; - struct ubi_vid_hdr *vidh = NULL; + struct ubi_vid_hdr *vh = NULL; unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); if (seb->sqnum == 0 && sqnum2 == 0) { @@ -323,11 +323,11 @@ static int compare_lebs(const struct ubi } else { pnum = seb->pnum; - vidh = ubi_zalloc_vid_hdr(ubi); - if (!vidh) + vh = ubi_zalloc_vid_hdr(ubi); + if (!vh) return -ENOMEM; - err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (err) { if (err == UBI_IO_BITFLIPS) bitflips = 1; @@ -341,7 +341,7 @@ static int compare_lebs(const struct ubi } } - if (!vidh->copy_flag) { + if (!vh->copy_flag) { /* It is not a copy, so it is newer */ dbg_bld("first PEB %d is newer, copy_flag is unset", pnum); @@ -349,7 +349,7 @@ static int compare_lebs(const struct ubi goto out_free_vidh; } - vid_hdr = vidh; + vid_hdr = vh; } /* Read the data of the copy and check the CRC */ @@ -379,7 +379,7 @@ static int compare_lebs(const struct ubi } vfree(buf); - ubi_free_vid_hdr(ubi, vidh); + ubi_free_vid_hdr(ubi, vh); if (second_is_newer) dbg_bld("second PEB %d is newer, copy_flag is set", pnum); @@ -391,7 +391,7 @@ static int compare_lebs(const struct ubi out_free_buf: vfree(buf); out_free_vidh: - ubi_free_vid_hdr(ubi, vidh); + ubi_free_vid_hdr(ubi, vh); ubi_assert(err < 0); return err; } @@ -673,10 +673,6 @@ int ubi_scan_erase_peb(const struct ubi_ int err; struct ubi_ec_hdr *ec_hdr; - ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); - if (!ec_hdr) - return -ENOMEM; - if ((long long)ec >= UBI_MAX_ERASECOUNTER) { /* * Erase counter overflow. Upgrade UBI and use 64-bit @@ -686,6 +682,10 @@ int ubi_scan_erase_peb(const struct ubi_ return -EINVAL; } + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ec_hdr) + return -ENOMEM; + ec_hdr->ec = cpu_to_be64(ec); err = ubi_io_sync_erase(ubi, pnum, 0); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index ea0d5c8..88629a3 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -37,21 +37,21 @@ static ssize_t vol_attribute_show(struct struct device_attribute *attr, char *buf); /* Device attributes corresponding to files in '//class/ubi/ubiX_Y' */ -static struct device_attribute vol_reserved_ebs = +static struct device_attribute attr_vol_reserved_ebs = __ATTR(reserved_ebs, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_type = +static struct device_attribute attr_vol_type = __ATTR(type, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_name = +static struct device_attribute attr_vol_name = __ATTR(name, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_corrupted = +static struct device_attribute attr_vol_corrupted = __ATTR(corrupted, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_alignment = +static struct device_attribute attr_vol_alignment = __ATTR(alignment, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_usable_eb_size = +static struct device_attribute attr_vol_usable_eb_size = __ATTR(usable_eb_size, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_data_bytes = +static struct device_attribute attr_vol_data_bytes = __ATTR(data_bytes, S_IRUGO, vol_attribute_show, NULL); -static struct device_attribute vol_upd_marker = +static struct device_attribute attr_vol_upd_marker = __ATTR(upd_marker, S_IRUGO, vol_attribute_show, NULL); /* @@ -78,23 +78,27 @@ static ssize_t vol_attribute_show(struct spin_unlock(&vol->ubi->volumes_lock); return -ENODEV; } - if (attr == &vol_reserved_ebs) + if (attr == &attr_vol_reserved_ebs) ret = sprintf(buf, "%d\n", vol->reserved_pebs); - else if (attr == &vol_type) { + else if (attr == &attr_vol_type) { const char *tp; - tp = vol->vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"; + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + tp = "dynamic"; + else + tp = "static"; ret = sprintf(buf, "%s\n", tp); - } else if (attr == &vol_name) + } else if (attr == &attr_vol_name) ret = sprintf(buf, "%s\n", vol->name); - else if (attr == &vol_corrupted) + else if (attr == &attr_vol_corrupted) ret = sprintf(buf, "%d\n", vol->corrupted); - else if (attr == &vol_alignment) + else if (attr == &attr_vol_alignment) ret = sprintf(buf, "%d\n", vol->alignment); - else if (attr == &vol_usable_eb_size) { + else if (attr == &attr_vol_usable_eb_size) { ret = sprintf(buf, "%d\n", vol->usable_leb_size); - } else if (attr == &vol_data_bytes) + } else if (attr == &attr_vol_data_bytes) ret = sprintf(buf, "%lld\n", vol->used_bytes); - else if (attr == &vol_upd_marker) + else if (attr == &attr_vol_upd_marker) ret = sprintf(buf, "%d\n", vol->upd_marker); else BUG(); @@ -126,28 +130,28 @@ static int volume_sysfs_init(struct ubi_ { int err; - err = device_create_file(&vol->dev, &vol_reserved_ebs); + err = device_create_file(&vol->dev, &attr_vol_reserved_ebs); if (err) return err; - err = device_create_file(&vol->dev, &vol_type); + err = device_create_file(&vol->dev, &attr_vol_type); if (err) return err; - err = device_create_file(&vol->dev, &vol_name); + err = device_create_file(&vol->dev, &attr_vol_name); if (err) return err; - err = device_create_file(&vol->dev, &vol_corrupted); + err = device_create_file(&vol->dev, &attr_vol_corrupted); if (err) return err; - err = device_create_file(&vol->dev, &vol_alignment); + err = device_create_file(&vol->dev, &attr_vol_alignment); if (err) return err; - err = device_create_file(&vol->dev, &vol_usable_eb_size); + err = device_create_file(&vol->dev, &attr_vol_usable_eb_size); if (err) return err; - err = device_create_file(&vol->dev, &vol_data_bytes); + err = device_create_file(&vol->dev, &attr_vol_data_bytes); if (err) return err; - err = device_create_file(&vol->dev, &vol_upd_marker); + err = device_create_file(&vol->dev, &attr_vol_upd_marker); if (err) return err; return 0; @@ -159,14 +163,14 @@ static int volume_sysfs_init(struct ubi_ */ static void volume_sysfs_close(struct ubi_volume *vol) { - device_remove_file(&vol->dev, &vol_upd_marker); - device_remove_file(&vol->dev, &vol_data_bytes); - device_remove_file(&vol->dev, &vol_usable_eb_size); - device_remove_file(&vol->dev, &vol_alignment); - device_remove_file(&vol->dev, &vol_corrupted); - device_remove_file(&vol->dev, &vol_name); - device_remove_file(&vol->dev, &vol_type); - device_remove_file(&vol->dev, &vol_reserved_ebs); + device_remove_file(&vol->dev, &attr_vol_upd_marker); + device_remove_file(&vol->dev, &attr_vol_data_bytes); + device_remove_file(&vol->dev, &attr_vol_usable_eb_size); + device_remove_file(&vol->dev, &attr_vol_alignment); + device_remove_file(&vol->dev, &attr_vol_corrupted); + device_remove_file(&vol->dev, &attr_vol_name); + device_remove_file(&vol->dev, &attr_vol_type); + device_remove_file(&vol->dev, &attr_vol_reserved_ebs); device_unregister(&vol->dev); } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index a5a9b8d..12b25e5 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1093,6 +1093,7 @@ static int erase_worker(struct ubi_devic return err; } + ubi_err("failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); kmem_cache_free(wl_entries_slab, e);