From d967a6927b07f1a4d822fddde536807be2c6fee0 Mon Sep 17 00:00:00 2001 From: Bhavesh Parekh Date: Wed, 30 Nov 2011 17:43:42 +0530 Subject: UBI: fix missing scrub when there is a bit-flip Under some cases, when scrubbing the PEB if we did not get the lock on the PEB it fails to scrub. Add that PEB again to the scrub list Artem: minor amendments. Cc: stable@kernel.org [2.6.31+] Signed-off-by: Bhavesh Parekh Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 6 ++++-- drivers/mtd/ubi/ubi.h | 2 ++ drivers/mtd/ubi/wl.c | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 4be671815014..c696c9481c95 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1028,12 +1028,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the * LEB is already locked, we just do not move it and return - * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later. + * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because + * we do not know the reasons of the contention - it may be just a + * normal I/O on this LEB, so we want to re-try. */ err = leb_write_trylock(ubi, vol_id, lnum); if (err) { dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum); - return MOVE_CANCEL_RACE; + return MOVE_RETRY; } /* diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index dc64c767fd21..d51d75d34446 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -120,6 +120,7 @@ enum { * PEB * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the * target PEB + * MOVE_RETRY: retry scrubbing the PEB */ enum { MOVE_CANCEL_RACE = 1, @@ -127,6 +128,7 @@ enum { MOVE_TARGET_RD_ERR, MOVE_TARGET_WR_ERR, MOVE_CANCEL_BITFLIPS, + MOVE_RETRY, }; /** diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 42c684cf3688..277c429a138f 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -795,7 +795,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, protect = 1; goto out_not_moved; } - + if (err == MOVE_RETRY) { + scrubbing = 1; + goto out_not_moved; + } if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || err == MOVE_TARGET_RD_ERR) { /* -- cgit v1.2.3 From 4bad08a739b86a1dee7a0818c10082b0102103b8 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 5 Jan 2012 10:47:18 +0200 Subject: UBI: fix use-after-free on error path When we fail to erase a PEB, we free the corresponding erase entry object, but then re-schedule this object if the error code was something like -EAGAIN. Obviously, it is a bug to use the object after we have freed it. Reported-by: Emese Revfy Cc: stable@kernel.org [v2.6.23+] Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 277c429a138f..0696e36b0539 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1052,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, ubi_err("failed to erase PEB %d, error %d", pnum, err); kfree(wl_wrk); - kmem_cache_free(ubi_wl_entry_slab, e); if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || err == -EBUSY) { @@ -1065,14 +1064,16 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, goto out_ro; } return err; - } else if (err != -EIO) { + } + + kmem_cache_free(ubi_wl_entry_slab, e); + if (err != -EIO) /* * If this is not %-EIO, we have no idea what to do. Scheduling * this physical eraseblock for erasure again would cause * errors again and again. Well, lets switch to R/O mode. */ goto out_ro; - } /* It is %-EIO, the PEB went bad */ -- cgit v1.2.3 From d02ed6b994e6b66e03eaa3fee648279f23faffac Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Thu, 22 Dec 2011 16:12:57 +0100 Subject: UBI: make vid_hdr non-static Remove 'static' modifier from the 'vid_hdr' local variable. I do not know how it slipped in, but this is a bug and will break UBI if someone attaches 2 UBI volumes at the same time. Artem: amended teh commit message, added -stable. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org --- drivers/mtd/ubi/vtbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 4b50a3029b84..d28f60ae9f15 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -306,7 +306,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, int copy, void *vtbl) { int err, tries = 0; - static struct ubi_vid_hdr *vid_hdr; + struct ubi_vid_hdr *vid_hdr; struct ubi_scan_leb *new_seb; ubi_msg("create volume table (copy #%d)", copy + 1); -- cgit v1.2.3 From f277933cb5dd95251e70d2792ea2061cf472985c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 10 Jan 2012 19:32:30 +0200 Subject: UBI: fix debugging messages Patch ab50ff684707031ed4bad2fdd313208ae392e5bb broke UBI debugging messages: before that commit when UBI debugging was enabled, users saw few useful debugging messages after attaching an MTD device. However, that patch turned 'dbg_msg()' into 'pr_debug()', so to enable the debugging messages users have to enable them first via /sys/kernel/debug/dynamic_debug/control, which is very impractical. This commit makes 'dbg_msg()' to use 'printk()' instead of 'pr_debug()', just as it was before the breakage. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [3.0+] --- drivers/mtd/ubi/debug.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 64fbb0021825..ead2cd16ba75 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -43,7 +43,10 @@ pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__) /* Just a debugging messages not related to any specific UBI subsystem */ -#define dbg_msg(fmt, ...) ubi_dbg_msg("msg", fmt, ##__VA_ARGS__) +#define dbg_msg(fmt, ...) \ + printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ + current->pid, __func__, ##__VA_ARGS__) + /* General debugging messages */ #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__) /* Messages from the eraseblock association sub-system */ -- cgit v1.2.3 From 374265b2ac238dbbc16a21ed6750f83c23053991 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Fri, 13 Jan 2012 15:07:40 +0100 Subject: UBI: fix nameless volumes handling Currently it's possible to create a volume without a name. E.g: ubimkvol -n 32 -s 2MiB -t static /dev/ubi0 -N "" After that vtbl_check() will always fail because it does not permit empty strings. Cc: stable@kernel.org Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 3320a50ba4f0..ad76592fb2f4 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -632,6 +632,9 @@ static int verify_mkvol_req(const struct ubi_device *ubi, if (req->alignment != 1 && n) goto bad; + if (!req->name[0] || !req->name_len) + goto bad; + if (req->name_len > UBI_VOL_NAME_MAX) { err = -ENAMETOOLONG; goto bad; -- cgit v1.2.3 From a970fbd4983de569dc4e4c854a742f5ea452d69f Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 10 Jan 2012 17:57:03 +0100 Subject: UBI: use own macros for the layout volume This is a minor nicification: UBI_LAYOUT_VOLUME_TYPE and UBI_LAYOUT_VOLUME_ALIGN are currently defined but not used - use them. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/vtbl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index d28f60ae9f15..118b966e0556 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -322,7 +322,7 @@ retry: goto out_free; } - vid_hdr->vol_type = UBI_VID_DYNAMIC; + vid_hdr->vol_type = UBI_LAYOUT_VOLUME_TYPE; vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOLUME_ID); vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; vid_hdr->data_size = vid_hdr->used_ebs = @@ -632,7 +632,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, return -ENOMEM; vol->reserved_pebs = UBI_LAYOUT_VOLUME_EBS; - vol->alignment = 1; + vol->alignment = UBI_LAYOUT_VOLUME_ALIGN; vol->vol_type = UBI_DYNAMIC_VOLUME; vol->name_len = sizeof(UBI_LAYOUT_VOLUME_NAME) - 1; memcpy(vol->name, UBI_LAYOUT_VOLUME_NAME, vol->name_len + 1); -- cgit v1.2.3 From 37f2ce47dac741192777dacd895a78f66b1cc991 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 30 Jan 2012 18:20:13 +0100 Subject: UBI: fix error handling in ubi_scan() Two bad things can happen in ubi_scan(): 1. If kmem_cache_create() fails we jump to out_si and call ubi_scan_destroy_si() which calls kmem_cache_destroy(). But si->scan_leb_slab is NULL. 2. If process_eb() fails we jump to out_vidh, call kmem_cache_destroy() and ubi_scan_destroy_si() which calls again kmem_cache_destroy(). Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org --- drivers/mtd/ubi/scan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index a3a198f9b98d..7256a53b7dd6 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1174,7 +1174,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) - goto out_slab; + goto out_si; vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) @@ -1235,8 +1235,6 @@ out_vidh: ubi_free_vid_hdr(ubi, vidh); out_ech: kfree(ech); -out_slab: - kmem_cache_destroy(si->scan_leb_slab); out_si: ubi_scan_destroy_si(si); return ERR_PTR(err); @@ -1325,7 +1323,9 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) } } - kmem_cache_destroy(si->scan_leb_slab); + if (si->scan_leb_slab) + kmem_cache_destroy(si->scan_leb_slab); + kfree(si); } -- cgit v1.2.3 From 0cac28a407f63e9fb3a1ad43f40247f39fe24809 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 7 Mar 2012 18:56:29 +0200 Subject: UBI: fix documentation and improve readability The "max" parameter of 'find_wl_entry()' was documented incorrectly and it actually means the maximum possible difference from the smallest erase counter. Rename it to "diff" instead, and amend the documentation. Reported-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy Reviewed-by: Shmulik Ladkani --- drivers/mtd/ubi/wl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0696e36b0539..8616f52144c1 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -350,18 +350,19 @@ static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e) /** * find_wl_entry - find wear-leveling entry closest to certain erase counter. * @root: the RB-tree where to look for - * @max: highest possible erase counter + * @diff: maximum possible difference from the smallest erase counter * * This function looks for a wear leveling entry with erase counter closest to - * @max and less than @max. + * min + @diff, where min is the smallest erase counter. */ -static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) +static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) { struct rb_node *p; struct ubi_wl_entry *e; + int max; e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); - max += e->ec; + max = e->ec + diff; p = root->rb_node; while (p) { -- cgit v1.2.3 From 6e6eb6fc6b52f3c003bc68a7d0008e68a8fc3f48 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 7 Mar 2012 19:08:36 +0200 Subject: UBI: fix eraseblock picking criteria The 'find_wl_entry()' function expects the maximum difference as the second argument, not the maximum absolute value. So the "unknown" eraseblock picking was incorrect, as Shmulik Ladkani spotted. This patch fixes the issue. Reported-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy Reviewed-by: Shmulik Ladkani Cc: stable@kernel.org --- drivers/mtd/ubi/wl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 8616f52144c1..512eab07c606 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -390,7 +390,7 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) */ int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) { - int err, medium_ec; + int err; struct ubi_wl_entry *e, *first, *last; ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || @@ -428,7 +428,7 @@ retry: * For unknown data we pick a physical eraseblock with medium * erase counter. But we by no means can pick a physical * eraseblock with erase counter greater or equivalent than the - * lowest erase counter plus %WL_FREE_MAX_DIFF. + * lowest erase counter plus %WL_FREE_MAX_DIFF/2. */ first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); @@ -437,10 +437,8 @@ retry: if (last->ec - first->ec < WL_FREE_MAX_DIFF) e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb); - else { - medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; - e = find_wl_entry(&ubi->free, medium_ec); - } + else + e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); break; case UBI_SHORTTERM: /* -- cgit v1.2.3 From f6efd7668eb65957fa0a9c84d0ca9c503d23c0e5 Mon Sep 17 00:00:00 2001 From: Josselin Costanzi Date: Wed, 22 Feb 2012 16:37:05 +0100 Subject: UBI: reduce memory consumption Remove the pre-allocated 'peb_buf2' buffer because we do not really need it. The only reason UBI has it is to check that the data were written correctly. But we do not have to have 2 buffers for this and waste RAM - we can just compare CRC checksums instead. This reduces UBI memory consumption. Artem bityutskiy: massaged the patch and commit message Signed-off-by: Josselin Costanzi Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 6 ------ drivers/mtd/ubi/eba.c | 6 +++--- drivers/mtd/ubi/ubi.h | 4 +--- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6c3fb5ab20f5..57f1717ea59d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -949,10 +949,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (!ubi->peb_buf1) goto out_free; - ubi->peb_buf2 = vmalloc(ubi->peb_size); - if (!ubi->peb_buf2) - goto out_free; - err = ubi_debugging_init_dev(ubi); if (err) goto out_free; @@ -1030,7 +1026,6 @@ out_debugging: ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf1); - vfree(ubi->peb_buf2); if (ref) put_device(&ubi->dev); else @@ -1102,7 +1097,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf1); - vfree(ubi->peb_buf2); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); put_device(&ubi->dev); return 0; diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index c696c9481c95..ef96a43c62ad 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1134,8 +1134,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * We've written the data and are going to read it back to make * sure it was written correctly. */ - - err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); + memset(ubi->peb_buf1, 0xFF, aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf1, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data back " @@ -1149,7 +1149,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); - if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { + if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size)) { ubi_warn("read data back from PEB %d and it is " "different", to); err = -EINVAL; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index d51d75d34446..cb93ad97468b 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -388,8 +388,7 @@ struct ubi_wl_entry; * @mtd: MTD device descriptor * * @peb_buf1: a buffer of PEB size used for different purposes - * @peb_buf2: another buffer of PEB size used for different purposes - * @buf_mutex: protects @peb_buf1 and @peb_buf2 + * @buf_mutex: protects @peb_buf1 * @ckvol_mutex: serializes static volume checking when opening * * @dbg: debugging information for this UBI device @@ -472,7 +471,6 @@ struct ubi_device { struct mtd_info *mtd; void *peb_buf1; - void *peb_buf2; struct mutex buf_mutex; struct mutex ckvol_mutex; -- cgit v1.2.3 From 21d029b6164303c087b7d0d64bf132427a280552 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 8 Mar 2012 15:29:37 +0200 Subject: UBI: rename peb_buf1 to peb_buf Now we have only one buffer so let's rename it to just 'peb_buf1'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 8 ++++---- drivers/mtd/ubi/eba.c | 24 ++++++++++++------------ drivers/mtd/ubi/io.c | 14 +++++++------- drivers/mtd/ubi/scan.c | 8 ++++---- drivers/mtd/ubi/ubi.h | 6 +++--- 5 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 57f1717ea59d..ba73c0096444 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -945,8 +945,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) goto out_free; err = -ENOMEM; - ubi->peb_buf1 = vmalloc(ubi->peb_size); - if (!ubi->peb_buf1) + ubi->peb_buf = vmalloc(ubi->peb_size); + if (!ubi->peb_buf) goto out_free; err = ubi_debugging_init_dev(ubi); @@ -1025,7 +1025,7 @@ out_detach: out_debugging: ubi_debugging_exit_dev(ubi); out_free: - vfree(ubi->peb_buf1); + vfree(ubi->peb_buf); if (ref) put_device(&ubi->dev); else @@ -1096,7 +1096,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) vfree(ubi->vtbl); put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); - vfree(ubi->peb_buf1); + vfree(ubi->peb_buf); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); put_device(&ubi->dev); return 0; diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index ef96a43c62ad..44001530ecea 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -529,18 +529,18 @@ retry: data_size = offset + len; mutex_lock(&ubi->buf_mutex); - memset(ubi->peb_buf1 + offset, 0xFF, len); + memset(ubi->peb_buf + offset, 0xFF, len); /* Read everything before the area where the write failure happened */ if (offset > 0) { - err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); + err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) goto out_unlock; } - memcpy(ubi->peb_buf1 + offset, buf, len); + memcpy(ubi->peb_buf + offset, buf, len); - err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); + err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size); if (err) { mutex_unlock(&ubi->buf_mutex); goto write_error; @@ -1053,13 +1053,13 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* * OK, now the LEB is locked and we can safely start moving it. Since - * this function utilizes the @ubi->peb_buf1 buffer which is shared + * this function utilizes the @ubi->peb_buf buffer which is shared * with some other functions - we lock the buffer by taking the * @ubi->buf_mutex. */ mutex_lock(&ubi->buf_mutex); dbg_wl("read %d bytes of data", aldata_size); - err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data from PEB %d", err, from); @@ -1079,10 +1079,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, */ if (vid_hdr->vol_type == UBI_VID_DYNAMIC) aldata_size = data_size = - ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); + ubi_calc_data_len(ubi, ubi->peb_buf, data_size); cond_resched(); - crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size); cond_resched(); /* @@ -1121,7 +1121,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } if (data_size > 0) { - err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); + err = ubi_io_write_data(ubi, ubi->peb_buf, to, 0, aldata_size); if (err) { if (err == -EIO) err = MOVE_TARGET_WR_ERR; @@ -1134,8 +1134,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * We've written the data and are going to read it back to make * sure it was written correctly. */ - memset(ubi->peb_buf1, 0xFF, aldata_size); - err = ubi_io_read_data(ubi, ubi->peb_buf1, to, 0, aldata_size); + memset(ubi->peb_buf, 0xFF, aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data back " @@ -1149,7 +1149,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); - if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size)) { + if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { ubi_warn("read data back from PEB %d and it is " "different", to); err = -EINVAL; diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 6ba55c235873..2614dcc497ee 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -431,11 +431,11 @@ static int torture_peb(struct ubi_device *ubi, int pnum) goto out; /* Make sure the PEB contains only 0xFF bytes */ - err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; - err = ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); + err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); if (err == 0) { ubi_err("erased PEB %d, but a non-0xFF byte found", pnum); @@ -444,17 +444,17 @@ static int torture_peb(struct ubi_device *ubi, int pnum) } /* Write a pattern and check it */ - memset(ubi->peb_buf1, patterns[i], ubi->peb_size); - err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + memset(ubi->peb_buf, patterns[i], ubi->peb_size); + err = ubi_io_write(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; - memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); - err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + memset(ubi->peb_buf, ~patterns[i], ubi->peb_size); + err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; - err = ubi_check_pattern(ubi->peb_buf1, patterns[i], + err = ubi_check_pattern(ubi->peb_buf, patterns[i], ubi->peb_size); if (err == 0) { ubi_err("pattern %x checking failed for PEB %d", diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 7256a53b7dd6..857e04f1e83c 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -789,9 +789,9 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, int err; mutex_lock(&ubi->buf_mutex); - memset(ubi->peb_buf1, 0x00, ubi->leb_size); + memset(ubi->peb_buf, 0x00, ubi->leb_size); - err = ubi_io_read(ubi, ubi->peb_buf1, pnum, ubi->leb_start, + err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start, ubi->leb_size); if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { /* @@ -808,7 +808,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, if (err) goto out_unlock; - if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) + if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) goto out_unlock; ubi_err("PEB %d contains corrupted VID header, and the data does not " @@ -818,7 +818,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, dbg_msg("hexdump of PEB %d offset %d, length %d", pnum, ubi->leb_start, ubi->leb_size); ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, - ubi->peb_buf1, ubi->leb_size, 1); + ubi->peb_buf, ubi->leb_size, 1); err = 1; out_unlock: diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index cb93ad97468b..bd6120c62c55 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -387,8 +387,8 @@ struct ubi_wl_entry; * time (MTD write buffer size) * @mtd: MTD device descriptor * - * @peb_buf1: a buffer of PEB size used for different purposes - * @buf_mutex: protects @peb_buf1 + * @peb_buf: a buffer of PEB size used for different purposes + * @buf_mutex: protects @peb_buf * @ckvol_mutex: serializes static volume checking when opening * * @dbg: debugging information for this UBI device @@ -470,7 +470,7 @@ struct ubi_device { int max_write_size; struct mtd_info *mtd; - void *peb_buf1; + void *peb_buf; struct mutex buf_mutex; struct mutex ckvol_mutex; -- cgit v1.2.3 From e436d9db970c0f8b68811161318878d3192b04a0 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 9 Mar 2012 10:31:18 +0200 Subject: UBI: rename MOVE_CANCEL_BITFLIPS to MOVE_TARGET_BITFLIPS While looking at a problem reported by UBI around the PEB moving area I noticed that the 'MOVE_CANCEL_BITFLIPS' is a bit inconsistent name and 'MOVE_TARGET_BITFLIPS' better - let's rename it. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 6 +++--- drivers/mtd/ubi/ubi.h | 4 ++-- drivers/mtd/ubi/wl.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 44001530ecea..9b7f87ea3285 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -979,7 +979,7 @@ static int is_error_sane(int err) * physical eraseblock @to. The @vid_hdr buffer may be changed by this * function. Returns: * o %0 in case of success; - * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, %MOVE_CANCEL_BITFLIPS, etc; + * o %MOVE_CANCEL_RACE, %MOVE_TARGET_WR_ERR, %MOVE_TARGET_BITFLIPS, etc; * o a negative error code in case of failure. */ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, @@ -1116,7 +1116,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; } else - err = MOVE_CANCEL_BITFLIPS; + err = MOVE_TARGET_BITFLIPS; goto out_unlock_buf; } @@ -1143,7 +1143,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; } else - err = MOVE_CANCEL_BITFLIPS; + err = MOVE_TARGET_BITFLIPS; goto out_unlock_buf; } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index bd6120c62c55..b162790790a9 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -118,7 +118,7 @@ enum { * PEB * MOVE_TARGET_WR_ERR: canceled because there was a write error to the target * PEB - * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the + * MOVE_TARGET_BITFLIPS: canceled because a bit-flip was detected in the * target PEB * MOVE_RETRY: retry scrubbing the PEB */ @@ -127,7 +127,7 @@ enum { MOVE_SOURCE_RD_ERR, MOVE_TARGET_RD_ERR, MOVE_TARGET_WR_ERR, - MOVE_CANCEL_BITFLIPS, + MOVE_TARGET_BITFLIPS, MOVE_RETRY, }; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 512eab07c606..7c1a9bf8ac86 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -798,7 +798,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, scrubbing = 1; goto out_not_moved; } - if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR || + if (err == MOVE_TARGET_BITFLIPS || err == MOVE_TARGET_WR_ERR || err == MOVE_TARGET_RD_ERR) { /* * Target PEB had bit-flips or write error - torture it. -- cgit v1.2.3 From e4521d1117af0a96a6c216086de63aada991ee48 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 24 Apr 2012 06:59:49 +0300 Subject: UBI: always dump the stack on error UBI (and UBIFS) are a bit over-engineered WRT debugging. The idea was to link as few as possible when debugging is disabled, but the downside is that most people produce bug reports which are difficult to understand. This patch weeds out the 'ubi_dbg_dump_stack()' function and turns it into 'dump_stack()' - it is always useful to have stack dump in case of an error. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 5 +---- drivers/mtd/ubi/io.c | 28 ++++++++++++++-------------- drivers/mtd/ubi/scan.c | 2 +- drivers/mtd/ubi/ubi.h | 2 +- drivers/mtd/ubi/wl.c | 6 +++--- 5 files changed, 20 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ead2cd16ba75..aff6499cde47 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -28,14 +28,12 @@ if (unlikely(!(expr))) { \ printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ __func__, __LINE__, current->pid); \ - ubi_dbg_dump_stack(); \ + dump_stack(); \ } \ } while (0) #define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) -#define ubi_dbg_dump_stack() dump_stack() - #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ print_hex_dump(l, ps, pt, r, g, b, len, a) @@ -194,7 +192,6 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) #define dbg_io(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) #define dbg_bld(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -static inline void ubi_dbg_dump_stack(void) { return; } static inline void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { return; } static inline void diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 2614dcc497ee..2c83b80d54cc 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -198,7 +198,7 @@ retry: ubi_err("error %d%s while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, errstr, len, pnum, offset, read); - ubi_dbg_dump_stack(); + dump_stack(); /* * The driver should never return -EBADMSG if it failed to read @@ -284,7 +284,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, if (ubi_dbg_is_write_failure(ubi)) { dbg_err("cannot write %d bytes to PEB %d:%d " "(emulated)", len, pnum, offset); - ubi_dbg_dump_stack(); + dump_stack(); return -EIO; } @@ -293,7 +293,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, if (err) { ubi_err("error %d while writing %d bytes to PEB %d:%d, written " "%zd bytes", err, len, pnum, offset, written); - ubi_dbg_dump_stack(); + dump_stack(); ubi_dbg_dump_flash(ubi, pnum, offset, len); } else ubi_assert(written == len); @@ -370,7 +370,7 @@ retry: goto retry; } ubi_err("cannot erase PEB %d, error %d", pnum, err); - ubi_dbg_dump_stack(); + dump_stack(); return err; } @@ -388,7 +388,7 @@ retry: goto retry; } ubi_err("cannot erase PEB %d", pnum); - ubi_dbg_dump_stack(); + dump_stack(); return -EIO; } @@ -723,7 +723,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi, bad: ubi_err("bad EC header"); ubi_dbg_dump_ec_hdr(ec_hdr); - ubi_dbg_dump_stack(); + dump_stack(); return 1; } @@ -999,7 +999,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, bad: ubi_err("bad VID header"); ubi_dbg_dump_vid_hdr(vid_hdr); - ubi_dbg_dump_stack(); + dump_stack(); return 1; } @@ -1154,7 +1154,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) return err; ubi_err("paranoid check failed for PEB %d", pnum); - ubi_dbg_dump_stack(); + dump_stack(); return err > 0 ? -EINVAL : err; } @@ -1193,7 +1193,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, fail: ubi_dbg_dump_ec_hdr(ec_hdr); - ubi_dbg_dump_stack(); + dump_stack(); return -EINVAL; } @@ -1228,7 +1228,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); ubi_err("paranoid check failed for PEB %d", pnum); ubi_dbg_dump_ec_hdr(ec_hdr); - ubi_dbg_dump_stack(); + dump_stack(); err = -EINVAL; goto exit; } @@ -1276,7 +1276,7 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, fail: ubi_err("paranoid check failed for PEB %d", pnum); ubi_dbg_dump_vid_hdr(vid_hdr); - ubi_dbg_dump_stack(); + dump_stack(); return -EINVAL; } @@ -1316,7 +1316,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) "read %#08x", pnum, crc, hdr_crc); ubi_err("paranoid check failed for PEB %d", pnum); ubi_dbg_dump_vid_hdr(vid_hdr); - ubi_dbg_dump_stack(); + dump_stack(); err = -EINVAL; goto exit; } @@ -1381,7 +1381,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf1 + i, dump_len, 1); - ubi_dbg_dump_stack(); + dump_stack(); err = -EINVAL; goto out_free; } @@ -1444,7 +1444,7 @@ fail: print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); err = -EINVAL; error: - ubi_dbg_dump_stack(); + dump_stack(); vfree(buf); return err; } diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 857e04f1e83c..39038a79d165 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1598,7 +1598,7 @@ bad_vid_hdr: ubi_dbg_dump_vid_hdr(vidh); out: - ubi_dbg_dump_stack(); + dump_stack(); return -EINVAL; } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index b162790790a9..4f5c9f136519 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -667,7 +667,7 @@ static inline void ubi_ro_mode(struct ubi_device *ubi) if (!ubi->ro_mode) { ubi->ro_mode = 1; ubi_warn("switch to read-only mode"); - ubi_dbg_dump_stack(); + dump_stack(); } } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 7c1a9bf8ac86..b0a6d53ef047 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1603,7 +1603,7 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) if (ec != read_ec) { ubi_err("paranoid check failed for PEB %d", pnum); ubi_err("read EC is %lld, should be %d", read_ec, ec); - ubi_dbg_dump_stack(); + dump_stack(); err = 1; } else err = 0; @@ -1634,7 +1634,7 @@ static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ", e->pnum, e->ec, root); - ubi_dbg_dump_stack(); + dump_stack(); return -EINVAL; } @@ -1662,7 +1662,7 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi, ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue", e->pnum, e->ec); - ubi_dbg_dump_stack(); + dump_stack(); return -EINVAL; } -- cgit v1.2.3 From e384cc0241da234f480408c8fe4411f15f40f867 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 24 Apr 2012 07:10:33 +0300 Subject: UBI: always dump flash contents in case of errors UBI (and UBIFS) are a bit over-engineered WRT debugging. The idea was to link as few as possible when debugging is disabled, but the downside is that most people produce bug reports which are difficult to understand. Always dump the flash contents in case of errors, not only when debugging is enabled. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Makefile | 3 +- drivers/mtd/ubi/debug.c | 75 ++++++++++++++++++++++-------------------------- drivers/mtd/ubi/debug.h | 5 ++-- drivers/mtd/ubi/io.c | 4 +-- 4 files changed, 40 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index c9302a5452b0..da71655e42db 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_MTD_UBI) += ubi.o ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o scan.o -ubi-y += misc.o +ubi-y += misc.o debug.o -ubi-$(CONFIG_MTD_UBI_DEBUG) += debug.o obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index ab80c0debac8..4f94cf6e0f47 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -18,19 +18,46 @@ * Author: Artem Bityutskiy (Битюцкий Артём) */ -/* - * Here we keep all the UBI debugging stuff which should normally be disabled - * and compiled-out, but it is extremely helpful when hunting bugs or doing big - * changes. - */ - -#ifdef CONFIG_MTD_UBI_DEBUG - #include "ubi.h" #include #include #include + +/** + * ubi_dump_flash - dump a region of flash. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to dump + * @offset: the starting offset within the physical eraseblock to dump + * @len: the length of the region to dump + */ +void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) +{ + int err; + size_t read; + void *buf; + loff_t addr = (loff_t)pnum * ubi->peb_size + offset; + + buf = vmalloc(len); + if (!buf) + return; + err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); + if (err && err != -EUCLEAN) { + ubi_err("error %d while reading %d bytes from PEB %d:%d, " + "read %zd bytes", err, len, pnum, offset, read); + goto out; + } + + ubi_msg("dumping %d bytes of data from PEB %d, offset %d", + len, pnum, offset); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); +out: + vfree(buf); + return; +} + +#ifdef CONFIG_MTD_UBI_DEBUG + /** * ubi_dbg_dump_ec_hdr - dump an erase counter header. * @ec_hdr: the erase counter header to dump @@ -199,38 +226,6 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm); } -/** - * ubi_dbg_dump_flash - dump a region of flash. - * @ubi: UBI device description object - * @pnum: the physical eraseblock number to dump - * @offset: the starting offset within the physical eraseblock to dump - * @len: the length of the region to dump - */ -void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) -{ - int err; - size_t read; - void *buf; - loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - - buf = vmalloc(len); - if (!buf) - return; - err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); - if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, " - "read %zd bytes", err, len, pnum, offset, read); - goto out; - } - - dbg_msg("dumping %d bytes of data from PEB %d, offset %d", - len, pnum, offset); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); -out: - vfree(buf); - return; -} - /** * ubi_debugging_init_dev - initialize debugging for an UBI device. * @ubi: UBI device description object diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index aff6499cde47..4bce78dc5226 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -21,6 +21,8 @@ #ifndef __UBI_DEBUG_H__ #define __UBI_DEBUG_H__ +void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); + #ifdef CONFIG_MTD_UBI_DEBUG #include @@ -63,7 +65,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); 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_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len); @@ -205,8 +206,6 @@ static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type) { return; } static inline void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; } -static inline void ubi_dbg_dump_flash(struct ubi_device *ubi, - int pnum, int offset, int len) { return; } static inline void ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, int g, const void *b, size_t len, bool a) { return; } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 2c83b80d54cc..e6c685efccc3 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -294,7 +294,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, ubi_err("error %d while writing %d bytes to PEB %d:%d, written " "%zd bytes", err, len, pnum, offset, written); dump_stack(); - ubi_dbg_dump_flash(ubi, pnum, offset, len); + ubi_dump_flash(ubi, pnum, offset, len); } else ubi_assert(written == len); @@ -564,7 +564,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) */ ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", pnum, err, err1); - ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size); + ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); return -EIO; } -- cgit v1.2.3 From b0d727f4e342c7932c23286a380f40f555f638ac Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 25 Apr 2012 09:02:44 +0300 Subject: UBI: always dump VID and EC headers in case of errors UBI (and UBIFS) are a bit over-engineered WRT debugging. The idea was to link as few as possible when debugging is disabled, but the downside is that most people produce bug reports which are difficult to understand. Always dump the VID and EC headers' contents in case of errors when it is helpful. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 12 ++++++------ drivers/mtd/ubi/debug.h | 8 ++------ drivers/mtd/ubi/io.c | 20 ++++++++++---------- drivers/mtd/ubi/scan.c | 12 ++++++------ 4 files changed, 24 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 4f94cf6e0f47..0321820092e9 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -56,13 +56,11 @@ out: return; } -#ifdef CONFIG_MTD_UBI_DEBUG - /** - * ubi_dbg_dump_ec_hdr - dump an erase counter header. + * ubi_dump_ec_hdr - dump an erase counter header. * @ec_hdr: the erase counter header to dump */ -void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) +void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { printk(KERN_DEBUG "Erase counter header dump:\n"); printk(KERN_DEBUG "\tmagic %#08x\n", @@ -84,10 +82,10 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) } /** - * ubi_dbg_dump_vid_hdr - dump a volume identifier header. + * ubi_dump_vid_hdr - dump a volume identifier header. * @vid_hdr: the volume identifier header to dump */ -void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) +void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { printk(KERN_DEBUG "Volume identifier header dump:\n"); printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); @@ -108,6 +106,8 @@ void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) vid_hdr, UBI_VID_HDR_SIZE, 1); } +#ifdef CONFIG_MTD_UBI_DEBUG + /** * ubi_dbg_dump_vol_info- dump volume information. * @vol: UBI volume description object diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 4bce78dc5226..b8672c947bb5 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -22,6 +22,8 @@ #define __UBI_DEBUG_H__ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); +void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); +void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); #ifdef CONFIG_MTD_UBI_DEBUG #include @@ -58,8 +60,6 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); /* Initialization and build messages */ #define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__) -void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); -void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dbg_dump_vol_info(const struct ubi_volume *vol); void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); @@ -193,10 +193,6 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) #define dbg_io(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) #define dbg_bld(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -static inline void -ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { return; } -static inline void -ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { return; } static inline void ubi_dbg_dump_vol_info(const struct ubi_volume *vol) { return; } static inline void diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index e6c685efccc3..b38667237450 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -722,7 +722,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi, bad: ubi_err("bad EC header"); - ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dump_ec_hdr(ec_hdr); dump_stack(); return 1; } @@ -804,7 +804,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (verbose) { ubi_warn("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_EC_HDR_MAGIC); - ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dump_ec_hdr(ec_hdr); } dbg_bld("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_EC_HDR_MAGIC); @@ -818,7 +818,7 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (verbose) { ubi_warn("bad EC header CRC at PEB %d, calculated " "%#08x, read %#08x", pnum, crc, hdr_crc); - ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dump_ec_hdr(ec_hdr); } dbg_bld("bad EC header CRC at PEB %d, calculated " "%#08x, read %#08x", pnum, crc, hdr_crc); @@ -998,7 +998,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, bad: ubi_err("bad VID header"); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); dump_stack(); return 1; } @@ -1055,7 +1055,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (verbose) { ubi_warn("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_VID_HDR_MAGIC); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); } dbg_bld("bad magic number at PEB %d: %08x instead of " "%08x", pnum, magic, UBI_VID_HDR_MAGIC); @@ -1069,7 +1069,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (verbose) { ubi_warn("bad CRC at PEB %d, calculated %#08x, " "read %#08x", pnum, crc, hdr_crc); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); } dbg_bld("bad CRC at PEB %d, calculated %#08x, " "read %#08x", pnum, crc, hdr_crc); @@ -1192,7 +1192,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, return 0; fail: - ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dump_ec_hdr(ec_hdr); dump_stack(); return -EINVAL; } @@ -1227,7 +1227,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) if (hdr_crc != crc) { ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); ubi_err("paranoid check failed for PEB %d", pnum); - ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dump_ec_hdr(ec_hdr); dump_stack(); err = -EINVAL; goto exit; @@ -1275,7 +1275,7 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, fail: ubi_err("paranoid check failed for PEB %d", pnum); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); dump_stack(); return -EINVAL; @@ -1315,7 +1315,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " "read %#08x", pnum, crc, hdr_crc); ubi_err("paranoid check failed for PEB %d", pnum); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); dump_stack(); err = -EINVAL; goto exit; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 39038a79d165..24a20a520156 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -230,7 +230,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, bad: ubi_err("inconsistent VID header at PEB %d", pnum); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); ubi_dbg_dump_sv(sv); return -EINVAL; } @@ -511,7 +511,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, ubi_err("two LEBs with same sequence number %llu", sqnum); ubi_dbg_dump_seb(seb, 0); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); return -EINVAL; } @@ -814,7 +814,7 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, ubi_err("PEB %d contains corrupted VID header, and the data does not " "contain all 0xFF, this may be a non-UBI PEB or a severe VID " "header corruption which requires manual inspection", pnum); - ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dump_vid_hdr(vid_hdr); dbg_msg("hexdump of PEB %d offset %d, length %d", pnum, ubi->leb_start, ubi->leb_size); ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, @@ -911,7 +911,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, */ ubi_err("erase counter overflow, max is %d", UBI_MAX_ERASECOUNTER); - ubi_dbg_dump_ec_hdr(ech); + ubi_dump_ec_hdr(ech); return -EINVAL; } @@ -933,7 +933,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, ubi->image_seq != image_seq) { ubi_err("bad image sequence number %d in PEB %d, " "expected %d", image_seq, pnum, ubi->image_seq); - ubi_dbg_dump_ec_hdr(ech); + ubi_dump_ec_hdr(ech); return -EINVAL; } } @@ -1595,7 +1595,7 @@ bad_sv: bad_vid_hdr: ubi_err("bad scanning information about volume %d", sv->vol_id); ubi_dbg_dump_sv(sv); - ubi_dbg_dump_vid_hdr(vidh); + ubi_dump_vid_hdr(vidh); out: dump_stack(); -- cgit v1.2.3 From 36ce2c92a99cc0430f0a39482bda89f1f3741508 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 25 Apr 2012 09:15:38 +0300 Subject: UBI: always warn if case of I/O errors Currently UBI silently retries I/O operation in case of errors. This patch makes it emit a warning before retrying. This should allow users notice issues earlier. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/io.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index b38667237450..99212245713a 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -189,9 +189,9 @@ retry: } if (retries++ < UBI_IO_RETRIES) { - dbg_io("error %d%s while reading %d bytes from PEB " - "%d:%d, read only %zd bytes, retry", - err, errstr, len, pnum, offset, read); + ubi_warn("error %d%s while reading %d bytes from PEB " + "%d:%d, read only %zd bytes, retry", + err, errstr, len, pnum, offset, read); yield(); goto retry; } @@ -364,8 +364,8 @@ retry: err = ubi->mtd->erase(ubi->mtd, &ei); if (err) { if (retries++ < UBI_IO_RETRIES) { - dbg_io("error %d while erasing PEB %d, retry", - err, pnum); + ubi_warn("error %d while erasing PEB %d, retry", + err, pnum); yield(); goto retry; } @@ -383,7 +383,7 @@ retry: if (ei.state == MTD_ERASE_FAILED) { if (retries++ < UBI_IO_RETRIES) { - dbg_io("error while erasing PEB %d, retry", pnum); + ubi_warn("error while erasing PEB %d, retry", pnum); yield(); goto retry; } -- cgit v1.2.3 From b44bf03a57d7b410d2feb3c91efc914a4e6e47fe Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 8 May 2012 00:47:20 +0200 Subject: UBI: remove superfluous "!!" operation !!(x < y) and (x < y) are identical expressions. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 24a20a520156..4b1eb88bb99f 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -337,7 +337,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, } /* Obviously the LEB with lower sequence counter is older */ - second_is_newer = !!(sqnum2 > seb->sqnum); + second_is_newer = (sqnum2 > seb->sqnum); /* * Now we know which copy is newer. If the copy flag of the PEB with -- cgit v1.2.3 From b4a7748a1841cfa2d37a93e0066c2bd0038ada39 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 14 May 2012 17:55:51 +0200 Subject: UBI: Kill data type hint We do not need this feature and to our shame it even was not working and there was a bug found very recently. -- Artem Bityutskiy Without the data type hint UBI2 (fastmap) will be easier to implement. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 8 ++------ drivers/mtd/ubi/eba.c | 20 ++++++++----------- drivers/mtd/ubi/gluebi.c | 2 +- drivers/mtd/ubi/kapi.c | 30 +++++++---------------------- drivers/mtd/ubi/ubi.h | 12 ++++-------- drivers/mtd/ubi/upd.c | 12 ++++-------- drivers/mtd/ubi/vtbl.c | 4 ++-- drivers/mtd/ubi/wl.c | 50 ++++++++---------------------------------------- 8 files changed, 36 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index ad76592fb2f4..f4061126926b 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -334,8 +334,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, break; } - err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len, - UBI_UNKNOWN); + err = ubi_eba_write_leb(ubi, vol, lnum, tbuf, off, len); if (err) break; @@ -477,9 +476,6 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, if (req.lnum < 0 || req.lnum >= vol->reserved_pebs || req.bytes < 0 || req.lnum >= vol->usable_leb_size) break; - if (req.dtype != UBI_LONGTERM && req.dtype != UBI_SHORTTERM && - req.dtype != UBI_UNKNOWN) - break; err = get_exclusive(desc); if (err < 0) @@ -532,7 +528,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, err = -EFAULT; break; } - err = ubi_leb_map(desc, req.lnum, req.dtype); + err = ubi_leb_map(desc, req.lnum); break; } diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 9b7f87ea3285..9eff9386f7b4 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -507,7 +507,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, return -ENOMEM; retry: - new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); + new_pnum = ubi_wl_get_peb(ubi); if (new_pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); return new_pnum; @@ -585,7 +585,6 @@ write_error: * @buf: the data to write * @offset: offset within the logical eraseblock where to write * @len: how many bytes to write - * @dtype: data type * * This function writes data to logical eraseblock @lnum of a dynamic volume * @vol. Returns zero in case of success and a negative error code in case @@ -593,7 +592,7 @@ write_error: * written to the flash media, but may be some garbage. */ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, - const void *buf, int offset, int len, int dtype) + const void *buf, int offset, int len) { int err, pnum, tries = 0, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; @@ -641,7 +640,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, vid_hdr->data_pad = cpu_to_be32(vol->data_pad); retry: - pnum = ubi_wl_get_peb(ubi, dtype); + pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); @@ -707,7 +706,6 @@ write_error: * @lnum: logical eraseblock number * @buf: data to write * @len: how many bytes to write - * @dtype: data type * @used_ebs: how many logical eraseblocks will this volume contain * * This function writes data to logical eraseblock @lnum of static volume @@ -724,8 +722,7 @@ write_error: * code in case of failure. */ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, - int lnum, const void *buf, int len, int dtype, - int used_ebs) + int lnum, const void *buf, int len, int used_ebs) { int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; @@ -763,7 +760,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, vid_hdr->data_crc = cpu_to_be32(crc); retry: - pnum = ubi_wl_get_peb(ubi, dtype); + pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); @@ -827,7 +824,6 @@ write_error: * @lnum: logical eraseblock number * @buf: data to write * @len: how many bytes to write - * @dtype: data type * * This function changes the contents of a logical eraseblock atomically. @buf * has to contain new logical eraseblock data, and @len - the length of the @@ -839,7 +835,7 @@ write_error: * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. */ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, - int lnum, const void *buf, int len, int dtype) + int lnum, const void *buf, int len) { int err, pnum, tries = 0, vol_id = vol->vol_id; struct ubi_vid_hdr *vid_hdr; @@ -856,7 +852,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, err = ubi_eba_unmap_leb(ubi, vol, lnum); if (err) return err; - return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); + return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0); } vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); @@ -881,7 +877,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, vid_hdr->data_crc = cpu_to_be32(crc); retry: - pnum = ubi_wl_get_peb(ubi, dtype); + pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { err = pnum; goto out_leb_unlock; diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 941bc3c05d6e..9eb07fb92ad8 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -238,7 +238,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, if (to_write > total_written) to_write = total_written; - err = ubi_write(gluebi->desc, lnum, buf, offs, to_write); + err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write); if (err) break; diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index d39716e5b204..7345a878b24a 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -426,11 +426,9 @@ EXPORT_SYMBOL_GPL(ubi_leb_read); * @buf: data to write * @offset: offset within the logical eraseblock where to write * @len: how many bytes to write - * @dtype: expected data type * * This function writes @len bytes of data from @buf to offset @offset of - * logical eraseblock @lnum. The @dtype argument describes expected lifetime of - * the data. + * logical eraseblock @lnum. * * This function takes care of physical eraseblock write failures. If write to * the physical eraseblock write operation fails, the logical eraseblock is @@ -447,7 +445,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_read); * returns immediately with %-EBADF code. */ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, - int offset, int len, int dtype) + int offset, int len) { struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; @@ -466,17 +464,13 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1)) return -EINVAL; - if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && - dtype != UBI_UNKNOWN) - return -EINVAL; - if (vol->upd_marker) return -EBADF; if (len == 0) return 0; - return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len, dtype); + return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len); } EXPORT_SYMBOL_GPL(ubi_leb_write); @@ -486,7 +480,6 @@ EXPORT_SYMBOL_GPL(ubi_leb_write); * @lnum: logical eraseblock number to change * @buf: data to write * @len: how many bytes to write - * @dtype: expected data type * * This function changes the contents of a logical eraseblock atomically. @buf * has to contain new logical eraseblock data, and @len - the length of the @@ -497,7 +490,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_write); * code in case of failure. */ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, - int len, int dtype) + int len) { struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; @@ -515,17 +508,13 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, len > vol->usable_leb_size || len & (ubi->min_io_size - 1)) return -EINVAL; - if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && - dtype != UBI_UNKNOWN) - return -EINVAL; - if (vol->upd_marker) return -EBADF; if (len == 0) return 0; - return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype); + return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len); } EXPORT_SYMBOL_GPL(ubi_leb_change); @@ -626,7 +615,6 @@ EXPORT_SYMBOL_GPL(ubi_leb_unmap); * ubi_leb_map - map logical eraseblock to a physical eraseblock. * @desc: volume descriptor * @lnum: logical eraseblock number - * @dtype: expected data type * * This function maps an un-mapped logical eraseblock @lnum to a physical * eraseblock. This means, that after a successful invocation of this @@ -639,7 +627,7 @@ EXPORT_SYMBOL_GPL(ubi_leb_unmap); * eraseblock is already mapped, and other negative error codes in case of * other failures. */ -int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) +int ubi_leb_map(struct ubi_volume_desc *desc, int lnum) { struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; @@ -652,17 +640,13 @@ int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) if (lnum < 0 || lnum >= vol->reserved_pebs) return -EINVAL; - if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && - dtype != UBI_UNKNOWN) - return -EINVAL; - if (vol->upd_marker) return -EBADF; if (vol->eba_tbl[lnum] >= 0) return -EBADMSG; - return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); + return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0); } EXPORT_SYMBOL_GPL(ubi_leb_map); diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 4f5c9f136519..75b9f1c61b78 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -222,8 +222,6 @@ struct ubi_volume_desc; * @upd_ebs: how many eraseblocks are expected to be updated * @ch_lnum: LEB number which is being changing by the atomic LEB change * operation - * @ch_dtype: data persistency type which is being changing by the atomic LEB - * change operation * @upd_bytes: how many bytes are expected to be received for volume update or * atomic LEB change * @upd_received: how many bytes were already received for volume update or @@ -270,7 +268,6 @@ struct ubi_volume { int upd_ebs; int ch_lnum; - int ch_dtype; long long upd_bytes; long long upd_received; void *upd_buf; @@ -525,18 +522,17 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, void *buf, int offset, int len, int check); int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, - const void *buf, int offset, int len, int dtype); + const void *buf, int offset, int len); int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, - int lnum, const void *buf, int len, int dtype, - int used_ebs); + int lnum, const void *buf, int len, int used_ebs); int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, - int lnum, const void *buf, int len, int dtype); + int lnum, const void *buf, int len); int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr); int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); /* wl.c */ -int ubi_wl_get_peb(struct ubi_device *ubi, int dtype); +int ubi_wl_get_peb(struct ubi_device *ubi); int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); int ubi_wl_flush(struct ubi_device *ubi); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 425bf5a3edd4..11a28f9ce0db 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -186,14 +186,12 @@ int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, dbg_gen("start changing LEB %d:%d, %u bytes", vol->vol_id, req->lnum, req->bytes); if (req->bytes == 0) - return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0, - req->dtype); + return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0); vol->upd_bytes = req->bytes; vol->upd_received = 0; vol->changing_leb = 1; vol->ch_lnum = req->lnum; - vol->ch_dtype = req->dtype; vol->upd_buf = vmalloc(req->bytes); if (!vol->upd_buf) @@ -246,8 +244,7 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, return 0; } - err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len, - UBI_UNKNOWN); + err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len); } else { /* * When writing static volume, and this is the last logical @@ -259,8 +256,7 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, * contain zeros, not random trash. */ memset(buf + len, 0, vol->usable_leb_size - len); - err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, - UBI_UNKNOWN, used_ebs); + err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs); } return err; @@ -421,7 +417,7 @@ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, len - vol->upd_bytes); len = ubi_calc_data_len(ubi, vol->upd_buf, len); err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum, - vol->upd_buf, len, UBI_UNKNOWN); + vol->upd_buf, len); if (err) return err; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 118b966e0556..48ad8a2d6317 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -106,7 +106,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, return err; err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size, UBI_LONGTERM); + ubi->vtbl_size); if (err) return err; } @@ -158,7 +158,7 @@ int ubi_vtbl_rename_volumes(struct ubi_device *ubi, return err; err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, - ubi->vtbl_size, UBI_LONGTERM); + ubi->vtbl_size); if (err) return err; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b0a6d53ef047..f0bc10743bc0 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -383,19 +383,15 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) /** * ubi_wl_get_peb - get a physical eraseblock. * @ubi: UBI device description object - * @dtype: type of data which will be stored in this physical eraseblock * * This function returns a physical eraseblock in case of success and a * negative error code in case of failure. Might sleep. */ -int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) +int ubi_wl_get_peb(struct ubi_device *ubi) { int err; struct ubi_wl_entry *e, *first, *last; - ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || - dtype == UBI_UNKNOWN); - retry: spin_lock(&ubi->wl_lock); if (!ubi->free.rb_node) { @@ -413,43 +409,13 @@ retry: goto retry; } - switch (dtype) { - case UBI_LONGTERM: - /* - * For long term data we pick a physical eraseblock with high - * erase counter. But the highest erase counter we can pick is - * bounded by the the lowest erase counter plus - * %WL_FREE_MAX_DIFF. - */ - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); - break; - case UBI_UNKNOWN: - /* - * For unknown data we pick a physical eraseblock with medium - * erase counter. But we by no means can pick a physical - * eraseblock with erase counter greater or equivalent than the - * lowest erase counter plus %WL_FREE_MAX_DIFF/2. - */ - first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, - u.rb); - last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); - - if (last->ec - first->ec < WL_FREE_MAX_DIFF) - e = rb_entry(ubi->free.rb_node, - struct ubi_wl_entry, u.rb); - else - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); - break; - case UBI_SHORTTERM: - /* - * For short term data we pick a physical eraseblock with the - * lowest erase counter as we expect it will be erased soon. - */ - e = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); - break; - default: - BUG(); - } + first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); + last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); + + if (last->ec - first->ec < WL_FREE_MAX_DIFF) + e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb); + else + e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); paranoid_check_in_wl_tree(ubi, e, &ubi->free); -- cgit v1.2.3 From 3f0b81760a5843489ca29bbf2cd1c7999609e75a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 14 May 2012 19:49:35 +0300 Subject: UBI: amend commentaries WRT dtype Richard removed the "dtype" hint, but few commentaries were left and this patch removes them. I've also added a better description about the "dtype" field in the ubi-user.h for people who may ever wonder what was that dtype thing about. This patch also adds an important note that it is better to use value "3" for the "dtype" field. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index f0bc10743bc0..64ce9930dacb 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -41,12 +41,6 @@ * physical eraseblocks with low erase counter to free physical eraseblocks * with high erase counter. * - * The 'ubi_wl_get_peb()' function accepts data type hints which help to pick - * an "optimal" physical eraseblock. For example, when it is known that the - * physical eraseblock will be "put" soon because it contains short-term data, - * the WL sub-system may pick a free physical eraseblock with low erase - * counter, and so forth. - * * If the WL sub-system fails to erase a physical eraseblock, it marks it as * bad. * @@ -70,8 +64,7 @@ * to the user; instead, we first want to let users fill them up with data; * * o there is a chance that the user will put the physical eraseblock very - * soon, so it makes sense not to move it for some time, but wait; this is - * especially important in case of "short term" physical eraseblocks. + * soon, so it makes sense not to move it for some time, but wait. * * Physical eraseblocks stay protected only for limited time. But the "time" is * measured in erase cycles in this case. This is implemented with help of the -- cgit v1.2.3 From 5378ace978899a25d3979b90da6d09f6da786686 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 17:53:17 +0300 Subject: UBI: rename ubi_dbg_dump_vol_info I am going to remove the "UBI debugging" compilation option and make the debugging stuff to be always compiled it. This patch is a preparation which renames 'ubi_dbg_dump_vol_info()' to 'ubi_dump_vol_info()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 4 ++-- drivers/mtd/ubi/vmt.c | 2 +- drivers/mtd/ubi/vtbl.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 0321820092e9..d3be75bf3c62 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -109,10 +109,10 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) #ifdef CONFIG_MTD_UBI_DEBUG /** - * ubi_dbg_dump_vol_info- dump volume information. + * ubi_dump_vol_info - dump volume information. * @vol: UBI volume description object */ -void ubi_dbg_dump_vol_info(const struct ubi_volume *vol) +void ubi_dump_vol_info(const struct ubi_volume *vol) { printk(KERN_DEBUG "Volume information dump:\n"); printk(KERN_DEBUG "\tvol_id %d\n", vol->vol_id); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index b8672c947bb5..ca36f2db2b0e 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -60,7 +60,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); /* Initialization and build messages */ #define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__) -void ubi_dbg_dump_vol_info(const struct ubi_volume *vol); +void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); @@ -194,7 +194,7 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) #define dbg_bld(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) static inline void -ubi_dbg_dump_vol_info(const struct ubi_volume *vol) { return; } +ubi_dump_vol_info(const struct ubi_volume *vol) { return; } static inline void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } static inline void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) { return; } diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 97e093d19672..3c844688d58e 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -854,7 +854,7 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id) fail: ubi_err("paranoid check failed for volume %d", vol_id); if (vol) - ubi_dbg_dump_vol_info(vol); + ubi_dump_vol_info(vol); ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); dump_stack(); spin_unlock(&ubi->volumes_lock); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 48ad8a2d6317..fabaa8392bd7 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -701,7 +701,7 @@ static int check_sv(const struct ubi_volume *vol, bad: ubi_err("bad scanning information, error %d", err); ubi_dbg_dump_sv(sv); - ubi_dbg_dump_vol_info(vol); + ubi_dump_vol_info(vol); return -EINVAL; } -- cgit v1.2.3 From ef98d5f459e59c36a68afaea6a512b70ce0cf681 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 17:56:50 +0300 Subject: UBI: rename ubi_dbg_dump_vtbl_record I am going to remove the "UBI debugging" compilation option and make the debugging stuff to be always compiled it. This patch is a preparation which renames 'ubi_dbg_dump_vtbl_record()' to 'ubi_dump_vtbl_record()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 4 ++-- drivers/mtd/ubi/vmt.c | 2 +- drivers/mtd/ubi/vtbl.c | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index d3be75bf3c62..f6865bcbef0d 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -139,11 +139,11 @@ void ubi_dump_vol_info(const struct ubi_volume *vol) } /** - * ubi_dbg_dump_vtbl_record - dump a &struct ubi_vtbl_record object. + * ubi_dump_vtbl_record - dump a &struct ubi_vtbl_record object. * @r: the object to dump * @idx: volume table index */ -void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) +void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { int name_len = be16_to_cpu(r->name_len); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ca36f2db2b0e..9728da4444cc 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -61,7 +61,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); #define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__) void ubi_dump_vol_info(const struct ubi_volume *vol); -void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); +void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); 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); @@ -196,7 +196,7 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) static inline void ubi_dump_vol_info(const struct ubi_volume *vol) { return; } static inline void -ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } +ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } static inline void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) { return; } static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type) { return; } diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 3c844688d58e..b915b263c158 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -855,7 +855,7 @@ fail: ubi_err("paranoid check failed for volume %d", vol_id); if (vol) ubi_dump_vol_info(vol); - ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); + ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); dump_stack(); spin_unlock(&ubi->volumes_lock); return -EINVAL; diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fabaa8392bd7..659fa003f2d7 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -197,7 +197,7 @@ static int vtbl_check(const struct ubi_device *ubi, if (be32_to_cpu(vtbl[i].crc) != crc) { ubi_err("bad CRC at record %u: %#08x, not %#08x", i, crc, be32_to_cpu(vtbl[i].crc)); - ubi_dbg_dump_vtbl_record(&vtbl[i], i); + ubi_dump_vtbl_record(&vtbl[i], i); return 1; } @@ -277,8 +277,8 @@ static int vtbl_check(const struct ubi_device *ubi, !strncmp(vtbl[i].name, vtbl[n].name, len1)) { ubi_err("volumes %d and %d have the same name" " \"%s\"", i, n, vtbl[i].name); - ubi_dbg_dump_vtbl_record(&vtbl[i], i); - ubi_dbg_dump_vtbl_record(&vtbl[n], n); + ubi_dump_vtbl_record(&vtbl[i], i); + ubi_dump_vtbl_record(&vtbl[n], n); return -EINVAL; } } @@ -288,7 +288,7 @@ static int vtbl_check(const struct ubi_device *ubi, bad: ubi_err("volume table check failed: record %d, error %d", i, err); - ubi_dbg_dump_vtbl_record(&vtbl[i], i); + ubi_dump_vtbl_record(&vtbl[i], i); return -EINVAL; } -- cgit v1.2.3 From 6fdc58043c888e9c448293bea0a0f6045419c3c8 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 17:59:36 +0300 Subject: UBI: rename ubi_dbg_dump_sv I am going to remove the "UBI debugging" compilation option and make the debugging stuff to be always compiled it. This patch is a preparation which renames 'ubi_dbg_dump_sv()' to 'ubi_dump_sv()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 4 ++-- drivers/mtd/ubi/scan.c | 8 ++++---- drivers/mtd/ubi/vtbl.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index f6865bcbef0d..dee765de18f6 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -173,10 +173,10 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) } /** - * ubi_dbg_dump_sv - dump a &struct ubi_scan_volume object. + * ubi_dump_sv - dump a &struct ubi_scan_volume object. * @sv: the object to dump */ -void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) +void ubi_dump_sv(const struct ubi_scan_volume *sv) { printk(KERN_DEBUG "Volume scanning information dump:\n"); printk(KERN_DEBUG "\tvol_id %d\n", sv->vol_id); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 9728da4444cc..5e3d4e88d7be 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -62,7 +62,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); -void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); +void ubi_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); int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); @@ -197,7 +197,7 @@ static inline void ubi_dump_vol_info(const struct ubi_volume *vol) { return; } static inline void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } -static inline void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) { return; } +static inline void ubi_dump_sv(const struct ubi_scan_volume *sv) { return; } static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type) { return; } static inline void diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 4b1eb88bb99f..ba31324e0bcd 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -231,7 +231,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, bad: ubi_err("inconsistent VID header at PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); - ubi_dbg_dump_sv(sv); + ubi_dump_sv(sv); return -EINVAL; } @@ -1584,17 +1584,17 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) bad_seb: ubi_err("bad scanning information about LEB %d", seb->lnum); ubi_dbg_dump_seb(seb, 0); - ubi_dbg_dump_sv(sv); + ubi_dump_sv(sv); goto out; bad_sv: ubi_err("bad scanning information about volume %d", sv->vol_id); - ubi_dbg_dump_sv(sv); + ubi_dump_sv(sv); goto out; bad_vid_hdr: ubi_err("bad scanning information about volume %d", sv->vol_id); - ubi_dbg_dump_sv(sv); + ubi_dump_sv(sv); ubi_dump_vid_hdr(vidh); out: diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 659fa003f2d7..8ea216e57c10 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -700,7 +700,7 @@ static int check_sv(const struct ubi_volume *vol, bad: ubi_err("bad scanning information, error %d", err); - ubi_dbg_dump_sv(sv); + ubi_dump_sv(sv); ubi_dump_vol_info(vol); return -EINVAL; } -- cgit v1.2.3 From c24231afd72ccd794abdf8c4c0f11055cbda6fcc Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:01:58 +0300 Subject: UBI: rename ubi_dbg_dump_seb I am going to remove the "UBI debugging" compilation option and make the debugging stuff to be always compiled it. This patch is a preparation which renames 'ubi_dbg_dump_seb()' to 'ubi_dump_seb()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 6 +++--- drivers/mtd/ubi/scan.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index dee765de18f6..214130530ff4 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -190,11 +190,11 @@ void ubi_dump_sv(const struct ubi_scan_volume *sv) } /** - * ubi_dbg_dump_seb - dump a &struct ubi_scan_leb object. + * ubi_dump_seb - dump a &struct ubi_scan_leb object. * @seb: the object to dump * @type: object type: 0 - not corrupted, 1 - corrupted */ -void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type) +void ubi_dump_seb(const struct ubi_scan_leb *seb, int type) { printk(KERN_DEBUG "eraseblock scanning information dump:\n"); printk(KERN_DEBUG "\tec %d\n", seb->ec); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 5e3d4e88d7be..b897c4ab7dc9 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -63,7 +63,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dump_sv(const struct ubi_scan_volume *sv); -void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); +void ubi_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, @@ -198,8 +198,8 @@ ubi_dump_vol_info(const struct ubi_volume *vol) { return; } static inline void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } static inline void ubi_dump_sv(const struct ubi_scan_volume *sv) { return; } -static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, - int type) { return; } +static inline void ubi_dump_seb(const struct ubi_scan_leb *seb, + int type) { return; } static inline void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; } static inline void diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index ba31324e0bcd..e9a16654c13e 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -510,7 +510,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, if (seb->sqnum == sqnum && sqnum != 0) { ubi_err("two LEBs with same sequence number %llu", sqnum); - ubi_dbg_dump_seb(seb, 0); + ubi_dump_seb(seb, 0); ubi_dump_vid_hdr(vid_hdr); return -EINVAL; } @@ -1583,7 +1583,7 @@ static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) bad_seb: ubi_err("bad scanning information about LEB %d", seb->lnum); - ubi_dbg_dump_seb(seb, 0); + ubi_dump_seb(seb, 0); ubi_dump_sv(sv); goto out; -- cgit v1.2.3 From 581bad99cfcc081db068d5fc12a0d4112cce3f49 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:03:32 +0300 Subject: UBI: rename ubi_dbg_dump_mkvol_req I am going to remove the "UBI debugging" compilation option and make the debugging stuff to be always compiled it. This patch is a preparation which renames 'ubi_dbg_dump_mkvol_req()' to 'ubi_dump_mkvol_req()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index f4061126926b..633ac82bbd22 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -644,7 +644,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, bad: dbg_err("bad volume creation request"); - ubi_dbg_dump_mkvol_req(req); + ubi_dump_mkvol_req(req); return err; } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 214130530ff4..ce067520b1bd 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -207,10 +207,10 @@ void ubi_dump_seb(const struct ubi_scan_leb *seb, int type) } /** - * ubi_dbg_dump_mkvol_req - dump a &struct ubi_mkvol_req object. + * ubi_dump_mkvol_req - dump a &struct ubi_mkvol_req object. * @req: the object to dump */ -void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) +void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) { char nm[17]; diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index b897c4ab7dc9..c98d2c8d3abe 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -64,7 +64,7 @@ void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dump_sv(const struct ubi_scan_volume *sv); void ubi_dump_seb(const struct ubi_scan_leb *seb, int type); -void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); +void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len); @@ -201,7 +201,7 @@ static inline void ubi_dump_sv(const struct ubi_scan_volume *sv) { return; } static inline void ubi_dump_seb(const struct ubi_scan_leb *seb, int type) { return; } static inline void -ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; } +ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; } static inline void ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, int g, const void *b, size_t len, bool a) { return; } -- cgit v1.2.3 From 74321b1a2a81071760eac3fba935ab155ae4eafe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:09:08 +0300 Subject: UBI: remove Kconfig debugging option This patch kills the UBI debugging Kconfig option completely and makes all the debugging stuff to be always compiled-in. It was pain in the neck to maintain this useless option because all users I am aware of have debugging enabled anyway - how else will you diagnose errors otherwise? Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 8 ------- drivers/mtd/ubi/debug.c | 4 ---- drivers/mtd/ubi/debug.h | 63 ------------------------------------------------- drivers/mtd/ubi/io.c | 12 ---------- drivers/mtd/ubi/scan.c | 8 ------- drivers/mtd/ubi/vmt.c | 7 ------ drivers/mtd/ubi/vtbl.c | 8 ------- drivers/mtd/ubi/wl.c | 10 -------- 8 files changed, 120 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 4dcc752a0c0b..738ee8dc16cd 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -52,12 +52,4 @@ config MTD_UBI_GLUEBI work on top of UBI. Do not enable this unless you use legacy software. -config MTD_UBI_DEBUG - bool "UBI debugging" - depends on SYSFS - select DEBUG_FS - select KALLSYMS - help - This option enables UBI debugging. - endif # MTD_UBI diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index ce067520b1bd..3b868104625e 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -106,8 +106,6 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) vid_hdr, UBI_VID_HDR_SIZE, 1); } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * ubi_dump_vol_info - dump volume information. * @vol: UBI volume description object @@ -482,5 +480,3 @@ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { debugfs_remove_recursive(ubi->dbg->dfs_dir); } - -#endif /* CONFIG_MTD_UBI_DEBUG */ diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index c98d2c8d3abe..3e5b60f3fdf1 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -25,7 +25,6 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len); void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); -#ifdef CONFIG_MTD_UBI_DEBUG #include #define ubi_assert(expr) do { \ @@ -166,66 +165,4 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) return 0; } -#else - -/* Use "if (0)" to make compiler check arguments even if debugging is off */ -#define ubi_assert(expr) do { \ - if (0) { \ - printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ - __func__, __LINE__, current->pid); \ - } \ -} while (0) - -#define dbg_err(fmt, ...) do { \ - if (0) \ - ubi_err(fmt, ##__VA_ARGS__); \ -} while (0) - -#define ubi_dbg_msg(fmt, ...) do { \ - if (0) \ - printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \ -} while (0) - -#define dbg_msg(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -#define dbg_gen(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -#define dbg_eba(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -#define dbg_wl(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -#define dbg_io(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) -#define dbg_bld(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__) - -static inline void -ubi_dump_vol_info(const struct ubi_volume *vol) { return; } -static inline void -ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { return; } -static inline void ubi_dump_sv(const struct ubi_scan_volume *sv) { return; } -static inline void ubi_dump_seb(const struct ubi_scan_leb *seb, - int type) { return; } -static inline void -ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) { return; } -static inline void -ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r, - int g, const void *b, size_t len, bool a) { return; } -static inline int ubi_dbg_check_all_ff(struct ubi_device *ubi, - int pnum, int offset, - int len) { return 0; } -static inline int ubi_dbg_check_write(struct ubi_device *ubi, - const void *buf, int pnum, - int offset, int len) { return 0; } - -static inline int ubi_debugging_init_dev(struct ubi_device *ubi) { return 0; } -static inline void ubi_debugging_exit_dev(struct ubi_device *ubi) { return; } -static inline int ubi_debugfs_init(void) { return 0; } -static inline void ubi_debugfs_exit(void) { return; } -static inline int ubi_debugfs_init_dev(struct ubi_device *ubi) { return 0; } -static inline void ubi_debugfs_exit_dev(struct ubi_device *ubi) { return; } - -static inline int -ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) { return 0; } -static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) { return 0; } -static inline int -ubi_dbg_is_write_failure(const struct ubi_device *ubi) { return 0; } -static inline int -ubi_dbg_is_erase_failure(const struct ubi_device *ubi) { return 0; } - -#endif /* !CONFIG_MTD_UBI_DEBUG */ #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 99212245713a..84b8f1c7137b 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -91,7 +91,6 @@ #include #include "ubi.h" -#ifdef CONFIG_MTD_UBI_DEBUG static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, @@ -99,13 +98,6 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, const struct ubi_vid_hdr *vid_hdr); -#else -#define paranoid_check_not_bad(ubi, pnum) 0 -#define paranoid_check_peb_ec_hdr(ubi, pnum) 0 -#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 -#define paranoid_check_peb_vid_hdr(ubi, pnum) 0 -#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 -#endif /** * ubi_io_read - read data from a physical eraseblock. @@ -1132,8 +1124,6 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, return err; } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. * @ubi: UBI device description object @@ -1448,5 +1438,3 @@ error: vfree(buf); return err; } - -#endif /* CONFIG_MTD_UBI_DEBUG */ diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index e9a16654c13e..acb2eba78d53 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -88,11 +88,7 @@ #include #include "ubi.h" -#ifdef CONFIG_MTD_UBI_DEBUG static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); -#else -#define paranoid_check_si(ubi, si) 0 -#endif /* Temporary variables used during scanning */ static struct ubi_ec_hdr *ech; @@ -1329,8 +1325,6 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) kfree(si); } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * paranoid_check_si - check the scanning information. * @ubi: UBI device description object @@ -1601,5 +1595,3 @@ out: dump_stack(); return -EINVAL; } - -#endif /* CONFIG_MTD_UBI_DEBUG */ diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index b915b263c158..4eb85473bebc 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -28,11 +28,7 @@ #include #include "ubi.h" -#ifdef CONFIG_MTD_UBI_DEBUG static int paranoid_check_volumes(struct ubi_device *ubi); -#else -#define paranoid_check_volumes(ubi) 0 -#endif static ssize_t vol_attribute_show(struct device *dev, struct device_attribute *attr, char *buf); @@ -711,8 +707,6 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol) volume_sysfs_close(vol); } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * paranoid_check_volume - check volume information. * @ubi: UBI device description object @@ -882,4 +876,3 @@ static int paranoid_check_volumes(struct ubi_device *ubi) return err; } -#endif diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 8ea216e57c10..e040980000fe 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -62,11 +62,7 @@ #include #include "ubi.h" -#ifdef CONFIG_MTD_UBI_DEBUG static void paranoid_vtbl_check(const struct ubi_device *ubi); -#else -#define paranoid_vtbl_check(ubi) -#endif /* Empty volume table record */ static struct ubi_vtbl_record empty_vtbl_record; @@ -858,8 +854,6 @@ out_free: return err; } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * paranoid_vtbl_check - check volume table. * @ubi: UBI device description object @@ -874,5 +868,3 @@ static void paranoid_vtbl_check(const struct ubi_device *ubi) BUG(); } } - -#endif /* CONFIG_MTD_UBI_DEBUG */ diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 64ce9930dacb..f99dbd084838 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -155,18 +155,12 @@ struct ubi_work { int torture; }; -#ifdef CONFIG_MTD_UBI_DEBUG static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root); static int paranoid_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e); -#else -#define paranoid_check_ec(ubi, pnum, ec) 0 -#define paranoid_check_in_wl_tree(ubi, e, root) -#define paranoid_check_in_pq(ubi, e) 0 -#endif /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. @@ -1526,8 +1520,6 @@ void ubi_wl_close(struct ubi_device *ubi) kfree(ubi->lookuptbl); } -#ifdef CONFIG_MTD_UBI_DEBUG - /** * paranoid_check_ec - make sure that the erase counter of a PEB is correct. * @ubi: UBI device description object @@ -1624,5 +1616,3 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi, dump_stack(); return -EINVAL; } - -#endif /* CONFIG_MTD_UBI_DEBUG */ -- cgit v1.2.3 From 4cd10aa3d99285a9f11119431f0777c97db6181b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:24:09 +0300 Subject: UBI: clean-up terminology for self-checks in io.c We have the "sefl-check" feature in UBI, but for historical reasons many corresponding functions and commentaries in the code use term "paranoid check" instead. Let's clean this up and use "self-check" everywhere. This patch renames functions, amends comments and messages. It touches only the io.c file. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/io.c | 76 +++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 84b8f1c7137b..c630163f28a9 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -91,13 +91,13 @@ #include #include "ubi.h" -static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); -static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); -static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, - const struct ubi_ec_hdr *ec_hdr); -static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); -static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, - const struct ubi_vid_hdr *vid_hdr); +static int self_check_not_bad(const struct ubi_device *ubi, int pnum); +static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); +static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_ec_hdr *ec_hdr); +static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); +static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_vid_hdr *vid_hdr); /** * ubi_io_read - read data from a physical eraseblock. @@ -134,7 +134,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); ubi_assert(len > 0); - err = paranoid_check_not_bad(ubi, pnum); + err = self_check_not_bad(ubi, pnum); if (err) return err; @@ -249,9 +249,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, return -EROFS; } - /* The below has to be compiled out if paranoid checks are disabled */ - - err = paranoid_check_not_bad(ubi, pnum); + err = self_check_not_bad(ubi, pnum); if (err) return err; @@ -265,10 +263,10 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, * We write to the data area of the physical eraseblock. Make * sure it has valid EC and VID headers. */ - err = paranoid_check_peb_ec_hdr(ubi, pnum); + err = self_check_peb_ec_hdr(ubi, pnum); if (err) return err; - err = paranoid_check_peb_vid_hdr(ubi, pnum); + err = self_check_peb_vid_hdr(ubi, pnum); if (err) return err; } @@ -582,7 +580,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) ubi_assert(pnum >= 0 && pnum < ubi->peb_count); - err = paranoid_check_not_bad(ubi, pnum); + err = self_check_not_bad(ubi, pnum); if (err != 0) return err; @@ -867,7 +865,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); ec_hdr->hdr_crc = cpu_to_be32(crc); - err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); + err = self_check_ec_hdr(ubi, pnum, ec_hdr); if (err) return err; @@ -1105,7 +1103,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, dbg_io("write VID header to PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); - err = paranoid_check_peb_ec_hdr(ubi, pnum); + err = self_check_peb_ec_hdr(ubi, pnum); if (err) return err; @@ -1114,7 +1112,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); vid_hdr->hdr_crc = cpu_to_be32(crc); - err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); + err = self_check_vid_hdr(ubi, pnum, vid_hdr); if (err) return err; @@ -1125,14 +1123,14 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, } /** - * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. + * self_check_not_bad - ensure that a physical eraseblock is not bad. * @ubi: UBI device description object * @pnum: physical eraseblock number to check * * This function returns zero if the physical eraseblock is good, %-EINVAL if * it is bad and a negative error code if an error occurred. */ -static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) +static int self_check_not_bad(const struct ubi_device *ubi, int pnum) { int err; @@ -1143,13 +1141,13 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) if (!err) return err; - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); dump_stack(); return err > 0 ? -EINVAL : err; } /** - * paranoid_check_ec_hdr - check if an erase counter header is all right. + * self_check_ec_hdr - check if an erase counter header is all right. * @ubi: UBI device description object * @pnum: physical eraseblock number the erase counter header belongs to * @ec_hdr: the erase counter header to check @@ -1157,8 +1155,8 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) * This function returns zero if the erase counter header contains valid * values, and %-EINVAL if not. */ -static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, - const struct ubi_ec_hdr *ec_hdr) +static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_ec_hdr *ec_hdr) { int err; uint32_t magic; @@ -1175,7 +1173,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, err = validate_ec_hdr(ubi, ec_hdr); if (err) { - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); goto fail; } @@ -1188,14 +1186,14 @@ fail: } /** - * paranoid_check_peb_ec_hdr - check erase counter header. + * self_check_peb_ec_hdr - check erase counter header. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * * This function returns zero if the erase counter header is all right and and * a negative error code if not or if an error occurred. */ -static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) +static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) { int err; uint32_t crc, hdr_crc; @@ -1216,14 +1214,14 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); if (hdr_crc != crc) { ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); ubi_dump_ec_hdr(ec_hdr); dump_stack(); err = -EINVAL; goto exit; } - err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); + err = self_check_ec_hdr(ubi, pnum, ec_hdr); exit: kfree(ec_hdr); @@ -1231,7 +1229,7 @@ exit: } /** - * paranoid_check_vid_hdr - check that a volume identifier header is all right. + * self_check_vid_hdr - check that a volume identifier header is all right. * @ubi: UBI device description object * @pnum: physical eraseblock number the volume identifier header belongs to * @vid_hdr: the volume identifier header to check @@ -1239,8 +1237,8 @@ exit: * This function returns zero if the volume identifier header is all right, and * %-EINVAL if not. */ -static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, - const struct ubi_vid_hdr *vid_hdr) +static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_vid_hdr *vid_hdr) { int err; uint32_t magic; @@ -1257,14 +1255,14 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, err = validate_vid_hdr(ubi, vid_hdr); if (err) { - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); goto fail; } return err; fail: - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); return -EINVAL; @@ -1272,14 +1270,14 @@ fail: } /** - * paranoid_check_peb_vid_hdr - check volume identifier header. + * self_check_peb_vid_hdr - check volume identifier header. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * * This function returns zero if the volume identifier header is all right, * and a negative error code if not or if an error occurred. */ -static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) +static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) { int err; uint32_t crc, hdr_crc; @@ -1304,14 +1302,14 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) if (hdr_crc != crc) { ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " "read %#08x", pnum, crc, hdr_crc); - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); err = -EINVAL; goto exit; } - err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); + err = self_check_vid_hdr(ubi, pnum, vid_hdr); exit: ubi_free_vid_hdr(ubi, vid_hdr); @@ -1359,7 +1357,7 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, if (c == c1) continue; - ubi_err("paranoid check failed for PEB %d:%d, len %d", + ubi_err("self-check failed for PEB %d:%d, len %d", pnum, offset, len); ubi_msg("data differ at position %d", i); dump_len = max_t(int, 128, len - i); @@ -1429,7 +1427,7 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) return 0; fail: - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); ubi_msg("hex dump of the %d-%d region", offset, offset + len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); err = -EINVAL; -- cgit v1.2.3 From 28f46452d3739eeea80456b0767e6f00b4086077 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:29:54 +0300 Subject: UBI: more of clean-up terminology for self-checks We have the "sefl-check" feature in UBI, but for historical reasons many corresponding functions and commentaries in the code use term "paranoid check" instead. Let's clean this up and use "self-check" everywhere. This patch renames functions, amends messages and kills several redundant debugging messages. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 8 ++++---- drivers/mtd/ubi/vmt.c | 31 +++++++++++++---------------- drivers/mtd/ubi/vtbl.c | 10 +++++----- drivers/mtd/ubi/wl.c | 54 ++++++++++++++++++++++++-------------------------- 4 files changed, 49 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index acb2eba78d53..dbc2210eafe6 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -88,7 +88,7 @@ #include #include "ubi.h" -static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); +static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); /* Temporary variables used during scanning */ static struct ubi_ec_hdr *ech; @@ -1218,7 +1218,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) if (seb->ec == UBI_SCAN_UNKNOWN_EC) seb->ec = si->mean_ec; - err = paranoid_check_si(ubi, si); + err = self_check_si(ubi, si); if (err) goto out_vidh; @@ -1326,14 +1326,14 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) } /** - * paranoid_check_si - check the scanning information. + * self_check_si - check the scanning information. * @ubi: UBI device description object * @si: scanning information * * This function returns zero if the scanning information is all right, and a * negative error code if not or if an error occurred. */ -static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) +static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 4eb85473bebc..21f5fb3f3604 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -28,7 +28,7 @@ #include #include "ubi.h" -static int paranoid_check_volumes(struct ubi_device *ubi); +static int self_check_volumes(struct ubi_device *ubi); static ssize_t vol_attribute_show(struct device *dev, struct device_attribute *attr, char *buf); @@ -355,8 +355,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) spin_unlock(&ubi->volumes_lock); ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED); - if (paranoid_check_volumes(ubi)) - dbg_err("check failed while creating volume %d", vol_id); + self_check_volumes(ubi); return err; out_sysfs: @@ -456,8 +455,8 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) spin_unlock(&ubi->volumes_lock); ubi_volume_notify(ubi, vol, UBI_VOLUME_REMOVED); - if (!no_vtbl && paranoid_check_volumes(ubi)) - dbg_err("check failed while removing volume %d", vol_id); + if (!no_vtbl) + self_check_volumes(ubi); return err; @@ -583,8 +582,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) } ubi_volume_notify(ubi, vol, UBI_VOLUME_RESIZED); - if (paranoid_check_volumes(ubi)) - dbg_err("check failed while re-sizing volume %d", vol_id); + self_check_volumes(ubi); return err; out_acc: @@ -633,8 +631,8 @@ int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list) } } - if (!err && paranoid_check_volumes(ubi)) - ; + if (!err) + self_check_volumes(ubi); return err; } @@ -681,8 +679,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) return err; } - if (paranoid_check_volumes(ubi)) - dbg_err("check failed while adding volume %d", vol_id); + self_check_volumes(ubi); return err; out_cdev: @@ -708,13 +705,13 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol) } /** - * paranoid_check_volume - check volume information. + * self_check_volume - check volume information. * @ubi: UBI device description object * @vol_id: volume ID * * Returns zero if volume is all right and a a negative error code if not. */ -static int paranoid_check_volume(struct ubi_device *ubi, int vol_id) +static int self_check_volume(struct ubi_device *ubi, int vol_id) { int idx = vol_id2idx(ubi, vol_id); int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker; @@ -846,7 +843,7 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id) return 0; fail: - ubi_err("paranoid check failed for volume %d", vol_id); + ubi_err("self-check failed for volume %d", vol_id); if (vol) ubi_dump_vol_info(vol); ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); @@ -856,12 +853,12 @@ fail: } /** - * paranoid_check_volumes - check information about all volumes. + * self_check_volumes - check information about all volumes. * @ubi: UBI device description object * * Returns zero if volumes are all right and a a negative error code if not. */ -static int paranoid_check_volumes(struct ubi_device *ubi) +static int self_check_volumes(struct ubi_device *ubi) { int i, err = 0; @@ -869,7 +866,7 @@ static int paranoid_check_volumes(struct ubi_device *ubi) return 0; for (i = 0; i < ubi->vtbl_slots; i++) { - err = paranoid_check_volume(ubi, i); + err = self_check_volume(ubi, i); if (err) break; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index e040980000fe..217caf5a5561 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -62,7 +62,7 @@ #include #include "ubi.h" -static void paranoid_vtbl_check(const struct ubi_device *ubi); +static void self_vtbl_check(const struct ubi_device *ubi); /* Empty volume table record */ static struct ubi_vtbl_record empty_vtbl_record; @@ -107,7 +107,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, return err; } - paranoid_vtbl_check(ubi); + self_vtbl_check(ubi); return 0; } @@ -855,16 +855,16 @@ out_free: } /** - * paranoid_vtbl_check - check volume table. + * self_vtbl_check - check volume table. * @ubi: UBI device description object */ -static void paranoid_vtbl_check(const struct ubi_device *ubi) +static void self_vtbl_check(const struct ubi_device *ubi) { if (!ubi->dbg->chk_gen) return; if (vtbl_check(ubi, ubi->vtbl)) { - ubi_err("paranoid check failed"); + ubi_err("self-check failed"); BUG(); } } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index f99dbd084838..75d2c1f7c3a8 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -155,12 +155,11 @@ struct ubi_work { int torture; }; -static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); -static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, - struct ubi_wl_entry *e, - struct rb_root *root); -static int paranoid_check_in_pq(const struct ubi_device *ubi, - struct ubi_wl_entry *e); +static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); +static int self_check_in_wl_tree(const struct ubi_device *ubi, + struct ubi_wl_entry *e, struct rb_root *root); +static int self_check_in_pq(const struct ubi_device *ubi, + struct ubi_wl_entry *e); /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. @@ -404,7 +403,7 @@ retry: else e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); - paranoid_check_in_wl_tree(ubi, e, &ubi->free); + self_check_in_wl_tree(ubi, e, &ubi->free); /* * Move the physical eraseblock to the protection queue where it will @@ -441,7 +440,7 @@ static int prot_queue_del(struct ubi_device *ubi, int pnum) if (!e) return -ENODEV; - if (paranoid_check_in_pq(ubi, e)) + if (self_check_in_pq(ubi, e)) return -ENODEV; list_del(&e->u.list); @@ -467,7 +466,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec); - err = paranoid_check_ec(ubi, e->pnum, e->ec); + err = self_check_ec(ubi, e->pnum, e->ec); if (err) return -EINVAL; @@ -667,7 +666,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, e1->ec, e2->ec); goto out_cancel; } - paranoid_check_in_wl_tree(ubi, e1, &ubi->used); + self_check_in_wl_tree(ubi, e1, &ubi->used); rb_erase(&e1->u.rb, &ubi->used); dbg_wl("move PEB %d EC %d to PEB %d EC %d", e1->pnum, e1->ec, e2->pnum, e2->ec); @@ -676,12 +675,12 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, scrubbing = 1; e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); - paranoid_check_in_wl_tree(ubi, e1, &ubi->scrub); + self_check_in_wl_tree(ubi, e1, &ubi->scrub); rb_erase(&e1->u.rb, &ubi->scrub); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); } - paranoid_check_in_wl_tree(ubi, e2, &ubi->free); + self_check_in_wl_tree(ubi, e2, &ubi->free); rb_erase(&e2->u.rb, &ubi->free); ubi->move_from = e1; ubi->move_to = e2; @@ -1128,13 +1127,13 @@ retry: return 0; } else { if (in_wl_tree(e, &ubi->used)) { - paranoid_check_in_wl_tree(ubi, e, &ubi->used); + self_check_in_wl_tree(ubi, e, &ubi->used); rb_erase(&e->u.rb, &ubi->used); } else if (in_wl_tree(e, &ubi->scrub)) { - paranoid_check_in_wl_tree(ubi, e, &ubi->scrub); + self_check_in_wl_tree(ubi, e, &ubi->scrub); rb_erase(&e->u.rb, &ubi->scrub); } else if (in_wl_tree(e, &ubi->erroneous)) { - paranoid_check_in_wl_tree(ubi, e, &ubi->erroneous); + self_check_in_wl_tree(ubi, e, &ubi->erroneous); rb_erase(&e->u.rb, &ubi->erroneous); ubi->erroneous_peb_count -= 1; ubi_assert(ubi->erroneous_peb_count >= 0); @@ -1201,7 +1200,7 @@ retry: } if (in_wl_tree(e, &ubi->used)) { - paranoid_check_in_wl_tree(ubi, e, &ubi->used); + self_check_in_wl_tree(ubi, e, &ubi->used); rb_erase(&e->u.rb, &ubi->used); } else { int err; @@ -1521,7 +1520,7 @@ void ubi_wl_close(struct ubi_device *ubi) } /** - * paranoid_check_ec - make sure that the erase counter of a PEB is correct. + * self_check_ec - make sure that the erase counter of a PEB is correct. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * @ec: the erase counter to check @@ -1530,7 +1529,7 @@ void ubi_wl_close(struct ubi_device *ubi) * is equivalent to @ec, and a negative error code if not or if an error * occurred. */ -static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) +static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) { int err; long long read_ec; @@ -1552,7 +1551,7 @@ static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) read_ec = be64_to_cpu(ec_hdr->ec); if (ec != read_ec) { - ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("self-check failed for PEB %d", pnum); ubi_err("read EC is %lld, should be %d", read_ec, ec); dump_stack(); err = 1; @@ -1565,7 +1564,7 @@ out_free: } /** - * paranoid_check_in_wl_tree - check that wear-leveling entry is in WL RB-tree. + * self_check_in_wl_tree - check that wear-leveling entry is in WL RB-tree. * @ubi: UBI device description object * @e: the wear-leveling entry to check * @root: the root of the tree @@ -1573,9 +1572,8 @@ out_free: * This function returns zero if @e is in the @root RB-tree and %-EINVAL if it * is not. */ -static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, - struct ubi_wl_entry *e, - struct rb_root *root) +static int self_check_in_wl_tree(const struct ubi_device *ubi, + struct ubi_wl_entry *e, struct rb_root *root) { if (!ubi->dbg->chk_gen) return 0; @@ -1583,22 +1581,22 @@ static int paranoid_check_in_wl_tree(const struct ubi_device *ubi, if (in_wl_tree(e, root)) return 0; - ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ", + ubi_err("self-check failed for PEB %d, EC %d, RB-tree %p ", e->pnum, e->ec, root); dump_stack(); return -EINVAL; } /** - * paranoid_check_in_pq - check if wear-leveling entry is in the protection + * self_check_in_pq - check if wear-leveling entry is in the protection * queue. * @ubi: UBI device description object * @e: the wear-leveling entry to check * * This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not. */ -static int paranoid_check_in_pq(const struct ubi_device *ubi, - struct ubi_wl_entry *e) +static int self_check_in_pq(const struct ubi_device *ubi, + struct ubi_wl_entry *e) { struct ubi_wl_entry *p; int i; @@ -1611,7 +1609,7 @@ static int paranoid_check_in_pq(const struct ubi_device *ubi, if (p == e) return 0; - ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue", + ubi_err("self-check failed for PEB %d, EC %d, Protect queue", e->pnum, e->ec); dump_stack(); return -EINVAL; -- cgit v1.2.3 From 268d36847059dbbcdf69dbe882bf59c28225cff6 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 18:39:56 +0300 Subject: UBI: get rid of dbg_err This patch removes the 'dbg_err()' macro and we now use 'ubi_err' instead. The idea of 'dbg_err()' was to compile out some error message to make the binary a bit smaller - but I think it was a bad idea. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 8 ++++---- drivers/mtd/ubi/cdev.c | 24 ++++++++++++------------ drivers/mtd/ubi/debug.h | 2 -- drivers/mtd/ubi/io.c | 36 ++++++++++++++++++------------------ drivers/mtd/ubi/kapi.c | 2 +- drivers/mtd/ubi/scan.c | 10 +++++----- drivers/mtd/ubi/vmt.c | 18 +++++++++--------- drivers/mtd/ubi/vtbl.c | 6 +++--- 8 files changed, 52 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index ba73c0096444..5f6b248ea447 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -881,7 +881,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) for (i = 0; i < UBI_MAX_DEVICES; i++) { ubi = ubi_devices[i]; if (ubi && mtd->index == ubi->mtd->index) { - dbg_err("mtd%d is already attached to ubi%d", + ubi_err("mtd%d is already attached to ubi%d", mtd->index, i); return -EEXIST; } @@ -907,7 +907,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (!ubi_devices[ubi_num]) break; if (ubi_num == UBI_MAX_DEVICES) { - dbg_err("only %d UBI devices may be created", + ubi_err("only %d UBI devices may be created", UBI_MAX_DEVICES); return -ENFILE; } @@ -917,7 +917,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) /* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { - dbg_err("ubi%d already exists", ubi_num); + ubi_err("ubi%d already exists", ubi_num); return -EEXIST; } } @@ -955,7 +955,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) err = attach_by_scanning(ubi); if (err) { - dbg_err("failed to attach by scanning, error %d", err); + ubi_err("failed to attach by scanning, error %d", err); goto out_debugging; } diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 633ac82bbd22..2364c00f66d0 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -63,7 +63,7 @@ static int get_exclusive(struct ubi_volume_desc *desc) users = vol->readers + vol->writers + vol->exclusive; ubi_assert(users > 0); if (users > 1) { - dbg_err("%d users for volume %d", users, vol->vol_id); + ubi_err("%d users for volume %d", users, vol->vol_id); err = -EBUSY; } else { vol->readers = vol->writers = 0; @@ -159,7 +159,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) if (vol->updating) { /* Update is in progress, seeking is prohibited */ - dbg_err("updating"); + ubi_err("updating"); return -EBUSY; } @@ -178,7 +178,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) } if (new_offset < 0 || new_offset > vol->used_bytes) { - dbg_err("bad seek %lld", new_offset); + ubi_err("bad seek %lld", new_offset); return -EINVAL; } @@ -216,11 +216,11 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, count, *offp, vol->vol_id); if (vol->updating) { - dbg_err("updating"); + ubi_err("updating"); return -EBUSY; } if (vol->upd_marker) { - dbg_err("damaged volume, update marker is set"); + ubi_err("damaged volume, update marker is set"); return -EBADF; } if (*offp == vol->used_bytes || count == 0) @@ -300,7 +300,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); if (off & (ubi->min_io_size - 1)) { - dbg_err("unaligned position"); + ubi_err("unaligned position"); return -EINVAL; } @@ -309,7 +309,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, /* We can write only in fractions of the minimum I/O unit */ if (count & (ubi->min_io_size - 1)) { - dbg_err("unaligned write length"); + ubi_err("unaligned write length"); return -EINVAL; } @@ -643,7 +643,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, return 0; bad: - dbg_err("bad volume creation request"); + ubi_err("bad volume creation request"); ubi_dump_mkvol_req(req); return err; } @@ -709,12 +709,12 @@ static int rename_volumes(struct ubi_device *ubi, for (i = 0; i < req->count - 1; i++) { for (n = i + 1; n < req->count; n++) { if (req->ents[i].vol_id == req->ents[n].vol_id) { - dbg_err("duplicated volume id %d", + ubi_err("duplicated volume id %d", req->ents[i].vol_id); return -EINVAL; } if (!strcmp(req->ents[i].name, req->ents[n].name)) { - dbg_err("duplicated volume name \"%s\"", + ubi_err("duplicated volume name \"%s\"", req->ents[i].name); return -EINVAL; } @@ -737,7 +737,7 @@ static int rename_volumes(struct ubi_device *ubi, re->desc = ubi_open_volume(ubi->ubi_num, vol_id, UBI_EXCLUSIVE); if (IS_ERR(re->desc)) { err = PTR_ERR(re->desc); - dbg_err("cannot open volume %d, error %d", vol_id, err); + ubi_err("cannot open volume %d, error %d", vol_id, err); kfree(re); goto out_free; } @@ -796,7 +796,7 @@ static int rename_volumes(struct ubi_device *ubi, continue; /* The volume exists but busy, or an error occurred */ - dbg_err("cannot open volume \"%s\", error %d", + ubi_err("cannot open volume \"%s\", error %d", re->new_name, err); goto out_free; } diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 3e5b60f3fdf1..449937431f42 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -35,8 +35,6 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); } \ } while (0) -#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) - #define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ print_hex_dump(l, ps, pt, r, g, b, len, a) diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index c630163f28a9..3c55572debeb 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -272,7 +272,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } if (ubi_dbg_is_write_failure(ubi)) { - dbg_err("cannot write %d bytes to PEB %d:%d " + ubi_err("cannot write %d bytes to PEB %d:%d " "(emulated)", len, pnum, offset); dump_stack(); return -EIO; @@ -387,7 +387,7 @@ retry: return err; if (ubi_dbg_is_erase_failure(ubi)) { - dbg_err("cannot erase PEB %d (emulated)", pnum); + ubi_err("cannot erase PEB %d (emulated)", pnum); return -EIO; } @@ -896,40 +896,40 @@ static int validate_vid_hdr(const struct ubi_device *ubi, int usable_leb_size = ubi->leb_size - data_pad; if (copy_flag != 0 && copy_flag != 1) { - dbg_err("bad copy_flag"); + ubi_err("bad copy_flag"); goto bad; } if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || data_pad < 0) { - dbg_err("negative values"); + ubi_err("negative values"); goto bad; } if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { - dbg_err("bad vol_id"); + ubi_err("bad vol_id"); goto bad; } if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { - dbg_err("bad compat"); + ubi_err("bad compat"); goto bad; } if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && compat != UBI_COMPAT_REJECT) { - dbg_err("bad compat"); + ubi_err("bad compat"); goto bad; } if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { - dbg_err("bad vol_type"); + ubi_err("bad vol_type"); goto bad; } if (data_pad >= ubi->leb_size / 2) { - dbg_err("bad data_pad"); + ubi_err("bad data_pad"); goto bad; } @@ -941,45 +941,45 @@ static int validate_vid_hdr(const struct ubi_device *ubi, * mapped logical eraseblocks. */ if (used_ebs == 0) { - dbg_err("zero used_ebs"); + ubi_err("zero used_ebs"); goto bad; } if (data_size == 0) { - dbg_err("zero data_size"); + ubi_err("zero data_size"); goto bad; } if (lnum < used_ebs - 1) { if (data_size != usable_leb_size) { - dbg_err("bad data_size"); + ubi_err("bad data_size"); goto bad; } } else if (lnum == used_ebs - 1) { if (data_size == 0) { - dbg_err("bad data_size at last LEB"); + ubi_err("bad data_size at last LEB"); goto bad; } } else { - dbg_err("too high lnum"); + ubi_err("too high lnum"); goto bad; } } else { if (copy_flag == 0) { if (data_crc != 0) { - dbg_err("non-zero data CRC"); + ubi_err("non-zero data CRC"); goto bad; } if (data_size != 0) { - dbg_err("non-zero data_size"); + ubi_err("non-zero data_size"); goto bad; } } else { if (data_size == 0) { - dbg_err("zero data_size of copy"); + ubi_err("zero data_size of copy"); goto bad; } } if (used_ebs != 0) { - dbg_err("bad used_ebs"); + ubi_err("bad used_ebs"); goto bad; } } diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 7345a878b24a..2edcba3d7cf3 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -221,7 +221,7 @@ out_free: kfree(desc); out_put_ubi: ubi_put_device(ubi); - dbg_err("cannot open device %d, volume %d, error %d", + ubi_err("cannot open device %d, volume %d, error %d", ubi_num, vol_id, err); return ERR_PTR(err); } diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index dbc2210eafe6..2888e8dc300e 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -197,7 +197,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, */ if (vol_id != sv->vol_id) { - dbg_err("inconsistent vol_id"); + ubi_err("inconsistent vol_id"); goto bad; } @@ -207,17 +207,17 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, sv_vol_type = UBI_VID_DYNAMIC; if (vol_type != sv_vol_type) { - dbg_err("inconsistent vol_type"); + ubi_err("inconsistent vol_type"); goto bad; } if (used_ebs != sv->used_ebs) { - dbg_err("inconsistent used_ebs"); + ubi_err("inconsistent used_ebs"); goto bad; } if (data_pad != sv->data_pad) { - dbg_err("inconsistent data_pad"); + ubi_err("inconsistent data_pad"); goto bad; } } @@ -369,7 +369,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, if (err == UBI_IO_BITFLIPS) bitflips = 1; else { - dbg_err("VID of PEB %d header is bad, but it " + ubi_err("VID of PEB %d header is bad, but it " "was OK earlier, err %d", pnum, err); if (err > 0) err = -EIO; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 21f5fb3f3604..192140566b72 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -222,7 +222,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) } if (vol_id == UBI_VOL_NUM_AUTO) { - dbg_err("out of volume IDs"); + ubi_err("out of volume IDs"); err = -ENFILE; goto out_unlock; } @@ -236,7 +236,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Ensure that this volume does not exist */ err = -EEXIST; if (ubi->volumes[vol_id]) { - dbg_err("volume %d already exists", vol_id); + ubi_err("volume %d already exists", vol_id); goto out_unlock; } @@ -245,7 +245,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (ubi->volumes[i] && ubi->volumes[i]->name_len == req->name_len && !strcmp(ubi->volumes[i]->name, req->name)) { - dbg_err("volume \"%s\" exists (ID %d)", req->name, i); + ubi_err("volume \"%s\" exists (ID %d)", req->name, i); goto out_unlock; } @@ -256,9 +256,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Reserve physical eraseblocks */ if (vol->reserved_pebs > ubi->avail_pebs) { - dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); + ubi_err("not enough PEBs, only %d available", ubi->avail_pebs); if (ubi->corr_peb_count) - dbg_err("%d PEBs are corrupted and not used", + ubi_err("%d PEBs are corrupted and not used", ubi->corr_peb_count); err = -ENOSPC; goto out_unlock; @@ -494,7 +494,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (vol->vol_type == UBI_STATIC_VOLUME && reserved_pebs < vol->used_ebs) { - dbg_err("too small size %d, %d LEBs contain data", + ubi_err("too small size %d, %d LEBs contain data", reserved_pebs, vol->used_ebs); return -EINVAL; } @@ -523,10 +523,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) if (pebs > 0) { spin_lock(&ubi->volumes_lock); if (pebs > ubi->avail_pebs) { - dbg_err("not enough PEBs: requested %d, available %d", + ubi_err("not enough PEBs: requested %d, available %d", pebs, ubi->avail_pebs); if (ubi->corr_peb_count) - dbg_err("%d PEBs are corrupted and not used", + ubi_err("%d PEBs are corrupted and not used", ubi->corr_peb_count); spin_unlock(&ubi->volumes_lock); err = -ENOSPC; @@ -761,7 +761,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id) } if (vol->upd_marker && vol->corrupted) { - dbg_err("update marker and corrupted simultaneously"); + ubi_err("update marker and corrupted simultaneously"); goto fail; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 217caf5a5561..abb38a0d7b03 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -225,7 +225,7 @@ static int vtbl_check(const struct ubi_device *ubi, n = ubi->leb_size % alignment; if (data_pad != n) { - dbg_err("bad data_pad, has to be %d", n); + ubi_err("bad data_pad, has to be %d", n); err = 6; goto bad; } @@ -241,7 +241,7 @@ static int vtbl_check(const struct ubi_device *ubi, } if (reserved_pebs > ubi->good_peb_count) { - dbg_err("too large reserved_pebs %d, good PEBs %d", + ubi_err("too large reserved_pebs %d, good PEBs %d", reserved_pebs, ubi->good_peb_count); err = 9; goto bad; @@ -815,7 +815,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) } else { if (sv->leb_count > UBI_LAYOUT_VOLUME_EBS) { /* This must not happen with proper UBI images */ - dbg_err("too many LEBs (%d) in layout volume", + ubi_err("too many LEBs (%d) in layout volume", sv->leb_count); return -EINVAL; } -- cgit v1.2.3 From 3e6afb4eb1606ef1b56a238301f459ddc2460164 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 16 May 2012 19:29:04 +0300 Subject: UBI: rename few functions for consistency Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 5 ++--- drivers/mtd/ubi/io.c | 20 +++++++++++--------- drivers/mtd/ubi/wl.c | 4 ++-- 3 files changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 449937431f42..4d0a4cdc9e3b 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -62,9 +62,8 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dump_sv(const struct ubi_scan_volume *sv); void ubi_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); -int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); -int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, - int offset, int len); +int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, + int len); int ubi_debugging_init_dev(struct ubi_device *ubi); void ubi_debugging_exit_dev(struct ubi_device *ubi); int ubi_debugfs_init(void); diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 3c55572debeb..1f568ed96f40 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -98,6 +98,8 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, const struct ubi_vid_hdr *vid_hdr); +static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, + int offset, int len); /** * ubi_io_read - read data from a physical eraseblock. @@ -254,7 +256,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, return err; /* The area we are writing to has to contain all 0xFF bytes */ - err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); + err = ubi_self_check_all_ff(ubi, pnum, offset, len); if (err) return err; @@ -289,7 +291,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, ubi_assert(written == len); if (!err) { - err = ubi_dbg_check_write(ubi, buf, pnum, offset, len); + err = self_check_write(ubi, buf, pnum, offset, len); if (err) return err; @@ -300,7 +302,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, offset += len; len = ubi->peb_size - offset; if (len) - err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); + err = ubi_self_check_all_ff(ubi, pnum, offset, len); } return err; @@ -382,7 +384,7 @@ retry: return -EIO; } - err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); + err = ubi_self_check_all_ff(ubi, pnum, 0, ubi->peb_size); if (err) return err; @@ -1317,7 +1319,7 @@ exit: } /** - * ubi_dbg_check_write - make sure write succeeded. + * self_check_write - make sure write succeeded. * @ubi: UBI device description object * @buf: buffer with data which were written * @pnum: physical eraseblock number the data were written to @@ -1328,8 +1330,8 @@ exit: * the original data buffer - the data have to match. Returns zero if the data * match and a negative error code if not or in case of failure. */ -int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, - int offset, int len) +static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, + int offset, int len) { int err, i; size_t read; @@ -1383,7 +1385,7 @@ out_free: } /** - * ubi_dbg_check_all_ff - check that a region of flash is empty. + * ubi_self_check_all_ff - check that a region of flash is empty. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * @offset: the starting offset within the physical eraseblock to check @@ -1393,7 +1395,7 @@ out_free: * @offset of the physical eraseblock @pnum, and a negative error code if not * or if an error occurred. */ -int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) +int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) { size_t read; int err; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 75d2c1f7c3a8..b847f5529ba6 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -414,8 +414,8 @@ retry: prot_queue_add(ubi, e); spin_unlock(&ubi->wl_lock); - err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, - ubi->peb_size - ubi->vid_hdr_aloffset); + err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, + ubi->peb_size - ubi->vid_hdr_aloffset); if (err) { ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); return err; -- cgit v1.2.3 From 20a9a78f7773f3ec03ac04f2eb161e3d4edf308e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 06:23:22 +0300 Subject: UBI: rename struct ubi_scan_leb Rename 'struct ubi_scan_leb' to 'struct ubi_ainf_leb'. This is part of the code re-structuring I am trying to do in order to add fastmap in a more logical way. Fastmap can share a lot with scanning, including the attach-time data structures, which all now have "scan" word in the name. Let's get rid of this word and use "ainf" instead which stands for "attach information". It has the same length as "scan" so re-naming is trivial. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 2 +- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 2 +- drivers/mtd/ubi/eba.c | 2 +- drivers/mtd/ubi/scan.c | 42 +++++++++++++++++++++--------------------- drivers/mtd/ubi/scan.h | 16 ++++++++-------- drivers/mtd/ubi/vtbl.c | 4 ++-- drivers/mtd/ubi/wl.c | 2 +- 8 files changed, 37 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 5f6b248ea447..f51eb287c488 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -937,7 +937,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) spin_lock_init(&ubi->volumes_lock); ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); - dbg_msg("sizeof(struct ubi_scan_leb) %zu", sizeof(struct ubi_scan_leb)); + dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); err = io_init(ubi); diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 3b868104625e..60b4bb498aba 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -188,11 +188,11 @@ void ubi_dump_sv(const struct ubi_scan_volume *sv) } /** - * ubi_dump_seb - dump a &struct ubi_scan_leb object. + * ubi_dump_seb - dump a &struct ubi_ainf_peb object. * @seb: the object to dump * @type: object type: 0 - not corrupted, 1 - corrupted */ -void ubi_dump_seb(const struct ubi_scan_leb *seb, int type) +void ubi_dump_seb(const struct ubi_ainf_peb *seb, int type) { printk(KERN_DEBUG "eraseblock scanning information dump:\n"); printk(KERN_DEBUG "\tec %d\n", seb->ec); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 4d0a4cdc9e3b..c6729ff0caa5 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -60,7 +60,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dump_sv(const struct ubi_scan_volume *sv); -void ubi_dump_seb(const struct ubi_scan_leb *seb, int type); +void ubi_dump_seb(const struct ubi_ainf_peb *seb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 9eff9386f7b4..901622605b2d 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1217,7 +1217,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) int i, j, err, num_volumes; struct ubi_scan_volume *sv; struct ubi_volume *vol; - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct rb_node *rb; dbg_eba("initialize EBA sub-system"); diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 2888e8dc300e..29648778f905 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -29,7 +29,7 @@ * objects which are kept in volume RB-tree with root at the @volumes field. * The RB-tree is indexed by the volume ID. * - * Scanned logical eraseblocks are represented by &struct ubi_scan_leb objects. + * Scanned logical eraseblocks are represented by &struct ubi_ainf_peb objects. * These objects are kept in per-volume RB-trees with the root at the * corresponding &struct ubi_scan_volume object. To put it differently, we keep * an RB-tree of per-volume objects and each of these objects is the root of @@ -113,7 +113,7 @@ static struct ubi_vid_hdr *vidh; static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, struct list_head *list) { - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; if (list == &si->free) { dbg_bld("add to free: PEB %d, EC %d", pnum, ec); @@ -150,7 +150,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, */ static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec) { - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); @@ -310,7 +310,7 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, * o bit 2 is cleared: the older LEB is not corrupted; * o bit 2 is set: the older LEB is corrupted. */ -static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, +static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, int pnum, const struct ubi_vid_hdr *vid_hdr) { void *buf; @@ -447,7 +447,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int err, vol_id, lnum; unsigned long long sqnum; struct ubi_scan_volume *sv; - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct rb_node **p, *parent = NULL; vol_id = be32_to_cpu(vid_hdr->vol_id); @@ -473,7 +473,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int cmp_res; parent = *p; - seb = rb_entry(parent, struct ubi_scan_leb, u.rb); + seb = rb_entry(parent, struct ubi_ainf_peb, u.rb); if (lnum != seb->lnum) { if (lnum < seb->lnum) p = &(*p)->rb_left; @@ -622,14 +622,14 @@ struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, * This function returns a pointer to the scanning logical eraseblock or %NULL * if there are no data about it in the scanning volume information. */ -struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, int lnum) { - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct rb_node *p = sv->root.rb_node; while (p) { - seb = rb_entry(p, struct ubi_scan_leb, u.rb); + seb = rb_entry(p, struct ubi_ainf_peb, u.rb); if (lnum == seb->lnum) return seb; @@ -651,12 +651,12 @@ struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) { struct rb_node *rb; - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; dbg_bld("remove scanning information about volume %d", sv->vol_id); while ((rb = rb_first(&sv->root))) { - seb = rb_entry(rb, struct ubi_scan_leb, u.rb); + seb = rb_entry(rb, struct ubi_ainf_peb, u.rb); rb_erase(&seb->u.rb, &sv->root); list_add_tail(&seb->u.list, &si->erase); } @@ -725,14 +725,14 @@ out_free: * This function returns scanning physical eraseblock information in case of * success and an error code in case of failure. */ -struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, +struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si) { int err = 0; - struct ubi_scan_leb *seb, *tmp_seb; + struct ubi_ainf_peb *seb, *tmp_seb; if (!list_empty(&si->free)) { - seb = list_entry(si->free.next, struct ubi_scan_leb, u.list); + seb = list_entry(si->free.next, struct ubi_ainf_peb, u.list); list_del(&seb->u.list); dbg_bld("return free PEB %d, EC %d", seb->pnum, seb->ec); return seb; @@ -1075,7 +1075,7 @@ adjust_mean_ec: */ static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) { - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; int max_corr, peb_count; peb_count = ubi->peb_count - si->bad_peb_count - si->alien_peb_count; @@ -1148,7 +1148,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) int err, pnum; struct rb_node *rb1, *rb2; struct ubi_scan_volume *sv; - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct ubi_scan_info *si; si = kzalloc(sizeof(struct ubi_scan_info), GFP_KERNEL); @@ -1163,7 +1163,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) err = -ENOMEM; si->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab", - sizeof(struct ubi_scan_leb), + sizeof(struct ubi_ainf_peb), 0, 0, NULL); if (!si->scan_leb_slab) goto out_si; @@ -1246,7 +1246,7 @@ out_si: */ static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) { - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct rb_node *this = sv->root.rb_node; while (this) { @@ -1255,7 +1255,7 @@ static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) else if (this->rb_right) this = this->rb_right; else { - seb = rb_entry(this, struct ubi_scan_leb, u.rb); + seb = rb_entry(this, struct ubi_ainf_peb, u.rb); this = rb_parent(this); if (this) { if (this->rb_left == &seb->u.rb) @@ -1276,7 +1276,7 @@ static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) */ void ubi_scan_destroy_si(struct ubi_scan_info *si) { - struct ubi_scan_leb *seb, *seb_tmp; + struct ubi_ainf_peb *seb, *seb_tmp; struct ubi_scan_volume *sv; struct rb_node *rb; @@ -1338,7 +1338,7 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; struct ubi_scan_volume *sv; - struct ubi_scan_leb *seb, *last_seb; + struct ubi_ainf_peb *seb, *last_seb; uint8_t *buf; if (!ubi->dbg->chk_gen) diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index d48aef15ab5d..2cd66624dfa1 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -25,7 +25,7 @@ #define UBI_SCAN_UNKNOWN_EC (-1) /** - * struct ubi_scan_leb - scanning information about a physical eraseblock. + * struct ubi_ainf_peb - scanning information about a physical eraseblock. * @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown) * @pnum: physical eraseblock number * @lnum: logical eraseblock number @@ -33,13 +33,13 @@ * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB) * @sqnum: sequence number * @u: unions RB-tree or @list links - * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects + * @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects * @u.list: link in one of the eraseblock lists * * One object of this type is allocated for each physical eraseblock during * scanning. */ -struct ubi_scan_leb { +struct ubi_ainf_peb { int ec; int pnum; int lnum; @@ -68,7 +68,7 @@ struct ubi_scan_leb { * @compat: compatibility flags of this volume * @rb: link in the volume RB-tree * @root: root of the RB-tree containing all the eraseblock belonging to this - * volume (&struct ubi_scan_leb objects) + * volume (&struct ubi_ainf_peb objects) * * One object of this type is allocated for each volume during scanning. */ @@ -109,7 +109,7 @@ struct ubi_scan_volume { * @mean_ec: mean erase counter value * @ec_sum: a temporary variable used when calculating @mean_ec * @ec_count: a temporary variable used when calculating @mean_ec - * @scan_leb_slab: slab cache for &struct ubi_scan_leb objects + * @scan_leb_slab: slab cache for &struct ubi_ainf_peb objects * * This data structure contains the result of scanning and may be used by other * UBI sub-systems to build final UBI data structures, further error-recovery @@ -149,7 +149,7 @@ struct ubi_vid_hdr; * @list: the list to move to */ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, - struct ubi_scan_leb *seb, + struct ubi_ainf_peb *seb, struct list_head *list) { rb_erase(&seb->u.rb, &sv->root); @@ -161,10 +161,10 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int bitflips); struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, int vol_id); -struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, int lnum); void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv); -struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, +struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si); int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, int pnum, int ec); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index abb38a0d7b03..a706910cae06 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -303,7 +303,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, { int err, tries = 0; struct ubi_vid_hdr *vid_hdr; - struct ubi_scan_leb *new_seb; + struct ubi_ainf_peb *new_seb; ubi_msg("create volume table (copy #%d)", copy + 1); @@ -378,7 +378,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, { int err; struct rb_node *rb; - struct ubi_scan_leb *seb; + struct ubi_ainf_peb *seb; struct ubi_vtbl_record *leb[UBI_LAYOUT_VOLUME_EBS] = { NULL, NULL }; int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1}; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b847f5529ba6..91869e8d2a90 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1385,7 +1385,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) int err, i; struct rb_node *rb1, *rb2; struct ubi_scan_volume *sv; - struct ubi_scan_leb *seb, *tmp; + struct ubi_ainf_peb *seb, *tmp; struct ubi_wl_entry *e; ubi->used = ubi->erroneous = ubi->free = ubi->scrub = RB_ROOT; -- cgit v1.2.3 From 5fb42fa8573d53fdcd87227ba8e38c397d76f131 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 06:59:30 +0300 Subject: UBI: rename struct ubi_scan_volume Rename 'struct ubi_scan_volume' to 'struct ubi_ainf_volume'. This is part of the code re-structuring I am trying to do in order to add fastmap in a more logical way. Fastmap can share a lot with scanning, including the attach-time data structures, which all now have "scan" word in the name. Let's get rid of this word and use "ainf" instead which stands for "attach information". It has the same length as "scan" so re-naming is trivial. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 4 ++-- drivers/mtd/ubi/debug.h | 2 +- drivers/mtd/ubi/eba.c | 2 +- drivers/mtd/ubi/scan.c | 36 ++++++++++++++++++------------------ drivers/mtd/ubi/scan.h | 12 ++++++------ drivers/mtd/ubi/vtbl.c | 10 +++++----- drivers/mtd/ubi/wl.c | 2 +- 7 files changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 60b4bb498aba..92b5d810a8e7 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -171,10 +171,10 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) } /** - * ubi_dump_sv - dump a &struct ubi_scan_volume object. + * ubi_dump_sv - dump a &struct ubi_ainf_volume object. * @sv: the object to dump */ -void ubi_dump_sv(const struct ubi_scan_volume *sv) +void ubi_dump_sv(const struct ubi_ainf_volume *sv) { printk(KERN_DEBUG "Volume scanning information dump:\n"); printk(KERN_DEBUG "\tvol_id %d\n", sv->vol_id); diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index c6729ff0caa5..041ee4d43dec 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -59,7 +59,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); -void ubi_dump_sv(const struct ubi_scan_volume *sv); +void ubi_dump_sv(const struct ubi_ainf_volume *sv); void ubi_dump_seb(const struct ubi_ainf_peb *seb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 901622605b2d..2d2bc73930f7 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1215,7 +1215,7 @@ static void print_rsvd_warning(struct ubi_device *ubi, int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) { int i, j, err, num_volumes; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_volume *vol; struct ubi_ainf_peb *seb; struct rb_node *rb; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 29648778f905..046618989db9 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -25,13 +25,13 @@ * headers and providing complete information about the UBI flash image. * * The scanning information is represented by a &struct ubi_scan_info' object. - * Information about found volumes is represented by &struct ubi_scan_volume + * Information about found volumes is represented by &struct ubi_ainf_volume * objects which are kept in volume RB-tree with root at the @volumes field. * The RB-tree is indexed by the volume ID. * * Scanned logical eraseblocks are represented by &struct ubi_ainf_peb objects. * These objects are kept in per-volume RB-trees with the root at the - * corresponding &struct ubi_scan_volume object. To put it differently, we keep + * corresponding &struct ubi_ainf_volume object. To put it differently, we keep * an RB-tree of per-volume objects and each of these objects is the root of * RB-tree of per-eraseblock objects. * @@ -180,7 +180,7 @@ static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec) * headers of the same volume. */ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, - const struct ubi_scan_volume *sv, int pnum) + const struct ubi_ainf_volume *sv, int pnum) { int vol_type = vid_hdr->vol_type; int vol_id = be32_to_cpu(vid_hdr->vol_id); @@ -244,11 +244,11 @@ bad: * to the scanning volume object in case of success and a negative error code * in case of failure. */ -static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, +static struct ubi_ainf_volume *add_volume(struct ubi_scan_info *si, int vol_id, int pnum, const struct ubi_vid_hdr *vid_hdr) { - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct rb_node **p = &si->volumes.rb_node, *parent = NULL; ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); @@ -256,7 +256,7 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, /* Walk the volume RB-tree to look if this volume is already present */ while (*p) { parent = *p; - sv = rb_entry(parent, struct ubi_scan_volume, rb); + sv = rb_entry(parent, struct ubi_ainf_volume, rb); if (vol_id == sv->vol_id) return sv; @@ -268,7 +268,7 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, } /* The volume is absent - add it */ - sv = kmalloc(sizeof(struct ubi_scan_volume), GFP_KERNEL); + sv = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); if (!sv) return ERR_PTR(-ENOMEM); @@ -446,7 +446,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, { int err, vol_id, lnum; unsigned long long sqnum; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_ainf_peb *seb; struct rb_node **p, *parent = NULL; @@ -593,14 +593,14 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, * This function returns a pointer to the volume description or %NULL if there * are no data about this volume in the scanning information. */ -struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, int vol_id) { - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct rb_node *p = si->volumes.rb_node; while (p) { - sv = rb_entry(p, struct ubi_scan_volume, rb); + sv = rb_entry(p, struct ubi_ainf_volume, rb); if (vol_id == sv->vol_id) return sv; @@ -622,7 +622,7 @@ struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, * This function returns a pointer to the scanning logical eraseblock or %NULL * if there are no data about it in the scanning volume information. */ -struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, int lnum) { struct ubi_ainf_peb *seb; @@ -648,7 +648,7 @@ struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, * @si: scanning information * @sv: the volume scanning information to delete */ -void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) +void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) { struct rb_node *rb; struct ubi_ainf_peb *seb; @@ -1147,7 +1147,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) { int err, pnum; struct rb_node *rb1, *rb2; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_ainf_peb *seb; struct ubi_scan_info *si; @@ -1244,7 +1244,7 @@ out_si: * This function destroys the volume RB-tree (@sv->root) and the scanning * volume information. */ -static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) +static void destroy_sv(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) { struct ubi_ainf_peb *seb; struct rb_node *this = sv->root.rb_node; @@ -1277,7 +1277,7 @@ static void destroy_sv(struct ubi_scan_info *si, struct ubi_scan_volume *sv) void ubi_scan_destroy_si(struct ubi_scan_info *si) { struct ubi_ainf_peb *seb, *seb_tmp; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct rb_node *rb; list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) { @@ -1305,7 +1305,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) else if (rb->rb_right) rb = rb->rb_right; else { - sv = rb_entry(rb, struct ubi_scan_volume, rb); + sv = rb_entry(rb, struct ubi_ainf_volume, rb); rb = rb_parent(rb); if (rb) { @@ -1337,7 +1337,7 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_ainf_peb *seb, *last_seb; uint8_t *buf; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 2cd66624dfa1..5523f0b0fe1d 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -53,7 +53,7 @@ struct ubi_ainf_peb { }; /** - * struct ubi_scan_volume - scanning information about a volume. + * struct ubi_ainf_volume - scanning information about a volume. * @vol_id: volume ID * @highest_lnum: highest logical eraseblock number in this volume * @leb_count: number of logical eraseblocks in this volume @@ -72,7 +72,7 @@ struct ubi_ainf_peb { * * One object of this type is allocated for each volume during scanning. */ -struct ubi_scan_volume { +struct ubi_ainf_volume { int vol_id; int highest_lnum; int leb_count; @@ -148,7 +148,7 @@ struct ubi_vid_hdr; * @seb: scanning eraseblock information * @list: the list to move to */ -static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, +static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *sv, struct ubi_ainf_peb *seb, struct list_head *list) { @@ -159,11 +159,11 @@ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, int vol_id); -struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, int lnum); -void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv); +void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_ainf_volume *sv); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_scan_info *si); int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index a706910cae06..75df84ecad0d 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -374,7 +374,7 @@ out_free: */ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, struct ubi_scan_info *si, - struct ubi_scan_volume *sv) + struct ubi_ainf_volume *sv) { int err; struct rb_node *rb; @@ -535,7 +535,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, const struct ubi_vtbl_record *vtbl) { int i, reserved_pebs = 0; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_volume *vol; for (i = 0; i < ubi->vtbl_slots; i++) { @@ -668,7 +668,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, * to the data read from the volume tabla, and %-EINVAL if not. */ static int check_sv(const struct ubi_volume *vol, - const struct ubi_scan_volume *sv) + const struct ubi_ainf_volume *sv) { int err; @@ -715,7 +715,7 @@ static int check_scanning_info(const struct ubi_device *ubi, struct ubi_scan_info *si) { int err, i; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_volume *vol; if (si->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { @@ -779,7 +779,7 @@ static int check_scanning_info(const struct ubi_device *ubi, int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) { int i, err; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 91869e8d2a90..53ef24b48211 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1384,7 +1384,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) { int err, i; struct rb_node *rb1, *rb2; - struct ubi_scan_volume *sv; + struct ubi_ainf_volume *sv; struct ubi_ainf_peb *seb, *tmp; struct ubi_wl_entry *e; -- cgit v1.2.3 From 04aa6f29d068d6b535538ebb3db5f41c7aa046f0 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 07:46:17 +0300 Subject: UBI: rename struct ubi_scan_info Rename 'struct ubi_scan_info' to 'struct ubi_attach_info'. This is part of the code re-structuring I am trying to do in order to add fastmap in a more logical way. Fastmap can share a lot with scanning, including the attach-time data structures, which all now have "scan" word in the name. Let's get rid of this word. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 2 +- drivers/mtd/ubi/eba.c | 4 ++-- drivers/mtd/ubi/scan.c | 41 +++++++++++++++++++++-------------------- drivers/mtd/ubi/scan.h | 18 +++++++++--------- drivers/mtd/ubi/ubi.h | 6 +++--- drivers/mtd/ubi/vtbl.c | 13 +++++++------ drivers/mtd/ubi/wl.c | 2 +- 7 files changed, 44 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index f51eb287c488..b239a22e6ae2 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -583,7 +583,7 @@ static void free_internal_volumes(struct ubi_device *ubi) static int attach_by_scanning(struct ubi_device *ubi) { int err; - struct ubi_scan_info *si; + struct ubi_attach_info *si; si = ubi_scan(ubi); if (IS_ERR(si)) diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 2d2bc73930f7..4b3cf31e9a92 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1182,7 +1182,7 @@ out_unlock_leb: * reported by real users. */ static void print_rsvd_warning(struct ubi_device *ubi, - struct ubi_scan_info *si) + struct ubi_attach_info *si) { /* * The 1 << 18 (256KiB) number is picked randomly, just a reasonably @@ -1212,7 +1212,7 @@ static void print_rsvd_warning(struct ubi_device *ubi, * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) { int i, j, err, num_volumes; struct ubi_ainf_volume *sv; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 046618989db9..bec1a51e85ca 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -24,7 +24,7 @@ * This sub-system is responsible for scanning the flash media, checking UBI * headers and providing complete information about the UBI flash image. * - * The scanning information is represented by a &struct ubi_scan_info' object. + * The scanning information is represented by a &struct ubi_attach_info' object. * Information about found volumes is represented by &struct ubi_ainf_volume * objects which are kept in volume RB-tree with root at the @volumes field. * The RB-tree is indexed by the volume ID. @@ -88,7 +88,7 @@ #include #include "ubi.h" -static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); +static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si); /* Temporary variables used during scanning */ static struct ubi_ec_hdr *ech; @@ -110,8 +110,8 @@ static struct ubi_vid_hdr *vidh; * returns zero in case of success and a negative error code in case of * failure. */ -static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, - struct list_head *list) +static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, + int to_head, struct list_head *list) { struct ubi_ainf_peb *seb; @@ -148,7 +148,7 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, int to_head, * The corruption was presumably not caused by a power cut. Returns zero in * case of success and a negative error code in case of failure. */ -static int add_corrupted(struct ubi_scan_info *si, int pnum, int ec) +static int add_corrupted(struct ubi_attach_info *si, int pnum, int ec) { struct ubi_ainf_peb *seb; @@ -244,8 +244,8 @@ bad: * to the scanning volume object in case of success and a negative error code * in case of failure. */ -static struct ubi_ainf_volume *add_volume(struct ubi_scan_info *si, int vol_id, - int pnum, +static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, + int vol_id, int pnum, const struct ubi_vid_hdr *vid_hdr) { struct ubi_ainf_volume *sv; @@ -440,7 +440,7 @@ out_free_vidh: * to be picked, while the older one has to be dropped. This function returns * zero in case of success and a negative error code in case of failure. */ -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) { @@ -593,7 +593,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, * This function returns a pointer to the volume description or %NULL if there * are no data about this volume in the scanning information. */ -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, int vol_id) { struct ubi_ainf_volume *sv; @@ -648,7 +648,7 @@ struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, * @si: scanning information * @sv: the volume scanning information to delete */ -void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) +void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) { struct rb_node *rb; struct ubi_ainf_peb *seb; @@ -679,7 +679,7 @@ void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *si, int pnum, int ec) { int err; @@ -726,7 +726,7 @@ out_free: * success and an error code in case of failure. */ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_scan_info *si) + struct ubi_attach_info *si) { int err = 0; struct ubi_ainf_peb *seb, *tmp_seb; @@ -831,7 +831,7 @@ out_unlock: * This function returns a zero if the physical eraseblock was successfully * handled and a negative error code in case of failure. */ -static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, +static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, int pnum) { long long uninitialized_var(ec); @@ -1073,7 +1073,8 @@ adjust_mean_ec: * MTD device. Returns zero if we should proceed with attaching the MTD device, * and %-EINVAL if we should not. */ -static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) +static int check_what_we_have(struct ubi_device *ubi, + struct ubi_attach_info *si) { struct ubi_ainf_peb *seb; int max_corr, peb_count; @@ -1143,15 +1144,15 @@ static int check_what_we_have(struct ubi_device *ubi, struct ubi_scan_info *si) * This function does full scanning of an MTD device and returns complete * information about it. In case of failure, an error code is returned. */ -struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) +struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) { int err, pnum; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *sv; struct ubi_ainf_peb *seb; - struct ubi_scan_info *si; + struct ubi_attach_info *si; - si = kzalloc(sizeof(struct ubi_scan_info), GFP_KERNEL); + si = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); if (!si) return ERR_PTR(-ENOMEM); @@ -1244,7 +1245,7 @@ out_si: * This function destroys the volume RB-tree (@sv->root) and the scanning * volume information. */ -static void destroy_sv(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) +static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) { struct ubi_ainf_peb *seb; struct rb_node *this = sv->root.rb_node; @@ -1274,7 +1275,7 @@ static void destroy_sv(struct ubi_scan_info *si, struct ubi_ainf_volume *sv) * ubi_scan_destroy_si - destroy scanning information. * @si: scanning information */ -void ubi_scan_destroy_si(struct ubi_scan_info *si) +void ubi_scan_destroy_si(struct ubi_attach_info *si) { struct ubi_ainf_peb *seb, *seb_tmp; struct ubi_ainf_volume *sv; @@ -1333,7 +1334,7 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si) * This function returns zero if the scanning information is all right, and a * negative error code if not or if an error occurred. */ -static int self_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) +static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 5523f0b0fe1d..d32f18315a0e 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -86,7 +86,7 @@ struct ubi_ainf_volume { }; /** - * struct ubi_scan_info - UBI scanning information. + * struct ubi_attach_info - UBI scanning information. * @volumes: root of the volume RB-tree * @corr: list of corrupted physical eraseblocks * @free: list of free physical eraseblocks @@ -115,7 +115,7 @@ struct ubi_ainf_volume { * UBI sub-systems to build final UBI data structures, further error-recovery * and so on. */ -struct ubi_scan_info { +struct ubi_attach_info { struct rb_root volumes; struct list_head corr; struct list_head free; @@ -156,19 +156,19 @@ static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *sv, list_add_tail(&seb->u.list, list); } -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, int vol_id); struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, int lnum); -void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_ainf_volume *sv); +void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_scan_info *si); -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + struct ubi_attach_info *si); +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *si, int pnum, int ec); -struct ubi_scan_info *ubi_scan(struct ubi_device *ubi); -void ubi_scan_destroy_si(struct ubi_scan_info *si); +struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); +void ubi_scan_destroy_si(struct ubi_attach_info *si); #endif /* !__UBI_SCAN_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 75b9f1c61b78..0f206517d811 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -489,7 +489,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, struct ubi_vtbl_record *vtbl_rec); int ubi_vtbl_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list); -int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si); +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si); /* vmt.c */ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req); @@ -529,14 +529,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, const void *buf, int len); int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr); -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si); /* wl.c */ int ubi_wl_get_peb(struct ubi_device *ubi); int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); int ubi_wl_flush(struct ubi_device *ubi); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si); void ubi_wl_close(struct ubi_device *ubi); int ubi_thread(void *u); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 75df84ecad0d..fc797ea8cffa 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -298,7 +298,7 @@ bad: * This function returns zero in case of success and a negative error code in * case of failure. */ -static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, +static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *si, int copy, void *vtbl) { int err, tries = 0; @@ -373,7 +373,7 @@ out_free: * table in case of success and a negative error code in case of failure. */ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, - struct ubi_scan_info *si, + struct ubi_attach_info *si, struct ubi_ainf_volume *sv) { int err; @@ -496,7 +496,7 @@ out_free: * negative error code in case of failure. */ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, - struct ubi_scan_info *si) + struct ubi_attach_info *si) { int i; struct ubi_vtbl_record *vtbl; @@ -531,7 +531,8 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, * Returns zero in case of success and a negative error code in case of * failure. */ -static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, +static int init_volumes(struct ubi_device *ubi, + const struct ubi_attach_info *si, const struct ubi_vtbl_record *vtbl) { int i, reserved_pebs = 0; @@ -712,7 +713,7 @@ bad: * information is OK and %-EINVAL if it is not. */ static int check_scanning_info(const struct ubi_device *ubi, - struct ubi_scan_info *si) + struct ubi_attach_info *si) { int err, i; struct ubi_ainf_volume *sv; @@ -776,7 +777,7 @@ static int check_scanning_info(const struct ubi_device *ubi, * or creates it if needed. Returns zero in case of success and a negative * error code in case of failure. */ -int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) { int i, err; struct ubi_ainf_volume *sv; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 53ef24b48211..12a85d5372cd 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1380,7 +1380,7 @@ static void cancel_pending(struct ubi_device *ubi) * This function returns zero in case of success, and a negative error code in * case of failure. */ -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) { int err, i; struct rb_node *rb1, *rb2; -- cgit v1.2.3 From 209d60d8f11ccb5f91f35513fab9329bd4c65469 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 08:06:01 +0300 Subject: UBI: amend comments after renaming in scan.c Now some commentaries are out-of-date, after we re-named the data structures - amend them. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index d32f18315a0e..9ba00c8f453a 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -25,7 +25,7 @@ #define UBI_SCAN_UNKNOWN_EC (-1) /** - * struct ubi_ainf_peb - scanning information about a physical eraseblock. + * struct ubi_ainf_peb - attach information about a physical eraseblock. * @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown) * @pnum: physical eraseblock number * @lnum: logical eraseblock number @@ -36,8 +36,8 @@ * @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects * @u.list: link in one of the eraseblock lists * - * One object of this type is allocated for each physical eraseblock during - * scanning. + * One object of this type is allocated for each physical eraseblock when + * attaching an MTD device. */ struct ubi_ainf_peb { int ec; @@ -53,7 +53,7 @@ struct ubi_ainf_peb { }; /** - * struct ubi_ainf_volume - scanning information about a volume. + * struct ubi_ainf_volume - attaching information about a volume. * @vol_id: volume ID * @highest_lnum: highest logical eraseblock number in this volume * @leb_count: number of logical eraseblocks in this volume @@ -70,7 +70,8 @@ struct ubi_ainf_peb { * @root: root of the RB-tree containing all the eraseblock belonging to this * volume (&struct ubi_ainf_peb objects) * - * One object of this type is allocated for each volume during scanning. + * One object of this type is allocated for each volume when attaching an MTD + * device. */ struct ubi_ainf_volume { int vol_id; @@ -86,7 +87,7 @@ struct ubi_ainf_volume { }; /** - * struct ubi_attach_info - UBI scanning information. + * struct ubi_attach_info - MTD device attaching information. * @volumes: root of the volume RB-tree * @corr: list of corrupted physical eraseblocks * @free: list of free physical eraseblocks @@ -100,7 +101,7 @@ struct ubi_ainf_volume { * @bad_peb_count: count of bad physical eraseblocks * @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked * as bad yet, but which look like bad - * @vols_found: number of volumes found during scanning + * @vols_found: number of volumes found * @highest_vol_id: highest volume ID * @is_empty: flag indicating whether the MTD device is empty or not * @min_ec: lowest erase counter value @@ -111,9 +112,9 @@ struct ubi_ainf_volume { * @ec_count: a temporary variable used when calculating @mean_ec * @scan_leb_slab: slab cache for &struct ubi_ainf_peb objects * - * This data structure contains the result of scanning and may be used by other - * UBI sub-systems to build final UBI data structures, further error-recovery - * and so on. + * This data structure contains the result of attaching an MTD device and may + * be used by other UBI sub-systems to build final UBI data structures, further + * error-recovery and so on. */ struct ubi_attach_info { struct rb_root volumes; -- cgit v1.2.3 From 1d69aaeba3bb9a5cdd04b398e1ed1a408f53ac52 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 08:26:24 +0300 Subject: UBI: rename seb to aeb After re-naming the 'struct ubi_scan_leb' we should adjust all variables named 'seb' to something else, because 'seb' stands for "scanning eraseblock". Let's rename it to 'aeb' which stands for "attaching eraseblock" which is a bit more consistend and has the same length. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 16 +-- drivers/mtd/ubi/debug.h | 2 +- drivers/mtd/ubi/eba.c | 10 +- drivers/mtd/ubi/scan.c | 296 ++++++++++++++++++++++++------------------------ drivers/mtd/ubi/scan.h | 10 +- drivers/mtd/ubi/vtbl.c | 36 +++--- drivers/mtd/ubi/wl.c | 22 ++-- 7 files changed, 196 insertions(+), 196 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 92b5d810a8e7..380f2d74a5d9 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -188,19 +188,19 @@ void ubi_dump_sv(const struct ubi_ainf_volume *sv) } /** - * ubi_dump_seb - dump a &struct ubi_ainf_peb object. - * @seb: the object to dump + * ubi_dump_aeb - dump a &struct ubi_ainf_peb object. + * @aeb: the object to dump * @type: object type: 0 - not corrupted, 1 - corrupted */ -void ubi_dump_seb(const struct ubi_ainf_peb *seb, int type) +void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type) { printk(KERN_DEBUG "eraseblock scanning information dump:\n"); - printk(KERN_DEBUG "\tec %d\n", seb->ec); - printk(KERN_DEBUG "\tpnum %d\n", seb->pnum); + printk(KERN_DEBUG "\tec %d\n", aeb->ec); + printk(KERN_DEBUG "\tpnum %d\n", aeb->pnum); if (type == 0) { - printk(KERN_DEBUG "\tlnum %d\n", seb->lnum); - printk(KERN_DEBUG "\tscrub %d\n", seb->scrub); - printk(KERN_DEBUG "\tsqnum %llu\n", seb->sqnum); + printk(KERN_DEBUG "\tlnum %d\n", aeb->lnum); + printk(KERN_DEBUG "\tscrub %d\n", aeb->scrub); + printk(KERN_DEBUG "\tsqnum %llu\n", aeb->sqnum); } } diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 041ee4d43dec..a0911c0c1064 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -60,7 +60,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dump_sv(const struct ubi_ainf_volume *sv); -void ubi_dump_seb(const struct ubi_ainf_peb *seb, int type); +void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 4b3cf31e9a92..88a52546923a 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1217,7 +1217,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) int i, j, err, num_volumes; struct ubi_ainf_volume *sv; struct ubi_volume *vol; - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct rb_node *rb; dbg_eba("initialize EBA sub-system"); @@ -1250,14 +1250,14 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) if (!sv) continue; - ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { - if (seb->lnum >= vol->reserved_pebs) + ubi_rb_for_each_entry(rb, aeb, &sv->root, u.rb) { + if (aeb->lnum >= vol->reserved_pebs) /* * This may happen in case of an unclean reboot * during re-size. */ - ubi_scan_move_to_list(sv, seb, &si->erase); - vol->eba_tbl[seb->lnum] = seb->pnum; + ubi_scan_move_to_list(sv, aeb, &si->erase); + vol->eba_tbl[aeb->lnum] = aeb->pnum; } } diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index bec1a51e85ca..d4b823b8f2a4 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -113,7 +113,7 @@ static struct ubi_vid_hdr *vidh; static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, int to_head, struct list_head *list) { - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; if (list == &si->free) { dbg_bld("add to free: PEB %d, EC %d", pnum, ec); @@ -125,16 +125,16 @@ static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, } else BUG(); - seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); - if (!seb) + aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + if (!aeb) return -ENOMEM; - seb->pnum = pnum; - seb->ec = ec; + aeb->pnum = pnum; + aeb->ec = ec; if (to_head) - list_add(&seb->u.list, list); + list_add(&aeb->u.list, list); else - list_add_tail(&seb->u.list, list); + list_add_tail(&aeb->u.list, list); return 0; } @@ -150,18 +150,18 @@ static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, */ static int add_corrupted(struct ubi_attach_info *si, int pnum, int ec) { - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); - seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); - if (!seb) + aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + if (!aeb) return -ENOMEM; si->corr_peb_count += 1; - seb->pnum = pnum; - seb->ec = ec; - list_add(&seb->u.list, &si->corr); + aeb->pnum = pnum; + aeb->ec = ec; + list_add(&aeb->u.list, &si->corr); return 0; } @@ -293,7 +293,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, /** * compare_lebs - find out which logical eraseblock is newer. * @ubi: UBI device description object - * @seb: first logical eraseblock to compare + * @aeb: first logical eraseblock to compare * @pnum: physical eraseblock number of the second logical eraseblock to * compare * @vid_hdr: volume identifier header of the second logical eraseblock @@ -302,7 +302,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, * case of success this function returns a positive value, in case of failure, a * negative error code is returned. The success return codes use the following * bits: - * o bit 0 is cleared: the first PEB (described by @seb) is newer than the + * o bit 0 is cleared: the first PEB (described by @aeb) is newer than the * second PEB (described by @pnum and @vid_hdr); * o bit 0 is set: the second PEB is newer; * o bit 1 is cleared: no bit-flips were detected in the newer LEB; @@ -310,7 +310,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, * o bit 2 is cleared: the older LEB is not corrupted; * o bit 2 is set: the older LEB is corrupted. */ -static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, +static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, int pnum, const struct ubi_vid_hdr *vid_hdr) { void *buf; @@ -319,7 +319,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, struct ubi_vid_hdr *vh = NULL; unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); - if (sqnum2 == seb->sqnum) { + if (sqnum2 == aeb->sqnum) { /* * This must be a really ancient UBI image which has been * created before sequence numbers support has been added. At @@ -333,7 +333,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, } /* Obviously the LEB with lower sequence counter is older */ - second_is_newer = (sqnum2 > seb->sqnum); + second_is_newer = (sqnum2 > aeb->sqnum); /* * Now we know which copy is newer. If the copy flag of the PEB with @@ -352,7 +352,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, return 1; } } else { - if (!seb->copy_flag) { + if (!aeb->copy_flag) { /* It is not a copy, so it is newer */ dbg_bld("first PEB %d is newer, copy_flag is unset", pnum); @@ -363,7 +363,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *seb, if (!vh) return -ENOMEM; - pnum = seb->pnum; + pnum = aeb->pnum; err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (err) { if (err == UBI_IO_BITFLIPS) @@ -447,7 +447,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, int err, vol_id, lnum; unsigned long long sqnum; struct ubi_ainf_volume *sv; - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct rb_node **p, *parent = NULL; vol_id = be32_to_cpu(vid_hdr->vol_id); @@ -473,9 +473,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, int cmp_res; parent = *p; - seb = rb_entry(parent, struct ubi_ainf_peb, u.rb); - if (lnum != seb->lnum) { - if (lnum < seb->lnum) + aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); + if (lnum != aeb->lnum) { + if (lnum < aeb->lnum) p = &(*p)->rb_left; else p = &(*p)->rb_right; @@ -487,8 +487,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, * logical eraseblock present. */ - dbg_bld("this LEB already exists: PEB %d, sqnum %llu, " - "EC %d", seb->pnum, seb->sqnum, seb->ec); + dbg_bld("this LEB already exists: PEB %d, sqnum %llu, EC %d", + aeb->pnum, aeb->sqnum, aeb->ec); /* * Make sure that the logical eraseblocks have different @@ -503,10 +503,10 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, * images, but refuse attaching old images with duplicated * logical eraseblocks because there was an unclean reboot. */ - if (seb->sqnum == sqnum && sqnum != 0) { + if (aeb->sqnum == sqnum && sqnum != 0) { ubi_err("two LEBs with same sequence number %llu", sqnum); - ubi_dump_seb(seb, 0); + ubi_dump_aeb(aeb, 0); ubi_dump_vid_hdr(vid_hdr); return -EINVAL; } @@ -515,7 +515,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, * Now we have to drop the older one and preserve the newer * one. */ - cmp_res = compare_lebs(ubi, seb, pnum, vid_hdr); + cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr); if (cmp_res < 0) return cmp_res; @@ -528,16 +528,16 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, if (err) return err; - err = add_to_list(si, seb->pnum, seb->ec, cmp_res & 4, + err = add_to_list(si, aeb->pnum, aeb->ec, cmp_res & 4, &si->erase); if (err) return err; - seb->ec = ec; - seb->pnum = pnum; - seb->scrub = ((cmp_res & 2) || bitflips); - seb->copy_flag = vid_hdr->copy_flag; - seb->sqnum = sqnum; + aeb->ec = ec; + aeb->pnum = pnum; + aeb->scrub = ((cmp_res & 2) || bitflips); + aeb->copy_flag = vid_hdr->copy_flag; + aeb->sqnum = sqnum; if (sv->highest_lnum == lnum) sv->last_data_size = @@ -563,16 +563,16 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, if (err) return err; - seb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); - if (!seb) + aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + if (!aeb) return -ENOMEM; - seb->ec = ec; - seb->pnum = pnum; - seb->lnum = lnum; - seb->scrub = bitflips; - seb->copy_flag = vid_hdr->copy_flag; - seb->sqnum = sqnum; + aeb->ec = ec; + aeb->pnum = pnum; + aeb->lnum = lnum; + aeb->scrub = bitflips; + aeb->copy_flag = vid_hdr->copy_flag; + aeb->sqnum = sqnum; if (sv->highest_lnum <= lnum) { sv->highest_lnum = lnum; @@ -580,8 +580,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, } sv->leb_count += 1; - rb_link_node(&seb->u.rb, parent, p); - rb_insert_color(&seb->u.rb, &sv->root); + rb_link_node(&aeb->u.rb, parent, p); + rb_insert_color(&aeb->u.rb, &sv->root); return 0; } @@ -615,26 +615,26 @@ struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, } /** - * ubi_scan_find_seb - find LEB in the volume scanning information. + * ubi_scan_find_aeb - find LEB in the volume scanning information. * @sv: a pointer to the volume scanning information * @lnum: the requested logical eraseblock * * This function returns a pointer to the scanning logical eraseblock or %NULL * if there are no data about it in the scanning volume information. */ -struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, int lnum) { - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct rb_node *p = sv->root.rb_node; while (p) { - seb = rb_entry(p, struct ubi_ainf_peb, u.rb); + aeb = rb_entry(p, struct ubi_ainf_peb, u.rb); - if (lnum == seb->lnum) - return seb; + if (lnum == aeb->lnum) + return aeb; - if (lnum > seb->lnum) + if (lnum > aeb->lnum) p = p->rb_left; else p = p->rb_right; @@ -651,14 +651,14 @@ struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) { struct rb_node *rb; - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; dbg_bld("remove scanning information about volume %d", sv->vol_id); while ((rb = rb_first(&sv->root))) { - seb = rb_entry(rb, struct ubi_ainf_peb, u.rb); - rb_erase(&seb->u.rb, &sv->root); - list_add_tail(&seb->u.list, &si->erase); + aeb = rb_entry(rb, struct ubi_ainf_peb, u.rb); + rb_erase(&aeb->u.rb, &sv->root); + list_add_tail(&aeb->u.list, &si->erase); } rb_erase(&sv->rb, &si->volumes); @@ -729,13 +729,13 @@ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *si) { int err = 0; - struct ubi_ainf_peb *seb, *tmp_seb; + struct ubi_ainf_peb *aeb, *tmp_aeb; if (!list_empty(&si->free)) { - seb = list_entry(si->free.next, struct ubi_ainf_peb, u.list); - list_del(&seb->u.list); - dbg_bld("return free PEB %d, EC %d", seb->pnum, seb->ec); - return seb; + aeb = list_entry(si->free.next, struct ubi_ainf_peb, u.list); + list_del(&aeb->u.list); + dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec); + return aeb; } /* @@ -744,18 +744,18 @@ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, * so forth. We don't want to take care about bad eraseblocks here - * they'll be handled later. */ - list_for_each_entry_safe(seb, tmp_seb, &si->erase, u.list) { - if (seb->ec == UBI_SCAN_UNKNOWN_EC) - seb->ec = si->mean_ec; + list_for_each_entry_safe(aeb, tmp_aeb, &si->erase, u.list) { + if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + aeb->ec = si->mean_ec; - err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1); + err = ubi_scan_erase_peb(ubi, si, aeb->pnum, aeb->ec+1); if (err) continue; - seb->ec += 1; - list_del(&seb->u.list); - dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec); - return seb; + aeb->ec += 1; + list_del(&aeb->u.list); + dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec); + return aeb; } ubi_err("no free eraseblocks"); @@ -1076,7 +1076,7 @@ adjust_mean_ec: static int check_what_we_have(struct ubi_device *ubi, struct ubi_attach_info *si) { - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; int max_corr, peb_count; peb_count = ubi->peb_count - si->bad_peb_count - si->alien_peb_count; @@ -1091,8 +1091,8 @@ static int check_what_we_have(struct ubi_device *ubi, ubi_err("%d PEBs are corrupted and preserved", si->corr_peb_count); printk(KERN_ERR "Corrupted PEBs are:"); - list_for_each_entry(seb, &si->corr, u.list) - printk(KERN_CONT " %d", seb->pnum); + list_for_each_entry(aeb, &si->corr, u.list) + printk(KERN_CONT " %d", aeb->pnum); printk(KERN_CONT "\n"); /* @@ -1149,7 +1149,7 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) int err, pnum; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *sv; - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct ubi_attach_info *si; si = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); @@ -1201,23 +1201,23 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) * value. */ ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { - ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) - if (seb->ec == UBI_SCAN_UNKNOWN_EC) - seb->ec = si->mean_ec; + ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) + if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + aeb->ec = si->mean_ec; } - list_for_each_entry(seb, &si->free, u.list) { - if (seb->ec == UBI_SCAN_UNKNOWN_EC) - seb->ec = si->mean_ec; + list_for_each_entry(aeb, &si->free, u.list) { + if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + aeb->ec = si->mean_ec; } - list_for_each_entry(seb, &si->corr, u.list) - if (seb->ec == UBI_SCAN_UNKNOWN_EC) - seb->ec = si->mean_ec; + list_for_each_entry(aeb, &si->corr, u.list) + if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + aeb->ec = si->mean_ec; - list_for_each_entry(seb, &si->erase, u.list) - if (seb->ec == UBI_SCAN_UNKNOWN_EC) - seb->ec = si->mean_ec; + list_for_each_entry(aeb, &si->erase, u.list) + if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + aeb->ec = si->mean_ec; err = self_check_si(ubi, si); if (err) @@ -1247,7 +1247,7 @@ out_si: */ static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) { - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct rb_node *this = sv->root.rb_node; while (this) { @@ -1256,16 +1256,16 @@ static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) else if (this->rb_right) this = this->rb_right; else { - seb = rb_entry(this, struct ubi_ainf_peb, u.rb); + aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); this = rb_parent(this); if (this) { - if (this->rb_left == &seb->u.rb) + if (this->rb_left == &aeb->u.rb) this->rb_left = NULL; else this->rb_right = NULL; } - kmem_cache_free(si->scan_leb_slab, seb); + kmem_cache_free(si->scan_leb_slab, aeb); } } kfree(sv); @@ -1277,25 +1277,25 @@ static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) */ void ubi_scan_destroy_si(struct ubi_attach_info *si) { - struct ubi_ainf_peb *seb, *seb_tmp; + struct ubi_ainf_peb *aeb, *aeb_tmp; struct ubi_ainf_volume *sv; struct rb_node *rb; - list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) { - list_del(&seb->u.list); - kmem_cache_free(si->scan_leb_slab, seb); + list_for_each_entry_safe(aeb, aeb_tmp, &si->alien, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(si->scan_leb_slab, aeb); } - list_for_each_entry_safe(seb, seb_tmp, &si->erase, u.list) { - list_del(&seb->u.list); - kmem_cache_free(si->scan_leb_slab, seb); + list_for_each_entry_safe(aeb, aeb_tmp, &si->erase, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(si->scan_leb_slab, aeb); } - list_for_each_entry_safe(seb, seb_tmp, &si->corr, u.list) { - list_del(&seb->u.list); - kmem_cache_free(si->scan_leb_slab, seb); + list_for_each_entry_safe(aeb, aeb_tmp, &si->corr, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(si->scan_leb_slab, aeb); } - list_for_each_entry_safe(seb, seb_tmp, &si->free, u.list) { - list_del(&seb->u.list); - kmem_cache_free(si->scan_leb_slab, seb); + list_for_each_entry_safe(aeb, aeb_tmp, &si->free, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(si->scan_leb_slab, aeb); } /* Destroy the volume RB-tree */ @@ -1339,7 +1339,7 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *sv; - struct ubi_ainf_peb *seb, *last_seb; + struct ubi_ainf_peb *aeb, *last_aeb; uint8_t *buf; if (!ubi->dbg->chk_gen) @@ -1390,51 +1390,51 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_sv; } - last_seb = NULL; - ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + last_aeb = NULL; + ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { cond_resched(); - last_seb = seb; + last_aeb = aeb; leb_count += 1; - if (seb->pnum < 0 || seb->ec < 0) { + if (aeb->pnum < 0 || aeb->ec < 0) { ubi_err("negative values"); - goto bad_seb; + goto bad_aeb; } - if (seb->ec < si->min_ec) { + if (aeb->ec < si->min_ec) { ubi_err("bad si->min_ec (%d), %d found", - si->min_ec, seb->ec); - goto bad_seb; + si->min_ec, aeb->ec); + goto bad_aeb; } - if (seb->ec > si->max_ec) { + if (aeb->ec > si->max_ec) { ubi_err("bad si->max_ec (%d), %d found", - si->max_ec, seb->ec); - goto bad_seb; + si->max_ec, aeb->ec); + goto bad_aeb; } - if (seb->pnum >= ubi->peb_count) { + if (aeb->pnum >= ubi->peb_count) { ubi_err("too high PEB number %d, total PEBs %d", - seb->pnum, ubi->peb_count); - goto bad_seb; + aeb->pnum, ubi->peb_count); + goto bad_aeb; } if (sv->vol_type == UBI_STATIC_VOLUME) { - if (seb->lnum >= sv->used_ebs) { + if (aeb->lnum >= sv->used_ebs) { ubi_err("bad lnum or used_ebs"); - goto bad_seb; + goto bad_aeb; } } else { if (sv->used_ebs != 0) { ubi_err("non-zero used_ebs"); - goto bad_seb; + goto bad_aeb; } } - if (seb->lnum > sv->highest_lnum) { + if (aeb->lnum > sv->highest_lnum) { ubi_err("incorrect highest_lnum or lnum"); - goto bad_seb; + goto bad_aeb; } } @@ -1444,14 +1444,14 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_sv; } - if (!last_seb) + if (!last_aeb) continue; - seb = last_seb; + aeb = last_aeb; - if (seb->lnum != sv->highest_lnum) { + if (aeb->lnum != sv->highest_lnum) { ubi_err("bad highest_lnum"); - goto bad_seb; + goto bad_aeb; } } @@ -1463,15 +1463,15 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) /* Check that scanning information is correct */ ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { - last_seb = NULL; - ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + last_aeb = NULL; + ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { int vol_type; cond_resched(); - last_seb = seb; + last_aeb = aeb; - err = ubi_io_read_vid_hdr(ubi, seb->pnum, vidh, 1); + err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidh, 1); if (err && err != UBI_IO_BITFLIPS) { ubi_err("VID header is not OK (%d)", err); if (err > 0) @@ -1486,8 +1486,8 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_vid_hdr; } - if (seb->sqnum != be64_to_cpu(vidh->sqnum)) { - ubi_err("bad sqnum %llu", seb->sqnum); + if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { + ubi_err("bad sqnum %llu", aeb->sqnum); goto bad_vid_hdr; } @@ -1501,8 +1501,8 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_vid_hdr; } - if (seb->lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad lnum %d", seb->lnum); + if (aeb->lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad lnum %d", aeb->lnum); goto bad_vid_hdr; } @@ -1517,7 +1517,7 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) } } - if (!last_seb) + if (!last_aeb) continue; if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) { @@ -1549,20 +1549,20 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) } ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) - ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) - buf[seb->pnum] = 1; + ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) + buf[aeb->pnum] = 1; - list_for_each_entry(seb, &si->free, u.list) - buf[seb->pnum] = 1; + list_for_each_entry(aeb, &si->free, u.list) + buf[aeb->pnum] = 1; - list_for_each_entry(seb, &si->corr, u.list) - buf[seb->pnum] = 1; + list_for_each_entry(aeb, &si->corr, u.list) + buf[aeb->pnum] = 1; - list_for_each_entry(seb, &si->erase, u.list) - buf[seb->pnum] = 1; + list_for_each_entry(aeb, &si->erase, u.list) + buf[aeb->pnum] = 1; - list_for_each_entry(seb, &si->alien, u.list) - buf[seb->pnum] = 1; + list_for_each_entry(aeb, &si->alien, u.list) + buf[aeb->pnum] = 1; err = 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) @@ -1576,9 +1576,9 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto out; return 0; -bad_seb: - ubi_err("bad scanning information about LEB %d", seb->lnum); - ubi_dump_seb(seb, 0); +bad_aeb: + ubi_err("bad scanning information about LEB %d", aeb->lnum); + ubi_dump_aeb(aeb, 0); ubi_dump_sv(sv); goto out; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 9ba00c8f453a..7e20a85b8c31 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -146,15 +146,15 @@ struct ubi_vid_hdr; * ubi_scan_move_to_list - move a PEB from the volume tree to a list. * * @sv: volume scanning information - * @seb: scanning eraseblock information + * @aeb: scanning eraseblock information * @list: the list to move to */ static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *sv, - struct ubi_ainf_peb *seb, + struct ubi_ainf_peb *aeb, struct list_head *list) { - rb_erase(&seb->u.rb, &sv->root); - list_add_tail(&seb->u.list, list); + rb_erase(&aeb->u.rb, &sv->root); + list_add_tail(&aeb->u.list, list); } int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, @@ -162,7 +162,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, int bitflips); struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, int vol_id); -struct ubi_ainf_peb *ubi_scan_find_seb(const struct ubi_ainf_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, int lnum); void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fc797ea8cffa..f6f8cc5b06ad 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -303,7 +303,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *si, { int err, tries = 0; struct ubi_vid_hdr *vid_hdr; - struct ubi_ainf_peb *new_seb; + struct ubi_ainf_peb *new_aeb; ubi_msg("create volume table (copy #%d)", copy + 1); @@ -312,9 +312,9 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *si, return -ENOMEM; retry: - new_seb = ubi_scan_get_free_peb(ubi, si); - if (IS_ERR(new_seb)) { - err = PTR_ERR(new_seb); + new_aeb = ubi_scan_get_free_peb(ubi, si); + if (IS_ERR(new_aeb)) { + err = PTR_ERR(new_aeb); goto out_free; } @@ -327,12 +327,12 @@ retry: vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum); /* The EC header is already there, write the VID header */ - err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); + err = ubi_io_write_vid_hdr(ubi, new_aeb->pnum, vid_hdr); if (err) goto write_error; /* Write the layout volume contents */ - err = ubi_io_write_data(ubi, vtbl, new_seb->pnum, 0, ubi->vtbl_size); + err = ubi_io_write_data(ubi, vtbl, new_aeb->pnum, 0, ubi->vtbl_size); if (err) goto write_error; @@ -340,9 +340,9 @@ retry: * And add it to the scanning information. Don't delete the old version * of this LEB as it will be deleted and freed in 'ubi_scan_add_used()'. */ - err = ubi_scan_add_used(ubi, si, new_seb->pnum, new_seb->ec, + err = ubi_scan_add_used(ubi, si, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); - kfree(new_seb); + kfree(new_aeb); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -352,10 +352,10 @@ write_error: * Probably this physical eraseblock went bad, try to pick * another one. */ - list_add(&new_seb->u.list, &si->erase); + list_add(&new_aeb->u.list, &si->erase); goto retry; } - kfree(new_seb); + kfree(new_aeb); out_free: ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -378,7 +378,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, { int err; struct rb_node *rb; - struct ubi_ainf_peb *seb; + struct ubi_ainf_peb *aeb; struct ubi_vtbl_record *leb[UBI_LAYOUT_VOLUME_EBS] = { NULL, NULL }; int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1}; @@ -410,14 +410,14 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, dbg_gen("check layout volume"); /* Read both LEB 0 and LEB 1 into memory */ - ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { - leb[seb->lnum] = vzalloc(ubi->vtbl_size); - if (!leb[seb->lnum]) { + ubi_rb_for_each_entry(rb, aeb, &sv->root, u.rb) { + leb[aeb->lnum] = vzalloc(ubi->vtbl_size); + if (!leb[aeb->lnum]) { err = -ENOMEM; goto out_free; } - err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, + err = ubi_io_read_data(ubi, leb[aeb->lnum], aeb->pnum, 0, ubi->vtbl_size); if (err == UBI_IO_BITFLIPS || err == -EBADMSG) /* @@ -425,12 +425,12 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, * uncorrectable ECC error, but we have our own CRC and * the data will be checked later. If the data is OK, * the PEB will be scrubbed (because we set - * seb->scrub). If the data is not OK, the contents of + * aeb->scrub). If the data is not OK, the contents of * the PEB will be recovered from the second copy, and - * seb->scrub will be cleared in + * aeb->scrub will be cleared in * 'ubi_scan_add_used()'. */ - seb->scrub = 1; + aeb->scrub = 1; else if (err) goto out_free; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 12a85d5372cd..fb870f4fc924 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1385,7 +1385,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) int err, i; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *sv; - struct ubi_ainf_peb *seb, *tmp; + struct ubi_ainf_peb *aeb, *tmp; struct ubi_wl_entry *e; ubi->used = ubi->erroneous = ubi->free = ubi->scrub = RB_ROOT; @@ -1406,15 +1406,15 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) INIT_LIST_HEAD(&ubi->pq[i]); ubi->pq_head = 0; - list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { + list_for_each_entry_safe(aeb, tmp, &si->erase, u.list) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); if (!e) goto out_free; - e->pnum = seb->pnum; - e->ec = seb->ec; + e->pnum = aeb->pnum; + e->ec = aeb->ec; ubi->lookuptbl[e->pnum] = e; if (schedule_erase(ubi, e, 0)) { kmem_cache_free(ubi_wl_entry_slab, e); @@ -1422,32 +1422,32 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) } } - list_for_each_entry(seb, &si->free, u.list) { + list_for_each_entry(aeb, &si->free, u.list) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); if (!e) goto out_free; - e->pnum = seb->pnum; - e->ec = seb->ec; + e->pnum = aeb->pnum; + e->ec = aeb->ec; ubi_assert(e->ec >= 0); wl_tree_add(e, &ubi->free); ubi->lookuptbl[e->pnum] = e; } ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { - ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); if (!e) goto out_free; - e->pnum = seb->pnum; - e->ec = seb->ec; + e->pnum = aeb->pnum; + e->ec = aeb->ec; ubi->lookuptbl[e->pnum] = e; - if (!seb->scrub) { + if (!aeb->scrub) { dbg_wl("add PEB %d EC %d to the used tree", e->pnum, e->ec); wl_tree_add(e, &ubi->used); -- cgit v1.2.3 From 658656722fdb1e13cd4f1079ba61c2ebafcd103b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 13:09:08 +0300 Subject: UBI: rename si to ai After re-naming the 'struct ubi_scan_info' we should adjust all variables named 'si' to something else, because 'si' stands for "scanning info". Let's rename it to 'ai' which stands for "attaching info" which is a bit more consistent and has the same length, which makes re-naming easy. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 32 ++--- drivers/mtd/ubi/debug.c | 4 +- drivers/mtd/ubi/eba.c | 18 +-- drivers/mtd/ubi/scan.c | 346 ++++++++++++++++++++++++------------------------ drivers/mtd/ubi/scan.h | 14 +- drivers/mtd/ubi/ubi.h | 6 +- drivers/mtd/ubi/vtbl.c | 86 ++++++------ drivers/mtd/ubi/wl.c | 14 +- 8 files changed, 260 insertions(+), 260 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index b239a22e6ae2..404d26ad9020 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -583,32 +583,32 @@ static void free_internal_volumes(struct ubi_device *ubi) static int attach_by_scanning(struct ubi_device *ubi) { int err; - struct ubi_attach_info *si; + struct ubi_attach_info *ai; - si = ubi_scan(ubi); - if (IS_ERR(si)) - return PTR_ERR(si); + ai = ubi_scan(ubi); + if (IS_ERR(ai)) + return PTR_ERR(ai); - ubi->bad_peb_count = si->bad_peb_count; + ubi->bad_peb_count = ai->bad_peb_count; ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; - ubi->corr_peb_count = si->corr_peb_count; - ubi->max_ec = si->max_ec; - ubi->mean_ec = si->mean_ec; - ubi_msg("max. sequence number: %llu", si->max_sqnum); + ubi->corr_peb_count = ai->corr_peb_count; + ubi->max_ec = ai->max_ec; + ubi->mean_ec = ai->mean_ec; + ubi_msg("max. sequence number: %llu", ai->max_sqnum); - err = ubi_read_volume_table(ubi, si); + err = ubi_read_volume_table(ubi, ai); if (err) - goto out_si; + goto out_ai; - err = ubi_wl_init_scan(ubi, si); + err = ubi_wl_init_scan(ubi, ai); if (err) goto out_vtbl; - err = ubi_eba_init_scan(ubi, si); + err = ubi_eba_init_scan(ubi, ai); if (err) goto out_wl; - ubi_scan_destroy_si(si); + ubi_scan_destroy_ai(ai); return 0; out_wl: @@ -616,8 +616,8 @@ out_wl: out_vtbl: free_internal_volumes(ubi); vfree(ubi->vtbl); -out_si: - ubi_scan_destroy_si(si); +out_ai: + ubi_scan_destroy_ai(ai); return err; } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 380f2d74a5d9..f46d276ecd7c 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -176,7 +176,7 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) */ void ubi_dump_sv(const struct ubi_ainf_volume *sv) { - printk(KERN_DEBUG "Volume scanning information dump:\n"); + printk(KERN_DEBUG "Volume attaching information dump:\n"); printk(KERN_DEBUG "\tvol_id %d\n", sv->vol_id); printk(KERN_DEBUG "\thighest_lnum %d\n", sv->highest_lnum); printk(KERN_DEBUG "\tleb_count %d\n", sv->leb_count); @@ -194,7 +194,7 @@ void ubi_dump_sv(const struct ubi_ainf_volume *sv) */ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type) { - printk(KERN_DEBUG "eraseblock scanning information dump:\n"); + printk(KERN_DEBUG "eraseblock attaching information dump:\n"); printk(KERN_DEBUG "\tec %d\n", aeb->ec); printk(KERN_DEBUG "\tpnum %d\n", aeb->pnum); if (type == 0) { diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 88a52546923a..7e91a6e57c44 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1182,13 +1182,13 @@ out_unlock_leb: * reported by real users. */ static void print_rsvd_warning(struct ubi_device *ubi, - struct ubi_attach_info *si) + struct ubi_attach_info *ai) { /* * The 1 << 18 (256KiB) number is picked randomly, just a reasonably * large number to distinguish between newly flashed and used images. */ - if (si->max_sqnum > (1 << 18)) { + if (ai->max_sqnum > (1 << 18)) { int min = ubi->beb_rsvd_level / 10; if (!min) @@ -1205,14 +1205,14 @@ static void print_rsvd_warning(struct ubi_device *ubi, } /** - * ubi_eba_init_scan - initialize the EBA sub-system using scanning information. + * ubi_eba_init_scan - initialize the EBA sub-system using attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) { int i, j, err, num_volumes; struct ubi_ainf_volume *sv; @@ -1226,7 +1226,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) mutex_init(&ubi->alc_mutex); ubi->ltree = RB_ROOT; - ubi->global_sqnum = si->max_sqnum + 1; + ubi->global_sqnum = ai->max_sqnum + 1; num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; for (i = 0; i < num_volumes; i++) { @@ -1246,7 +1246,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) for (j = 0; j < vol->reserved_pebs; j++) vol->eba_tbl[j] = UBI_LEB_UNMAPPED; - sv = ubi_scan_find_sv(si, idx2vol_id(ubi, i)); + sv = ubi_scan_find_sv(ai, idx2vol_id(ubi, i)); if (!sv) continue; @@ -1256,7 +1256,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) * This may happen in case of an unclean reboot * during re-size. */ - ubi_scan_move_to_list(sv, aeb, &si->erase); + ubi_scan_move_to_list(sv, aeb, &ai->erase); vol->eba_tbl[aeb->lnum] = aeb->pnum; } } @@ -1279,7 +1279,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) if (ubi->avail_pebs < ubi->beb_rsvd_level) { /* No enough free physical eraseblocks */ ubi->beb_rsvd_pebs = ubi->avail_pebs; - print_rsvd_warning(ubi, si); + print_rsvd_warning(ubi, ai); } else ubi->beb_rsvd_pebs = ubi->beb_rsvd_level; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index d4b823b8f2a4..a36319b07539 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -24,10 +24,10 @@ * This sub-system is responsible for scanning the flash media, checking UBI * headers and providing complete information about the UBI flash image. * - * The scanning information is represented by a &struct ubi_attach_info' object. - * Information about found volumes is represented by &struct ubi_ainf_volume - * objects which are kept in volume RB-tree with root at the @volumes field. - * The RB-tree is indexed by the volume ID. + * The attaching information is represented by a &struct ubi_attach_info' + * object. Information about found volumes is represented by + * &struct ubi_ainf_volume objects which are kept in volume RB-tree with root + * at the @volumes field. The RB-tree is indexed by the volume ID. * * Scanned logical eraseblocks are represented by &struct ubi_ainf_peb objects. * These objects are kept in per-volume RB-trees with the root at the @@ -88,7 +88,7 @@ #include #include "ubi.h" -static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si); +static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai); /* Temporary variables used during scanning */ static struct ubi_ec_hdr *ech; @@ -96,7 +96,7 @@ static struct ubi_vid_hdr *vidh; /** * add_to_list - add physical eraseblock to a list. - * @si: scanning information + * @ai: attaching information * @pnum: physical eraseblock number to add * @ec: erase counter of the physical eraseblock * @to_head: if not zero, add to the head of the list @@ -110,22 +110,22 @@ static struct ubi_vid_hdr *vidh; * returns zero in case of success and a negative error code in case of * failure. */ -static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, +static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, int to_head, struct list_head *list) { struct ubi_ainf_peb *aeb; - if (list == &si->free) { + if (list == &ai->free) { dbg_bld("add to free: PEB %d, EC %d", pnum, ec); - } else if (list == &si->erase) { + } else if (list == &ai->erase) { dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); - } else if (list == &si->alien) { + } else if (list == &ai->alien) { dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); - si->alien_peb_count += 1; + ai->alien_peb_count += 1; } else BUG(); - aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); if (!aeb) return -ENOMEM; @@ -140,7 +140,7 @@ static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, /** * add_corrupted - add a corrupted physical eraseblock. - * @si: scanning information + * @ai: attaching information * @pnum: physical eraseblock number to add * @ec: erase counter of the physical eraseblock * @@ -148,20 +148,20 @@ static int add_to_list(struct ubi_attach_info *si, int pnum, int ec, * The corruption was presumably not caused by a power cut. Returns zero in * case of success and a negative error code in case of failure. */ -static int add_corrupted(struct ubi_attach_info *si, int pnum, int ec) +static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) { struct ubi_ainf_peb *aeb; dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); - aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); if (!aeb) return -ENOMEM; - si->corr_peb_count += 1; + ai->corr_peb_count += 1; aeb->pnum = pnum; aeb->ec = ec; - list_add(&aeb->u.list, &si->corr); + list_add(&aeb->u.list, &ai->corr); return 0; } @@ -232,24 +232,24 @@ bad: } /** - * add_volume - add volume to the scanning information. - * @si: scanning information + * add_volume - add volume to the attaching information. + * @ai: attaching information * @vol_id: ID of the volume to add * @pnum: physical eraseblock number * @vid_hdr: volume identifier header * * If the volume corresponding to the @vid_hdr logical eraseblock is already - * present in the scanning information, this function does nothing. Otherwise - * it adds corresponding volume to the scanning information. Returns a pointer + * present in the attaching information, this function does nothing. Otherwise + * it adds corresponding volume to the attaching information. Returns a pointer * to the scanning volume object in case of success and a negative error code * in case of failure. */ -static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, +static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, int vol_id, int pnum, const struct ubi_vid_hdr *vid_hdr) { struct ubi_ainf_volume *sv; - struct rb_node **p = &si->volumes.rb_node, *parent = NULL; + struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); @@ -280,12 +280,12 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *si, sv->compat = vid_hdr->compat; sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; - if (vol_id > si->highest_vol_id) - si->highest_vol_id = vol_id; + if (vol_id > ai->highest_vol_id) + ai->highest_vol_id = vol_id; rb_link_node(&sv->rb, parent, p); - rb_insert_color(&sv->rb, &si->volumes); - si->vols_found += 1; + rb_insert_color(&sv->rb, &ai->volumes); + ai->vols_found += 1; dbg_bld("added volume %d", vol_id); return sv; } @@ -425,9 +425,9 @@ out_free_vidh: } /** - * ubi_scan_add_used - add physical eraseblock to the scanning information. + * ubi_scan_add_used - add physical eraseblock to the attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * @pnum: the physical eraseblock number * @ec: erase counter * @vid_hdr: the volume identifier header @@ -440,7 +440,7 @@ out_free_vidh: * to be picked, while the older one has to be dropped. This function returns * zero in case of success and a negative error code in case of failure. */ -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) { @@ -457,12 +457,12 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", pnum, vol_id, lnum, ec, sqnum, bitflips); - sv = add_volume(si, vol_id, pnum, vid_hdr); + sv = add_volume(ai, vol_id, pnum, vid_hdr); if (IS_ERR(sv)) return PTR_ERR(sv); - if (si->max_sqnum < sqnum) - si->max_sqnum = sqnum; + if (ai->max_sqnum < sqnum) + ai->max_sqnum = sqnum; /* * Walk the RB-tree of logical eraseblocks of volume @vol_id to look @@ -528,8 +528,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, if (err) return err; - err = add_to_list(si, aeb->pnum, aeb->ec, cmp_res & 4, - &si->erase); + err = add_to_list(ai, aeb->pnum, aeb->ec, cmp_res & 4, + &ai->erase); if (err) return err; @@ -549,21 +549,21 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, * This logical eraseblock is older than the one found * previously. */ - return add_to_list(si, pnum, ec, cmp_res & 4, - &si->erase); + return add_to_list(ai, pnum, ec, cmp_res & 4, + &ai->erase); } } /* * We've met this logical eraseblock for the first time, add it to the - * scanning information. + * attaching information. */ err = validate_vid_hdr(vid_hdr, sv, pnum); if (err) return err; - aeb = kmem_cache_alloc(si->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); if (!aeb) return -ENOMEM; @@ -586,18 +586,18 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, } /** - * ubi_scan_find_sv - find volume in the scanning information. - * @si: scanning information + * ubi_scan_find_sv - find volume in the attaching information. + * @ai: attaching information * @vol_id: the requested volume ID * * This function returns a pointer to the volume description or %NULL if there - * are no data about this volume in the scanning information. + * are no data about this volume in the attaching information. */ -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *ai, int vol_id) { struct ubi_ainf_volume *sv; - struct rb_node *p = si->volumes.rb_node; + struct rb_node *p = ai->volumes.rb_node; while (p) { sv = rb_entry(p, struct ubi_ainf_volume, rb); @@ -615,8 +615,8 @@ struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, } /** - * ubi_scan_find_aeb - find LEB in the volume scanning information. - * @sv: a pointer to the volume scanning information + * ubi_scan_find_aeb - find LEB in the volume attaching information. + * @sv: a pointer to the volume attaching information * @lnum: the requested logical eraseblock * * This function returns a pointer to the scanning logical eraseblock or %NULL @@ -644,32 +644,32 @@ struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, } /** - * ubi_scan_rm_volume - delete scanning information about a volume. - * @si: scanning information - * @sv: the volume scanning information to delete + * ubi_scan_rm_volume - delete attaching information about a volume. + * @ai: attaching information + * @sv: the volume attaching information to delete */ -void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) +void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) { struct rb_node *rb; struct ubi_ainf_peb *aeb; - dbg_bld("remove scanning information about volume %d", sv->vol_id); + dbg_bld("remove attaching information about volume %d", sv->vol_id); while ((rb = rb_first(&sv->root))) { aeb = rb_entry(rb, struct ubi_ainf_peb, u.rb); rb_erase(&aeb->u.rb, &sv->root); - list_add_tail(&aeb->u.list, &si->erase); + list_add_tail(&aeb->u.list, &ai->erase); } - rb_erase(&sv->rb, &si->volumes); + rb_erase(&sv->rb, &ai->volumes); kfree(sv); - si->vols_found -= 1; + ai->vols_found -= 1; } /** * ubi_scan_erase_peb - erase a physical eraseblock. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * @pnum: physical eraseblock number to erase; * @ec: erase counter value to write (%UBI_SCAN_UNKNOWN_EC if it is unknown) * @@ -679,7 +679,7 @@ void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *si, +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *ai, int pnum, int ec) { int err; @@ -714,7 +714,7 @@ out_free: /** * ubi_scan_get_free_peb - get a free physical eraseblock. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This function returns a free physical eraseblock. It is supposed to be * called on the UBI initialization stages when the wear-leveling sub-system is @@ -726,13 +726,13 @@ out_free: * success and an error code in case of failure. */ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_attach_info *si) + struct ubi_attach_info *ai) { int err = 0; struct ubi_ainf_peb *aeb, *tmp_aeb; - if (!list_empty(&si->free)) { - aeb = list_entry(si->free.next, struct ubi_ainf_peb, u.list); + if (!list_empty(&ai->free)) { + aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list); list_del(&aeb->u.list); dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec); return aeb; @@ -744,11 +744,11 @@ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, * so forth. We don't want to take care about bad eraseblocks here - * they'll be handled later. */ - list_for_each_entry_safe(aeb, tmp_aeb, &si->erase, u.list) { + list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { if (aeb->ec == UBI_SCAN_UNKNOWN_EC) - aeb->ec = si->mean_ec; + aeb->ec = ai->mean_ec; - err = ubi_scan_erase_peb(ubi, si, aeb->pnum, aeb->ec+1); + err = ubi_scan_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); if (err) continue; @@ -823,15 +823,15 @@ out_unlock: } /** - * process_eb - read, check UBI headers, and add them to scanning information. + * process_eb - read, check UBI headers, and add them to attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * @pnum: the physical eraseblock number * * This function returns a zero if the physical eraseblock was successfully * handled and a negative error code in case of failure. */ -static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, +static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum) { long long uninitialized_var(ec); @@ -849,7 +849,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, * initialize this, but MTD does not provide enough * information. */ - si->bad_peb_count += 1; + ai->bad_peb_count += 1; return 0; } @@ -863,13 +863,13 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, bitflips = 1; break; case UBI_IO_FF: - si->empty_peb_count += 1; - return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 0, - &si->erase); + ai->empty_peb_count += 1; + return add_to_list(ai, pnum, UBI_SCAN_UNKNOWN_EC, 0, + &ai->erase); case UBI_IO_FF_BITFLIPS: - si->empty_peb_count += 1; - return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, 1, - &si->erase); + ai->empty_peb_count += 1; + return add_to_list(ai, pnum, UBI_SCAN_UNKNOWN_EC, 1, + &ai->erase); case UBI_IO_BAD_HDR_EBADMSG: case UBI_IO_BAD_HDR: /* @@ -953,7 +953,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, * PEB, bit it is not marked as bad yet. This may also * be a result of power cut during erasure. */ - si->maybe_bad_peb_count += 1; + ai->maybe_bad_peb_count += 1; case UBI_IO_BAD_HDR: if (ec_err) /* @@ -980,23 +980,23 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, return err; else if (!err) /* This corruption is caused by a power cut */ - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(ai, pnum, ec, 1, &ai->erase); else /* This is an unexpected corruption */ - err = add_corrupted(si, pnum, ec); + err = add_corrupted(ai, pnum, ec); if (err) return err; goto adjust_mean_ec; case UBI_IO_FF_BITFLIPS: - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(ai, pnum, ec, 1, &ai->erase); if (err) return err; goto adjust_mean_ec; case UBI_IO_FF: if (ec_err) - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(ai, pnum, ec, 1, &ai->erase); else - err = add_to_list(si, pnum, ec, 0, &si->free); + err = add_to_list(ai, pnum, ec, 0, &ai->free); if (err) return err; goto adjust_mean_ec; @@ -1015,7 +1015,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, case UBI_COMPAT_DELETE: ubi_msg("\"delete\" compatible internal volume %d:%d" " found, will remove it", vol_id, lnum); - err = add_to_list(si, pnum, ec, 1, &si->erase); + err = add_to_list(ai, pnum, ec, 1, &ai->erase); if (err) return err; return 0; @@ -1030,7 +1030,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, case UBI_COMPAT_PRESERVE: ubi_msg("\"preserve\" compatible internal volume %d:%d" " found", vol_id, lnum); - err = add_to_list(si, pnum, ec, 0, &si->alien); + err = add_to_list(ai, pnum, ec, 0, &ai->alien); if (err) return err; return 0; @@ -1045,18 +1045,18 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *si, if (ec_err) ubi_warn("valid VID header but corrupted EC header at PEB %d", pnum); - err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips); + err = ubi_scan_add_used(ubi, ai, pnum, ec, vidh, bitflips); if (err) return err; adjust_mean_ec: if (!ec_err) { - si->ec_sum += ec; - si->ec_count += 1; - if (ec > si->max_ec) - si->max_ec = ec; - if (ec < si->min_ec) - si->min_ec = ec; + ai->ec_sum += ec; + ai->ec_count += 1; + if (ec > ai->max_ec) + ai->max_ec = ec; + if (ec < ai->min_ec) + ai->min_ec = ec; } return 0; @@ -1065,7 +1065,7 @@ adjust_mean_ec: /** * check_what_we_have - check what PEB were found by scanning. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This is a helper function which takes a look what PEBs were found by * scanning, and decides whether the flash is empty and should be formatted and @@ -1074,12 +1074,12 @@ adjust_mean_ec: * and %-EINVAL if we should not. */ static int check_what_we_have(struct ubi_device *ubi, - struct ubi_attach_info *si) + struct ubi_attach_info *ai) { struct ubi_ainf_peb *aeb; int max_corr, peb_count; - peb_count = ubi->peb_count - si->bad_peb_count - si->alien_peb_count; + peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count; max_corr = peb_count / 20 ?: 8; /* @@ -1087,11 +1087,11 @@ static int check_what_we_have(struct ubi_device *ubi, * unclean reboots. However, many of them may indicate some problems * with the flash HW or driver. */ - if (si->corr_peb_count) { + if (ai->corr_peb_count) { ubi_err("%d PEBs are corrupted and preserved", - si->corr_peb_count); + ai->corr_peb_count); printk(KERN_ERR "Corrupted PEBs are:"); - list_for_each_entry(aeb, &si->corr, u.list) + list_for_each_entry(aeb, &ai->corr, u.list) printk(KERN_CONT " %d", aeb->pnum); printk(KERN_CONT "\n"); @@ -1099,13 +1099,13 @@ static int check_what_we_have(struct ubi_device *ubi, * If too many PEBs are corrupted, we refuse attaching, * otherwise, only print a warning. */ - if (si->corr_peb_count >= max_corr) { + if (ai->corr_peb_count >= max_corr) { ubi_err("too many corrupted PEBs, refusing"); return -EINVAL; } } - if (si->empty_peb_count + si->maybe_bad_peb_count == peb_count) { + if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) { /* * All PEBs are empty, or almost all - a couple PEBs look like * they may be bad PEBs which were not marked as bad yet. @@ -1121,8 +1121,8 @@ static int check_what_we_have(struct ubi_device *ubi, * 2. Flash contains non-UBI data and we do not want to format * it and destroy possibly important information. */ - if (si->maybe_bad_peb_count <= 2) { - si->is_empty = 1; + if (ai->maybe_bad_peb_count <= 2) { + ai->is_empty = 1; ubi_msg("empty MTD device detected"); get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); @@ -1150,28 +1150,28 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) struct rb_node *rb1, *rb2; struct ubi_ainf_volume *sv; struct ubi_ainf_peb *aeb; - struct ubi_attach_info *si; + struct ubi_attach_info *ai; - si = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); - if (!si) + ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + if (!ai) return ERR_PTR(-ENOMEM); - INIT_LIST_HEAD(&si->corr); - INIT_LIST_HEAD(&si->free); - INIT_LIST_HEAD(&si->erase); - INIT_LIST_HEAD(&si->alien); - si->volumes = RB_ROOT; + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; err = -ENOMEM; - si->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab", + ai->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab", sizeof(struct ubi_ainf_peb), 0, 0, NULL); - if (!si->scan_leb_slab) - goto out_si; + if (!ai->scan_leb_slab) + goto out_ai; ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) - goto out_si; + goto out_ai; vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) @@ -1181,7 +1181,7 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) cond_resched(); dbg_gen("process PEB %d", pnum); - err = process_eb(ubi, si, pnum); + err = process_eb(ubi, ai, pnum); if (err < 0) goto out_vidh; } @@ -1189,10 +1189,10 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) dbg_msg("scanning is finished"); /* Calculate mean erase counter */ - if (si->ec_count) - si->mean_ec = div_u64(si->ec_sum, si->ec_count); + if (ai->ec_count) + ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); - err = check_what_we_have(ubi, si); + err = check_what_we_have(ubi, ai); if (err) goto out_vidh; @@ -1200,52 +1200,52 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) * In case of unknown erase counter we use the mean erase counter * value. */ - ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) if (aeb->ec == UBI_SCAN_UNKNOWN_EC) - aeb->ec = si->mean_ec; + aeb->ec = ai->mean_ec; } - list_for_each_entry(aeb, &si->free, u.list) { + list_for_each_entry(aeb, &ai->free, u.list) { if (aeb->ec == UBI_SCAN_UNKNOWN_EC) - aeb->ec = si->mean_ec; + aeb->ec = ai->mean_ec; } - list_for_each_entry(aeb, &si->corr, u.list) + list_for_each_entry(aeb, &ai->corr, u.list) if (aeb->ec == UBI_SCAN_UNKNOWN_EC) - aeb->ec = si->mean_ec; + aeb->ec = ai->mean_ec; - list_for_each_entry(aeb, &si->erase, u.list) + list_for_each_entry(aeb, &ai->erase, u.list) if (aeb->ec == UBI_SCAN_UNKNOWN_EC) - aeb->ec = si->mean_ec; + aeb->ec = ai->mean_ec; - err = self_check_si(ubi, si); + err = self_check_ai(ubi, ai); if (err) goto out_vidh; ubi_free_vid_hdr(ubi, vidh); kfree(ech); - return si; + return ai; out_vidh: ubi_free_vid_hdr(ubi, vidh); out_ech: kfree(ech); -out_si: - ubi_scan_destroy_si(si); +out_ai: + ubi_scan_destroy_ai(ai); return ERR_PTR(err); } /** * destroy_sv - free the scanning volume information * @sv: scanning volume information - * @si: scanning information + * @ai: attaching information * * This function destroys the volume RB-tree (@sv->root) and the scanning * volume information. */ -static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) +static void destroy_sv(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) { struct ubi_ainf_peb *aeb; struct rb_node *this = sv->root.rb_node; @@ -1265,41 +1265,41 @@ static void destroy_sv(struct ubi_attach_info *si, struct ubi_ainf_volume *sv) this->rb_right = NULL; } - kmem_cache_free(si->scan_leb_slab, aeb); + kmem_cache_free(ai->scan_leb_slab, aeb); } } kfree(sv); } /** - * ubi_scan_destroy_si - destroy scanning information. - * @si: scanning information + * ubi_scan_destroy_ai - destroy attaching information. + * @ai: attaching information */ -void ubi_scan_destroy_si(struct ubi_attach_info *si) +void ubi_scan_destroy_ai(struct ubi_attach_info *ai) { struct ubi_ainf_peb *aeb, *aeb_tmp; struct ubi_ainf_volume *sv; struct rb_node *rb; - list_for_each_entry_safe(aeb, aeb_tmp, &si->alien, u.list) { + list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { list_del(&aeb->u.list); - kmem_cache_free(si->scan_leb_slab, aeb); + kmem_cache_free(ai->scan_leb_slab, aeb); } - list_for_each_entry_safe(aeb, aeb_tmp, &si->erase, u.list) { + list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { list_del(&aeb->u.list); - kmem_cache_free(si->scan_leb_slab, aeb); + kmem_cache_free(ai->scan_leb_slab, aeb); } - list_for_each_entry_safe(aeb, aeb_tmp, &si->corr, u.list) { + list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { list_del(&aeb->u.list); - kmem_cache_free(si->scan_leb_slab, aeb); + kmem_cache_free(ai->scan_leb_slab, aeb); } - list_for_each_entry_safe(aeb, aeb_tmp, &si->free, u.list) { + list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { list_del(&aeb->u.list); - kmem_cache_free(si->scan_leb_slab, aeb); + kmem_cache_free(ai->scan_leb_slab, aeb); } /* Destroy the volume RB-tree */ - rb = si->volumes.rb_node; + rb = ai->volumes.rb_node; while (rb) { if (rb->rb_left) rb = rb->rb_left; @@ -1316,25 +1316,25 @@ void ubi_scan_destroy_si(struct ubi_attach_info *si) rb->rb_right = NULL; } - destroy_sv(si, sv); + destroy_sv(ai, sv); } } - if (si->scan_leb_slab) - kmem_cache_destroy(si->scan_leb_slab); + if (ai->scan_leb_slab) + kmem_cache_destroy(ai->scan_leb_slab); - kfree(si); + kfree(ai); } /** - * self_check_si - check the scanning information. + * self_check_ai - check the attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * - * This function returns zero if the scanning information is all right, and a + * This function returns zero if the attaching information is all right, and a * negative error code if not or if an error occurred. */ -static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) +static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; @@ -1346,16 +1346,16 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) return 0; /* - * At first, check that scanning information is OK. + * At first, check that attaching information is OK. */ - ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { int leb_count = 0; cond_resched(); vols_found += 1; - if (si->is_empty) { + if (ai->is_empty) { ubi_err("bad is_empty flag"); goto bad_sv; } @@ -1373,9 +1373,9 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_sv; } - if (sv->vol_id > si->highest_vol_id) { + if (sv->vol_id > ai->highest_vol_id) { ubi_err("highest_vol_id is %d, but vol_id %d is there", - si->highest_vol_id, sv->vol_id); + ai->highest_vol_id, sv->vol_id); goto out; } @@ -1402,15 +1402,15 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) goto bad_aeb; } - if (aeb->ec < si->min_ec) { - ubi_err("bad si->min_ec (%d), %d found", - si->min_ec, aeb->ec); + if (aeb->ec < ai->min_ec) { + ubi_err("bad ai->min_ec (%d), %d found", + ai->min_ec, aeb->ec); goto bad_aeb; } - if (aeb->ec > si->max_ec) { - ubi_err("bad si->max_ec (%d), %d found", - si->max_ec, aeb->ec); + if (aeb->ec > ai->max_ec) { + ubi_err("bad ai->max_ec (%d), %d found", + ai->max_ec, aeb->ec); goto bad_aeb; } @@ -1455,14 +1455,14 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) } } - if (vols_found != si->vols_found) { - ubi_err("bad si->vols_found %d, should be %d", - si->vols_found, vols_found); + if (vols_found != ai->vols_found) { + ubi_err("bad ai->vols_found %d, should be %d", + ai->vols_found, vols_found); goto out; } - /* Check that scanning information is correct */ - ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + /* Check that attaching information is correct */ + ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { last_aeb = NULL; ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { int vol_type; @@ -1548,20 +1548,20 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) buf[pnum] = 1; } - ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) + ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) buf[aeb->pnum] = 1; - list_for_each_entry(aeb, &si->free, u.list) + list_for_each_entry(aeb, &ai->free, u.list) buf[aeb->pnum] = 1; - list_for_each_entry(aeb, &si->corr, u.list) + list_for_each_entry(aeb, &ai->corr, u.list) buf[aeb->pnum] = 1; - list_for_each_entry(aeb, &si->erase, u.list) + list_for_each_entry(aeb, &ai->erase, u.list) buf[aeb->pnum] = 1; - list_for_each_entry(aeb, &si->alien, u.list) + list_for_each_entry(aeb, &ai->alien, u.list) buf[aeb->pnum] = 1; err = 0; @@ -1577,18 +1577,18 @@ static int self_check_si(struct ubi_device *ubi, struct ubi_attach_info *si) return 0; bad_aeb: - ubi_err("bad scanning information about LEB %d", aeb->lnum); + ubi_err("bad attaching information about LEB %d", aeb->lnum); ubi_dump_aeb(aeb, 0); ubi_dump_sv(sv); goto out; bad_sv: - ubi_err("bad scanning information about volume %d", sv->vol_id); + ubi_err("bad attaching information about volume %d", sv->vol_id); ubi_dump_sv(sv); goto out; bad_vid_hdr: - ubi_err("bad scanning information about volume %d", sv->vol_id); + ubi_err("bad attaching information about volume %d", sv->vol_id); ubi_dump_sv(sv); ubi_dump_vid_hdr(vidh); diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 7e20a85b8c31..0f0725e18b7f 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -145,7 +145,7 @@ struct ubi_vid_hdr; /* * ubi_scan_move_to_list - move a PEB from the volume tree to a list. * - * @sv: volume scanning information + * @sv: volume attaching information * @aeb: scanning eraseblock information * @list: the list to move to */ @@ -157,19 +157,19 @@ static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *sv, list_add_tail(&aeb->u.list, list); } -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *si, +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *si, +struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *ai, int vol_id); struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, int lnum); -void ubi_scan_rm_volume(struct ubi_attach_info *si, struct ubi_ainf_volume *sv); +void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_attach_info *si); -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *si, + struct ubi_attach_info *ai); +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *ai, int pnum, int ec); struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); -void ubi_scan_destroy_si(struct ubi_attach_info *si); +void ubi_scan_destroy_ai(struct ubi_attach_info *ai); #endif /* !__UBI_SCAN_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 0f206517d811..faaf72933bcb 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -489,7 +489,7 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, struct ubi_vtbl_record *vtbl_rec); int ubi_vtbl_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list); -int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si); +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai); /* vmt.c */ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req); @@ -529,14 +529,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, const void *buf, int len); int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr); -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si); +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai); /* wl.c */ int ubi_wl_get_peb(struct ubi_device *ubi); int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); int ubi_wl_flush(struct ubi_device *ubi); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si); +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai); void ubi_wl_close(struct ubi_device *ubi); int ubi_thread(void *u); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index f6f8cc5b06ad..9632163c05fb 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -291,14 +291,14 @@ bad: /** * create_vtbl - create a copy of volume table. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * @copy: number of the volume table copy * @vtbl: contents of the volume table * * This function returns zero in case of success and a negative error code in * case of failure. */ -static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *si, +static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai, int copy, void *vtbl) { int err, tries = 0; @@ -312,7 +312,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *si, return -ENOMEM; retry: - new_aeb = ubi_scan_get_free_peb(ubi, si); + new_aeb = ubi_scan_get_free_peb(ubi, ai); if (IS_ERR(new_aeb)) { err = PTR_ERR(new_aeb); goto out_free; @@ -324,7 +324,7 @@ retry: vid_hdr->data_size = vid_hdr->used_ebs = vid_hdr->data_pad = cpu_to_be32(0); vid_hdr->lnum = cpu_to_be32(copy); - vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum); + vid_hdr->sqnum = cpu_to_be64(++ai->max_sqnum); /* The EC header is already there, write the VID header */ err = ubi_io_write_vid_hdr(ubi, new_aeb->pnum, vid_hdr); @@ -337,10 +337,10 @@ retry: goto write_error; /* - * And add it to the scanning information. Don't delete the old version + * And add it to the attaching information. Don't delete the old version * of this LEB as it will be deleted and freed in 'ubi_scan_add_used()'. */ - err = ubi_scan_add_used(ubi, si, new_aeb->pnum, new_aeb->ec, + err = ubi_scan_add_used(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); kfree(new_aeb); ubi_free_vid_hdr(ubi, vid_hdr); @@ -352,7 +352,7 @@ write_error: * Probably this physical eraseblock went bad, try to pick * another one. */ - list_add(&new_aeb->u.list, &si->erase); + list_add(&new_aeb->u.list, &ai->erase); goto retry; } kfree(new_aeb); @@ -365,15 +365,15 @@ out_free: /** * process_lvol - process the layout volume. * @ubi: UBI device description object - * @si: scanning information - * @sv: layout volume scanning information + * @ai: attaching information + * @sv: layout volume attaching information * * This function is responsible for reading the layout volume, ensuring it is * not corrupted, and recovering from corruptions if needed. Returns volume * table in case of success and a negative error code in case of failure. */ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, - struct ubi_attach_info *si, + struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) { int err; @@ -449,7 +449,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, ubi->vtbl_size); if (leb_corrupted[1]) { ubi_warn("volume table copy #2 is corrupted"); - err = create_vtbl(ubi, si, 1, leb[0]); + err = create_vtbl(ubi, ai, 1, leb[0]); if (err) goto out_free; ubi_msg("volume table was restored"); @@ -472,7 +472,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, } ubi_warn("volume table copy #1 is corrupted"); - err = create_vtbl(ubi, si, 0, leb[1]); + err = create_vtbl(ubi, ai, 0, leb[1]); if (err) goto out_free; ubi_msg("volume table was restored"); @@ -490,13 +490,13 @@ out_free: /** * create_empty_lvol - create empty layout volume. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This function returns volume table contents in case of success and a * negative error code in case of failure. */ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, - struct ubi_attach_info *si) + struct ubi_attach_info *ai) { int i; struct ubi_vtbl_record *vtbl; @@ -511,7 +511,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { int err; - err = create_vtbl(ubi, si, i, vtbl); + err = create_vtbl(ubi, ai, i, vtbl); if (err) { vfree(vtbl); return ERR_PTR(err); @@ -524,7 +524,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, /** * init_volumes - initialize volume information for existing volumes. * @ubi: UBI device description object - * @si: scanning information + * @ai: scanning information * @vtbl: volume table * * This function allocates volume description objects for existing volumes. @@ -532,7 +532,7 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, * failure. */ static int init_volumes(struct ubi_device *ubi, - const struct ubi_attach_info *si, + const struct ubi_attach_info *ai, const struct ubi_vtbl_record *vtbl) { int i, reserved_pebs = 0; @@ -592,7 +592,7 @@ static int init_volumes(struct ubi_device *ubi, } /* Static volumes only */ - sv = ubi_scan_find_sv(si, i); + sv = ubi_scan_find_sv(ai, i); if (!sv) { /* * No eraseblocks belonging to this volume found. We @@ -661,11 +661,11 @@ static int init_volumes(struct ubi_device *ubi, } /** - * check_sv - check volume scanning information. + * check_sv - check volume attaching information. * @vol: UBI volume description object - * @sv: volume scanning information + * @sv: volume attaching information * - * This function returns zero if the volume scanning information is consistent + * This function returns zero if the volume attaching information is consistent * to the data read from the volume tabla, and %-EINVAL if not. */ static int check_sv(const struct ubi_volume *vol, @@ -696,50 +696,50 @@ static int check_sv(const struct ubi_volume *vol, return 0; bad: - ubi_err("bad scanning information, error %d", err); + ubi_err("bad attaching information, error %d", err); ubi_dump_sv(sv); ubi_dump_vol_info(vol); return -EINVAL; } /** - * check_scanning_info - check that scanning information. + * check_scanning_info - check that attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * Even though we protect on-flash data by CRC checksums, we still don't trust - * the media. This function ensures that scanning information is consistent to + * the media. This function ensures that attaching information is consistent to * the information read from the volume table. Returns zero if the scanning * information is OK and %-EINVAL if it is not. */ static int check_scanning_info(const struct ubi_device *ubi, - struct ubi_attach_info *si) + struct ubi_attach_info *ai) { int err, i; struct ubi_ainf_volume *sv; struct ubi_volume *vol; - if (si->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { + if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { ubi_err("scanning found %d volumes, maximum is %d + %d", - si->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); + ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); return -EINVAL; } - if (si->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && - si->highest_vol_id < UBI_INTERNAL_VOL_START) { + if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && + ai->highest_vol_id < UBI_INTERNAL_VOL_START) { ubi_err("too large volume ID %d found by scanning", - si->highest_vol_id); + ai->highest_vol_id); return -EINVAL; } for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { cond_resched(); - sv = ubi_scan_find_sv(si, i); + sv = ubi_scan_find_sv(ai, i); vol = ubi->volumes[i]; if (!vol) { if (sv) - ubi_scan_rm_volume(si, sv); + ubi_scan_rm_volume(ai, sv); continue; } @@ -757,7 +757,7 @@ static int check_scanning_info(const struct ubi_device *ubi, * these eraseblocks. */ ubi_msg("finish volume %d removal", sv->vol_id); - ubi_scan_rm_volume(si, sv); + ubi_scan_rm_volume(ai, sv); } else if (sv) { err = check_sv(vol, sv); if (err) @@ -771,13 +771,13 @@ static int check_scanning_info(const struct ubi_device *ubi, /** * ubi_read_volume_table - read the volume table. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This function reads volume table, checks it, recover from errors if needed, * or creates it if needed. Returns zero in case of success and a negative * error code in case of failure. */ -int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) { int i, err; struct ubi_ainf_volume *sv; @@ -795,7 +795,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE; ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size); - sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID); + sv = ubi_scan_find_sv(ai, UBI_LAYOUT_VOLUME_ID); if (!sv) { /* * No logical eraseblocks belonging to the layout volume were @@ -805,8 +805,8 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) * But if flash is not empty this must be a corruption or the * MTD device just contains garbage. */ - if (si->is_empty) { - ubi->vtbl = create_empty_lvol(ubi, si); + if (ai->is_empty) { + ubi->vtbl = create_empty_lvol(ubi, ai); if (IS_ERR(ubi->vtbl)) return PTR_ERR(ubi->vtbl); } else { @@ -821,7 +821,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) return -EINVAL; } - ubi->vtbl = process_lvol(ubi, si, sv); + ubi->vtbl = process_lvol(ubi, ai, sv); if (IS_ERR(ubi->vtbl)) return PTR_ERR(ubi->vtbl); } @@ -832,15 +832,15 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *si) * The layout volume is OK, initialize the corresponding in-RAM data * structures. */ - err = init_volumes(ubi, si, ubi->vtbl); + err = init_volumes(ubi, ai, ubi->vtbl); if (err) goto out_free; /* - * Make sure that the scanning information is consistent to the + * Make sure that the attaching information is consistent to the * information stored in the volume table. */ - err = check_scanning_info(ubi, si); + err = check_scanning_info(ubi, ai); if (err) goto out_free; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index fb870f4fc924..992240dae1b1 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1373,14 +1373,14 @@ static void cancel_pending(struct ubi_device *ubi) } /** - * ubi_wl_init_scan - initialize the WL sub-system using scanning information. + * ubi_wl_init_scan - initialize the WL sub-system using attaching information. * @ubi: UBI device description object - * @si: scanning information + * @ai: attaching information * * This function returns zero in case of success, and a negative error code in * case of failure. */ -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) { int err, i; struct rb_node *rb1, *rb2; @@ -1392,7 +1392,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) spin_lock_init(&ubi->wl_lock); mutex_init(&ubi->move_mutex); init_rwsem(&ubi->work_sem); - ubi->max_ec = si->max_ec; + ubi->max_ec = ai->max_ec; INIT_LIST_HEAD(&ubi->works); sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); @@ -1406,7 +1406,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) INIT_LIST_HEAD(&ubi->pq[i]); ubi->pq_head = 0; - list_for_each_entry_safe(aeb, tmp, &si->erase, u.list) { + list_for_each_entry_safe(aeb, tmp, &ai->erase, u.list) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); @@ -1422,7 +1422,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) } } - list_for_each_entry(aeb, &si->free, u.list) { + list_for_each_entry(aeb, &ai->free, u.list) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); @@ -1436,7 +1436,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *si) ubi->lookuptbl[e->pnum] = e; } - ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { cond_resched(); -- cgit v1.2.3 From a9abf45f4cbd95f113874ea8c427e267c66ab92e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 14:38:34 +0300 Subject: UBI: rename sv to av After re-naming the 'struct ubi_scan_volume' we should adjust all variables named 'sv' to something else, because 'sv' stands for "scanning volume". Let's rename it to 'av' which stands for "attaching volume" which is a bit more consistent and has the same length, which makes re-naming easy. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 22 ++--- drivers/mtd/ubi/debug.h | 2 +- drivers/mtd/ubi/eba.c | 10 +- drivers/mtd/ubi/scan.c | 240 ++++++++++++++++++++++++------------------------ drivers/mtd/ubi/scan.h | 12 +-- drivers/mtd/ubi/vtbl.c | 72 +++++++-------- drivers/mtd/ubi/wl.c | 6 +- 7 files changed, 182 insertions(+), 182 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index f46d276ecd7c..d8411f814ce3 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -171,20 +171,20 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) } /** - * ubi_dump_sv - dump a &struct ubi_ainf_volume object. - * @sv: the object to dump + * ubi_dump_av - dump a &struct ubi_ainf_volume object. + * @av: the object to dump */ -void ubi_dump_sv(const struct ubi_ainf_volume *sv) +void ubi_dump_av(const struct ubi_ainf_volume *av) { printk(KERN_DEBUG "Volume attaching information dump:\n"); - printk(KERN_DEBUG "\tvol_id %d\n", sv->vol_id); - printk(KERN_DEBUG "\thighest_lnum %d\n", sv->highest_lnum); - printk(KERN_DEBUG "\tleb_count %d\n", sv->leb_count); - printk(KERN_DEBUG "\tcompat %d\n", sv->compat); - printk(KERN_DEBUG "\tvol_type %d\n", sv->vol_type); - printk(KERN_DEBUG "\tused_ebs %d\n", sv->used_ebs); - printk(KERN_DEBUG "\tlast_data_size %d\n", sv->last_data_size); - printk(KERN_DEBUG "\tdata_pad %d\n", sv->data_pad); + printk(KERN_DEBUG "\tvol_id %d\n", av->vol_id); + printk(KERN_DEBUG "\thighest_lnum %d\n", av->highest_lnum); + printk(KERN_DEBUG "\tleb_count %d\n", av->leb_count); + printk(KERN_DEBUG "\tcompat %d\n", av->compat); + printk(KERN_DEBUG "\tvol_type %d\n", av->vol_type); + printk(KERN_DEBUG "\tused_ebs %d\n", av->used_ebs); + printk(KERN_DEBUG "\tlast_data_size %d\n", av->last_data_size); + printk(KERN_DEBUG "\tdata_pad %d\n", av->data_pad); } /** diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index a0911c0c1064..d5d2645b51a7 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -59,7 +59,7 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); void ubi_dump_vol_info(const struct ubi_volume *vol); void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); -void ubi_dump_sv(const struct ubi_ainf_volume *sv); +void ubi_dump_av(const struct ubi_ainf_volume *av); void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 7e91a6e57c44..b49bff083b97 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1215,7 +1215,7 @@ static void print_rsvd_warning(struct ubi_device *ubi, int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) { int i, j, err, num_volumes; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_volume *vol; struct ubi_ainf_peb *aeb; struct rb_node *rb; @@ -1246,17 +1246,17 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) for (j = 0; j < vol->reserved_pebs; j++) vol->eba_tbl[j] = UBI_LEB_UNMAPPED; - sv = ubi_scan_find_sv(ai, idx2vol_id(ubi, i)); - if (!sv) + av = ubi_scan_find_av(ai, idx2vol_id(ubi, i)); + if (!av) continue; - ubi_rb_for_each_entry(rb, aeb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) { if (aeb->lnum >= vol->reserved_pebs) /* * This may happen in case of an unclean reboot * during re-size. */ - ubi_scan_move_to_list(sv, aeb, &ai->erase); + ubi_scan_move_to_list(av, aeb, &ai->erase); vol->eba_tbl[aeb->lnum] = aeb->pnum; } } diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index a36319b07539..a7ac06809f16 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -168,7 +168,7 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) /** * validate_vid_hdr - check volume identifier header. * @vid_hdr: the volume identifier header to check - * @sv: information about the volume this logical eraseblock belongs to + * @av: information about the volume this logical eraseblock belongs to * @pnum: physical eraseblock number the VID header came from * * This function checks that data stored in @vid_hdr is consistent. Returns @@ -180,15 +180,15 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) * headers of the same volume. */ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, - const struct ubi_ainf_volume *sv, int pnum) + const struct ubi_ainf_volume *av, int pnum) { int vol_type = vid_hdr->vol_type; int vol_id = be32_to_cpu(vid_hdr->vol_id); int used_ebs = be32_to_cpu(vid_hdr->used_ebs); int data_pad = be32_to_cpu(vid_hdr->data_pad); - if (sv->leb_count != 0) { - int sv_vol_type; + if (av->leb_count != 0) { + int av_vol_type; /* * This is not the first logical eraseblock belonging to this @@ -196,27 +196,27 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, * to the data in previous logical eraseblock headers. */ - if (vol_id != sv->vol_id) { + if (vol_id != av->vol_id) { ubi_err("inconsistent vol_id"); goto bad; } - if (sv->vol_type == UBI_STATIC_VOLUME) - sv_vol_type = UBI_VID_STATIC; + if (av->vol_type == UBI_STATIC_VOLUME) + av_vol_type = UBI_VID_STATIC; else - sv_vol_type = UBI_VID_DYNAMIC; + av_vol_type = UBI_VID_DYNAMIC; - if (vol_type != sv_vol_type) { + if (vol_type != av_vol_type) { ubi_err("inconsistent vol_type"); goto bad; } - if (used_ebs != sv->used_ebs) { + if (used_ebs != av->used_ebs) { ubi_err("inconsistent used_ebs"); goto bad; } - if (data_pad != sv->data_pad) { + if (data_pad != av->data_pad) { ubi_err("inconsistent data_pad"); goto bad; } @@ -227,7 +227,7 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, bad: ubi_err("inconsistent VID header at PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); - ubi_dump_sv(sv); + ubi_dump_av(av); return -EINVAL; } @@ -248,7 +248,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, int vol_id, int pnum, const struct ubi_vid_hdr *vid_hdr) { - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); @@ -256,38 +256,38 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, /* Walk the volume RB-tree to look if this volume is already present */ while (*p) { parent = *p; - sv = rb_entry(parent, struct ubi_ainf_volume, rb); + av = rb_entry(parent, struct ubi_ainf_volume, rb); - if (vol_id == sv->vol_id) - return sv; + if (vol_id == av->vol_id) + return av; - if (vol_id > sv->vol_id) + if (vol_id > av->vol_id) p = &(*p)->rb_left; else p = &(*p)->rb_right; } /* The volume is absent - add it */ - sv = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); - if (!sv) + av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); + if (!av) return ERR_PTR(-ENOMEM); - sv->highest_lnum = sv->leb_count = 0; - sv->vol_id = vol_id; - sv->root = RB_ROOT; - sv->used_ebs = be32_to_cpu(vid_hdr->used_ebs); - sv->data_pad = be32_to_cpu(vid_hdr->data_pad); - sv->compat = vid_hdr->compat; - sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME + av->highest_lnum = av->leb_count = 0; + av->vol_id = vol_id; + av->root = RB_ROOT; + av->used_ebs = be32_to_cpu(vid_hdr->used_ebs); + av->data_pad = be32_to_cpu(vid_hdr->data_pad); + av->compat = vid_hdr->compat; + av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; if (vol_id > ai->highest_vol_id) ai->highest_vol_id = vol_id; - rb_link_node(&sv->rb, parent, p); - rb_insert_color(&sv->rb, &ai->volumes); + rb_link_node(&av->rb, parent, p); + rb_insert_color(&av->rb, &ai->volumes); ai->vols_found += 1; dbg_bld("added volume %d", vol_id); - return sv; + return av; } /** @@ -446,7 +446,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, { int err, vol_id, lnum; unsigned long long sqnum; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb; struct rb_node **p, *parent = NULL; @@ -457,9 +457,9 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", pnum, vol_id, lnum, ec, sqnum, bitflips); - sv = add_volume(ai, vol_id, pnum, vid_hdr); - if (IS_ERR(sv)) - return PTR_ERR(sv); + av = add_volume(ai, vol_id, pnum, vid_hdr); + if (IS_ERR(av)) + return PTR_ERR(av); if (ai->max_sqnum < sqnum) ai->max_sqnum = sqnum; @@ -468,7 +468,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, * Walk the RB-tree of logical eraseblocks of volume @vol_id to look * if this is the first instance of this logical eraseblock or not. */ - p = &sv->root.rb_node; + p = &av->root.rb_node; while (*p) { int cmp_res; @@ -524,7 +524,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, * This logical eraseblock is newer than the one * found earlier. */ - err = validate_vid_hdr(vid_hdr, sv, pnum); + err = validate_vid_hdr(vid_hdr, av, pnum); if (err) return err; @@ -539,8 +539,8 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, aeb->copy_flag = vid_hdr->copy_flag; aeb->sqnum = sqnum; - if (sv->highest_lnum == lnum) - sv->last_data_size = + if (av->highest_lnum == lnum) + av->last_data_size = be32_to_cpu(vid_hdr->data_size); return 0; @@ -559,7 +559,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, * attaching information. */ - err = validate_vid_hdr(vid_hdr, sv, pnum); + err = validate_vid_hdr(vid_hdr, av, pnum); if (err) return err; @@ -574,38 +574,38 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, aeb->copy_flag = vid_hdr->copy_flag; aeb->sqnum = sqnum; - if (sv->highest_lnum <= lnum) { - sv->highest_lnum = lnum; - sv->last_data_size = be32_to_cpu(vid_hdr->data_size); + if (av->highest_lnum <= lnum) { + av->highest_lnum = lnum; + av->last_data_size = be32_to_cpu(vid_hdr->data_size); } - sv->leb_count += 1; + av->leb_count += 1; rb_link_node(&aeb->u.rb, parent, p); - rb_insert_color(&aeb->u.rb, &sv->root); + rb_insert_color(&aeb->u.rb, &av->root); return 0; } /** - * ubi_scan_find_sv - find volume in the attaching information. + * ubi_scan_find_av - find volume in the attaching information. * @ai: attaching information * @vol_id: the requested volume ID * * This function returns a pointer to the volume description or %NULL if there * are no data about this volume in the attaching information. */ -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *ai, +struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, int vol_id) { - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct rb_node *p = ai->volumes.rb_node; while (p) { - sv = rb_entry(p, struct ubi_ainf_volume, rb); + av = rb_entry(p, struct ubi_ainf_volume, rb); - if (vol_id == sv->vol_id) - return sv; + if (vol_id == av->vol_id) + return av; - if (vol_id > sv->vol_id) + if (vol_id > av->vol_id) p = p->rb_left; else p = p->rb_right; @@ -616,17 +616,17 @@ struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *ai, /** * ubi_scan_find_aeb - find LEB in the volume attaching information. - * @sv: a pointer to the volume attaching information + * @av: a pointer to the volume attaching information * @lnum: the requested logical eraseblock * * This function returns a pointer to the scanning logical eraseblock or %NULL * if there are no data about it in the scanning volume information. */ -struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *av, int lnum) { struct ubi_ainf_peb *aeb; - struct rb_node *p = sv->root.rb_node; + struct rb_node *p = av->root.rb_node; while (p) { aeb = rb_entry(p, struct ubi_ainf_peb, u.rb); @@ -646,23 +646,23 @@ struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, /** * ubi_scan_rm_volume - delete attaching information about a volume. * @ai: attaching information - * @sv: the volume attaching information to delete + * @av: the volume attaching information to delete */ -void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) +void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) { struct rb_node *rb; struct ubi_ainf_peb *aeb; - dbg_bld("remove attaching information about volume %d", sv->vol_id); + dbg_bld("remove attaching information about volume %d", av->vol_id); - while ((rb = rb_first(&sv->root))) { + while ((rb = rb_first(&av->root))) { aeb = rb_entry(rb, struct ubi_ainf_peb, u.rb); - rb_erase(&aeb->u.rb, &sv->root); + rb_erase(&aeb->u.rb, &av->root); list_add_tail(&aeb->u.list, &ai->erase); } - rb_erase(&sv->rb, &ai->volumes); - kfree(sv); + rb_erase(&av->rb, &ai->volumes); + kfree(av); ai->vols_found -= 1; } @@ -1148,7 +1148,7 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) { int err, pnum; struct rb_node *rb1, *rb2; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb; struct ubi_attach_info *ai; @@ -1200,8 +1200,8 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) * In case of unknown erase counter we use the mean erase counter * value. */ - ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { - ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) if (aeb->ec == UBI_SCAN_UNKNOWN_EC) aeb->ec = ai->mean_ec; } @@ -1238,17 +1238,17 @@ out_ai: } /** - * destroy_sv - free the scanning volume information - * @sv: scanning volume information + * destroy_av - free the scanning volume information + * @av: scanning volume information * @ai: attaching information * - * This function destroys the volume RB-tree (@sv->root) and the scanning + * This function destroys the volume RB-tree (@av->root) and the scanning * volume information. */ -static void destroy_sv(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) +static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) { struct ubi_ainf_peb *aeb; - struct rb_node *this = sv->root.rb_node; + struct rb_node *this = av->root.rb_node; while (this) { if (this->rb_left) @@ -1268,7 +1268,7 @@ static void destroy_sv(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) kmem_cache_free(ai->scan_leb_slab, aeb); } } - kfree(sv); + kfree(av); } /** @@ -1278,7 +1278,7 @@ static void destroy_sv(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv) void ubi_scan_destroy_ai(struct ubi_attach_info *ai) { struct ubi_ainf_peb *aeb, *aeb_tmp; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct rb_node *rb; list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { @@ -1306,17 +1306,17 @@ void ubi_scan_destroy_ai(struct ubi_attach_info *ai) else if (rb->rb_right) rb = rb->rb_right; else { - sv = rb_entry(rb, struct ubi_ainf_volume, rb); + av = rb_entry(rb, struct ubi_ainf_volume, rb); rb = rb_parent(rb); if (rb) { - if (rb->rb_left == &sv->rb) + if (rb->rb_left == &av->rb) rb->rb_left = NULL; else rb->rb_right = NULL; } - destroy_sv(ai, sv); + destroy_av(ai, av); } } @@ -1338,7 +1338,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) { int pnum, err, vols_found = 0; struct rb_node *rb1, *rb2; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb, *last_aeb; uint8_t *buf; @@ -1348,7 +1348,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) /* * At first, check that attaching information is OK. */ - ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { int leb_count = 0; cond_resched(); @@ -1357,41 +1357,41 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) if (ai->is_empty) { ubi_err("bad is_empty flag"); - goto bad_sv; + goto bad_av; } - if (sv->vol_id < 0 || sv->highest_lnum < 0 || - sv->leb_count < 0 || sv->vol_type < 0 || sv->used_ebs < 0 || - sv->data_pad < 0 || sv->last_data_size < 0) { + if (av->vol_id < 0 || av->highest_lnum < 0 || + av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || + av->data_pad < 0 || av->last_data_size < 0) { ubi_err("negative values"); - goto bad_sv; + goto bad_av; } - if (sv->vol_id >= UBI_MAX_VOLUMES && - sv->vol_id < UBI_INTERNAL_VOL_START) { + if (av->vol_id >= UBI_MAX_VOLUMES && + av->vol_id < UBI_INTERNAL_VOL_START) { ubi_err("bad vol_id"); - goto bad_sv; + goto bad_av; } - if (sv->vol_id > ai->highest_vol_id) { + if (av->vol_id > ai->highest_vol_id) { ubi_err("highest_vol_id is %d, but vol_id %d is there", - ai->highest_vol_id, sv->vol_id); + ai->highest_vol_id, av->vol_id); goto out; } - if (sv->vol_type != UBI_DYNAMIC_VOLUME && - sv->vol_type != UBI_STATIC_VOLUME) { + if (av->vol_type != UBI_DYNAMIC_VOLUME && + av->vol_type != UBI_STATIC_VOLUME) { ubi_err("bad vol_type"); - goto bad_sv; + goto bad_av; } - if (sv->data_pad > ubi->leb_size / 2) { + if (av->data_pad > ubi->leb_size / 2) { ubi_err("bad data_pad"); - goto bad_sv; + goto bad_av; } last_aeb = NULL; - ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { cond_resched(); last_aeb = aeb; @@ -1420,28 +1420,28 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) goto bad_aeb; } - if (sv->vol_type == UBI_STATIC_VOLUME) { - if (aeb->lnum >= sv->used_ebs) { + if (av->vol_type == UBI_STATIC_VOLUME) { + if (aeb->lnum >= av->used_ebs) { ubi_err("bad lnum or used_ebs"); goto bad_aeb; } } else { - if (sv->used_ebs != 0) { + if (av->used_ebs != 0) { ubi_err("non-zero used_ebs"); goto bad_aeb; } } - if (aeb->lnum > sv->highest_lnum) { + if (aeb->lnum > av->highest_lnum) { ubi_err("incorrect highest_lnum or lnum"); goto bad_aeb; } } - if (sv->leb_count != leb_count) { + if (av->leb_count != leb_count) { ubi_err("bad leb_count, %d objects in the tree", leb_count); - goto bad_sv; + goto bad_av; } if (!last_aeb) @@ -1449,7 +1449,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) aeb = last_aeb; - if (aeb->lnum != sv->highest_lnum) { + if (aeb->lnum != av->highest_lnum) { ubi_err("bad highest_lnum"); goto bad_aeb; } @@ -1462,9 +1462,9 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) } /* Check that attaching information is correct */ - ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { last_aeb = NULL; - ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { int vol_type; cond_resched(); @@ -1481,7 +1481,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; - if (sv->vol_type != vol_type) { + if (av->vol_type != vol_type) { ubi_err("bad vol_type"); goto bad_vid_hdr; } @@ -1491,12 +1491,12 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) goto bad_vid_hdr; } - if (sv->vol_id != be32_to_cpu(vidh->vol_id)) { - ubi_err("bad vol_id %d", sv->vol_id); + if (av->vol_id != be32_to_cpu(vidh->vol_id)) { + ubi_err("bad vol_id %d", av->vol_id); goto bad_vid_hdr; } - if (sv->compat != vidh->compat) { + if (av->compat != vidh->compat) { ubi_err("bad compat %d", vidh->compat); goto bad_vid_hdr; } @@ -1506,13 +1506,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) goto bad_vid_hdr; } - if (sv->used_ebs != be32_to_cpu(vidh->used_ebs)) { - ubi_err("bad used_ebs %d", sv->used_ebs); + if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { + ubi_err("bad used_ebs %d", av->used_ebs); goto bad_vid_hdr; } - if (sv->data_pad != be32_to_cpu(vidh->data_pad)) { - ubi_err("bad data_pad %d", sv->data_pad); + if (av->data_pad != be32_to_cpu(vidh->data_pad)) { + ubi_err("bad data_pad %d", av->data_pad); goto bad_vid_hdr; } } @@ -1520,13 +1520,13 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) if (!last_aeb) continue; - if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad highest_lnum %d", sv->highest_lnum); + if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad highest_lnum %d", av->highest_lnum); goto bad_vid_hdr; } - if (sv->last_data_size != be32_to_cpu(vidh->data_size)) { - ubi_err("bad last_data_size %d", sv->last_data_size); + if (av->last_data_size != be32_to_cpu(vidh->data_size)) { + ubi_err("bad last_data_size %d", av->last_data_size); goto bad_vid_hdr; } } @@ -1548,8 +1548,8 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) buf[pnum] = 1; } - ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) - ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) buf[aeb->pnum] = 1; list_for_each_entry(aeb, &ai->free, u.list) @@ -1579,17 +1579,17 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) bad_aeb: ubi_err("bad attaching information about LEB %d", aeb->lnum); ubi_dump_aeb(aeb, 0); - ubi_dump_sv(sv); + ubi_dump_av(av); goto out; -bad_sv: - ubi_err("bad attaching information about volume %d", sv->vol_id); - ubi_dump_sv(sv); +bad_av: + ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_dump_av(av); goto out; bad_vid_hdr: - ubi_err("bad attaching information about volume %d", sv->vol_id); - ubi_dump_sv(sv); + ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_dump_av(av); ubi_dump_vid_hdr(vidh); out: diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 0f0725e18b7f..3e19cb665a55 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -145,26 +145,26 @@ struct ubi_vid_hdr; /* * ubi_scan_move_to_list - move a PEB from the volume tree to a list. * - * @sv: volume attaching information + * @av: volume attaching information * @aeb: scanning eraseblock information * @list: the list to move to */ -static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *sv, +static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *av, struct ubi_ainf_peb *aeb, struct list_head *list) { - rb_erase(&aeb->u.rb, &sv->root); + rb_erase(&aeb->u.rb, &av->root); list_add_tail(&aeb->u.list, list); } int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_ainf_volume *ubi_scan_find_sv(const struct ubi_attach_info *ai, +struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, int vol_id); -struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *sv, +struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *av, int lnum); -void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *sv); +void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *ai, diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 9632163c05fb..92c44a549f51 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -366,7 +366,7 @@ out_free: * process_lvol - process the layout volume. * @ubi: UBI device description object * @ai: attaching information - * @sv: layout volume attaching information + * @av: layout volume attaching information * * This function is responsible for reading the layout volume, ensuring it is * not corrupted, and recovering from corruptions if needed. Returns volume @@ -374,7 +374,7 @@ out_free: */ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, struct ubi_attach_info *ai, - struct ubi_ainf_volume *sv) + struct ubi_ainf_volume *av) { int err; struct rb_node *rb; @@ -410,7 +410,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, dbg_gen("check layout volume"); /* Read both LEB 0 and LEB 1 into memory */ - ubi_rb_for_each_entry(rb, aeb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) { leb[aeb->lnum] = vzalloc(ubi->vtbl_size); if (!leb[aeb->lnum]) { err = -ENOMEM; @@ -536,7 +536,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_vtbl_record *vtbl) { int i, reserved_pebs = 0; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_volume *vol; for (i = 0; i < ubi->vtbl_slots; i++) { @@ -592,8 +592,8 @@ static int init_volumes(struct ubi_device *ubi, } /* Static volumes only */ - sv = ubi_scan_find_sv(ai, i); - if (!sv) { + av = ubi_scan_find_av(ai, i); + if (!av) { /* * No eraseblocks belonging to this volume found. We * don't actually know whether this static volume is @@ -605,22 +605,22 @@ static int init_volumes(struct ubi_device *ubi, continue; } - if (sv->leb_count != sv->used_ebs) { + if (av->leb_count != av->used_ebs) { /* * We found a static volume which misses several * eraseblocks. Treat it as corrupted. */ ubi_warn("static volume %d misses %d LEBs - corrupted", - sv->vol_id, sv->used_ebs - sv->leb_count); + av->vol_id, av->used_ebs - av->leb_count); vol->corrupted = 1; continue; } - vol->used_ebs = sv->used_ebs; + vol->used_ebs = av->used_ebs; vol->used_bytes = (long long)(vol->used_ebs - 1) * vol->usable_leb_size; - vol->used_bytes += sv->last_data_size; - vol->last_eb_bytes = sv->last_data_size; + vol->used_bytes += av->last_data_size; + vol->last_eb_bytes = av->last_data_size; } /* And add the layout volume */ @@ -661,35 +661,35 @@ static int init_volumes(struct ubi_device *ubi, } /** - * check_sv - check volume attaching information. + * check_av - check volume attaching information. * @vol: UBI volume description object - * @sv: volume attaching information + * @av: volume attaching information * * This function returns zero if the volume attaching information is consistent * to the data read from the volume tabla, and %-EINVAL if not. */ -static int check_sv(const struct ubi_volume *vol, - const struct ubi_ainf_volume *sv) +static int check_av(const struct ubi_volume *vol, + const struct ubi_ainf_volume *av) { int err; - if (sv->highest_lnum >= vol->reserved_pebs) { + if (av->highest_lnum >= vol->reserved_pebs) { err = 1; goto bad; } - if (sv->leb_count > vol->reserved_pebs) { + if (av->leb_count > vol->reserved_pebs) { err = 2; goto bad; } - if (sv->vol_type != vol->vol_type) { + if (av->vol_type != vol->vol_type) { err = 3; goto bad; } - if (sv->used_ebs > vol->reserved_pebs) { + if (av->used_ebs > vol->reserved_pebs) { err = 4; goto bad; } - if (sv->data_pad != vol->data_pad) { + if (av->data_pad != vol->data_pad) { err = 5; goto bad; } @@ -697,7 +697,7 @@ static int check_sv(const struct ubi_volume *vol, bad: ubi_err("bad attaching information, error %d", err); - ubi_dump_sv(sv); + ubi_dump_av(av); ubi_dump_vol_info(vol); return -EINVAL; } @@ -716,7 +716,7 @@ static int check_scanning_info(const struct ubi_device *ubi, struct ubi_attach_info *ai) { int err, i; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_volume *vol; if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { @@ -735,18 +735,18 @@ static int check_scanning_info(const struct ubi_device *ubi, for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { cond_resched(); - sv = ubi_scan_find_sv(ai, i); + av = ubi_scan_find_av(ai, i); vol = ubi->volumes[i]; if (!vol) { - if (sv) - ubi_scan_rm_volume(ai, sv); + if (av) + ubi_scan_rm_volume(ai, av); continue; } if (vol->reserved_pebs == 0) { ubi_assert(i < ubi->vtbl_slots); - if (!sv) + if (!av) continue; /* @@ -756,10 +756,10 @@ static int check_scanning_info(const struct ubi_device *ubi, * reboot while the volume was being removed. Discard * these eraseblocks. */ - ubi_msg("finish volume %d removal", sv->vol_id); - ubi_scan_rm_volume(ai, sv); - } else if (sv) { - err = check_sv(vol, sv); + ubi_msg("finish volume %d removal", av->vol_id); + ubi_scan_rm_volume(ai, av); + } else if (av) { + err = check_av(vol, av); if (err) return err; } @@ -780,7 +780,7 @@ static int check_scanning_info(const struct ubi_device *ubi, int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) { int i, err; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); @@ -795,8 +795,8 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE; ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size); - sv = ubi_scan_find_sv(ai, UBI_LAYOUT_VOLUME_ID); - if (!sv) { + av = ubi_scan_find_av(ai, UBI_LAYOUT_VOLUME_ID); + if (!av) { /* * No logical eraseblocks belonging to the layout volume were * found. This could mean that the flash is just empty. In @@ -814,14 +814,14 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) return -EINVAL; } } else { - if (sv->leb_count > UBI_LAYOUT_VOLUME_EBS) { + if (av->leb_count > UBI_LAYOUT_VOLUME_EBS) { /* This must not happen with proper UBI images */ ubi_err("too many LEBs (%d) in layout volume", - sv->leb_count); + av->leb_count); return -EINVAL; } - ubi->vtbl = process_lvol(ubi, ai, sv); + ubi->vtbl = process_lvol(ubi, ai, av); if (IS_ERR(ubi->vtbl)) return PTR_ERR(ubi->vtbl); } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 992240dae1b1..72fbae1f0a5d 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1384,7 +1384,7 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) { int err, i; struct rb_node *rb1, *rb2; - struct ubi_ainf_volume *sv; + struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb, *tmp; struct ubi_wl_entry *e; @@ -1436,8 +1436,8 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) ubi->lookuptbl[e->pnum] = e; } - ubi_rb_for_each_entry(rb1, sv, &ai->volumes, rb) { - ubi_rb_for_each_entry(rb2, aeb, &sv->root, u.rb) { + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { cond_resched(); e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); -- cgit v1.2.3 From aea180f018eccc498d7aff7efa30672afc108cce Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:20:28 +0300 Subject: UBI: make ubi_scan_erase_peb static and rename The 'ubi_scan_erase_peb()' is used only in scan.c so can be static. Also re-name it to 'early_erase_peb()' because we tend to use "ubi_" prefix only for non-static fuction and also because the new name is better. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 8 ++++---- drivers/mtd/ubi/scan.h | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index a7ac06809f16..3222ae898dc8 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -667,7 +667,7 @@ void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) } /** - * ubi_scan_erase_peb - erase a physical eraseblock. + * early_erase_peb - erase a physical eraseblock. * @ubi: UBI device description object * @ai: attaching information * @pnum: physical eraseblock number to erase; @@ -679,8 +679,8 @@ void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *ai, - int pnum, int ec) +static int early_erase_peb(struct ubi_device *ubi, + const struct ubi_attach_info *ai, int pnum, int ec) { int err; struct ubi_ec_hdr *ec_hdr; @@ -748,7 +748,7 @@ struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, if (aeb->ec == UBI_SCAN_UNKNOWN_EC) aeb->ec = ai->mean_ec; - err = ubi_scan_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); + err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); if (err) continue; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 3e19cb665a55..59ed0750cef8 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -167,8 +167,6 @@ struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *av, void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); -int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_attach_info *ai, - int pnum, int ec); struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); void ubi_scan_destroy_ai(struct ubi_attach_info *ai); -- cgit v1.2.3 From fe418d0413e4d858459f7f09c98df06a85f6f7bb Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:24:58 +0300 Subject: UBI: remove unused function The 'ubi_scan_find_aeb()' function is unused and thus can be removed. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 29 ----------------------------- drivers/mtd/ubi/scan.h | 2 -- 2 files changed, 31 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 3222ae898dc8..75f49fa8bc59 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -614,35 +614,6 @@ struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, return NULL; } -/** - * ubi_scan_find_aeb - find LEB in the volume attaching information. - * @av: a pointer to the volume attaching information - * @lnum: the requested logical eraseblock - * - * This function returns a pointer to the scanning logical eraseblock or %NULL - * if there are no data about it in the scanning volume information. - */ -struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *av, - int lnum) -{ - struct ubi_ainf_peb *aeb; - struct rb_node *p = av->root.rb_node; - - while (p) { - aeb = rb_entry(p, struct ubi_ainf_peb, u.rb); - - if (lnum == aeb->lnum) - return aeb; - - if (lnum > aeb->lnum) - p = p->rb_left; - else - p = p->rb_right; - } - - return NULL; -} - /** * ubi_scan_rm_volume - delete attaching information about a volume. * @ai: attaching information diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 59ed0750cef8..ef6e903be8e0 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -162,8 +162,6 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, int bitflips); struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, int vol_id); -struct ubi_ainf_peb *ubi_scan_find_aeb(const struct ubi_ainf_volume *av, - int lnum); void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); -- cgit v1.2.3 From 27256f5f10db46a062576d6640c8b392476395d3 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:31:31 +0300 Subject: UBI: rename ubi_scan_add_used The old name is not logical anymore - rename it to 'ubi_add_to_av()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 9 ++++----- drivers/mtd/ubi/scan.h | 5 ++--- drivers/mtd/ubi/vtbl.c | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 75f49fa8bc59..15bf1e16921e 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -425,7 +425,7 @@ out_free_vidh: } /** - * ubi_scan_add_used - add physical eraseblock to the attaching information. + * ubi_add_to_av - add physical eraseblock to the attaching information. * @ubi: UBI device description object * @ai: attaching information * @pnum: the physical eraseblock number @@ -440,9 +440,8 @@ out_free_vidh: * to be picked, while the older one has to be dropped. This function returns * zero in case of success and a negative error code in case of failure. */ -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, - int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, - int bitflips) +int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, + int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) { int err, vol_id, lnum; unsigned long long sqnum; @@ -1016,7 +1015,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (ec_err) ubi_warn("valid VID header but corrupted EC header at PEB %d", pnum); - err = ubi_scan_add_used(ubi, ai, pnum, ec, vidh, bitflips); + err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); if (err) return err; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index ef6e903be8e0..5a9ecc0abdd2 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -157,9 +157,8 @@ static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *av, list_add_tail(&aeb->u.list, list); } -int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_attach_info *ai, - int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, - int bitflips); +int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, + int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, int vol_id); void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 92c44a549f51..209a6dbaf741 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -338,10 +338,9 @@ retry: /* * And add it to the attaching information. Don't delete the old version - * of this LEB as it will be deleted and freed in 'ubi_scan_add_used()'. + * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. */ - err = ubi_scan_add_used(ubi, ai, new_aeb->pnum, new_aeb->ec, - vid_hdr, 0); + err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); kfree(new_aeb); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -428,7 +427,7 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, * aeb->scrub). If the data is not OK, the contents of * the PEB will be recovered from the second copy, and * aeb->scrub will be cleared in - * 'ubi_scan_add_used()'. + * 'ubi_add_to_av()'. */ aeb->scrub = 1; else if (err) -- cgit v1.2.3 From cd60bd4c9701b59818141573eb56c72fbf0a4061 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:33:20 +0300 Subject: UBI: rename ubi_scan_find_av The old name is not logical anymore - rename it to 'ubi_find_av()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 2 +- drivers/mtd/ubi/scan.c | 6 +++--- drivers/mtd/ubi/scan.h | 4 ++-- drivers/mtd/ubi/vtbl.c | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index b49bff083b97..b177d7d51997 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1246,7 +1246,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) for (j = 0; j < vol->reserved_pebs; j++) vol->eba_tbl[j] = UBI_LEB_UNMAPPED; - av = ubi_scan_find_av(ai, idx2vol_id(ubi, i)); + av = ubi_find_av(ai, idx2vol_id(ubi, i)); if (!av) continue; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 15bf1e16921e..fa5613de193b 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -585,15 +585,15 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, } /** - * ubi_scan_find_av - find volume in the attaching information. + * ubi_find_av - find volume in the attaching information. * @ai: attaching information * @vol_id: the requested volume ID * * This function returns a pointer to the volume description or %NULL if there * are no data about this volume in the attaching information. */ -struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, - int vol_id) +struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, + int vol_id) { struct ubi_ainf_volume *av; struct rb_node *p = ai->volumes.rb_node; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 5a9ecc0abdd2..b1eeb0bda0e7 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -159,8 +159,8 @@ static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *av, int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_ainf_volume *ubi_scan_find_av(const struct ubi_attach_info *ai, - int vol_id); +struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, + int vol_id); void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 209a6dbaf741..e2644a403c02 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -591,7 +591,7 @@ static int init_volumes(struct ubi_device *ubi, } /* Static volumes only */ - av = ubi_scan_find_av(ai, i); + av = ubi_find_av(ai, i); if (!av) { /* * No eraseblocks belonging to this volume found. We @@ -734,7 +734,7 @@ static int check_scanning_info(const struct ubi_device *ubi, for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { cond_resched(); - av = ubi_scan_find_av(ai, i); + av = ubi_find_av(ai, i); vol = ubi->volumes[i]; if (!vol) { if (av) @@ -794,7 +794,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE; ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size); - av = ubi_scan_find_av(ai, UBI_LAYOUT_VOLUME_ID); + av = ubi_find_av(ai, UBI_LAYOUT_VOLUME_ID); if (!av) { /* * No logical eraseblocks belonging to the layout volume were -- cgit v1.2.3 From 33373d8ff7c1b049ba5ec057fd6b252f7270c43a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:36:39 +0300 Subject: UBI: rename ubi_scan_rm_volume The old name is not logical anymore - rename it to 'ubi_remove_av()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 4 ++-- drivers/mtd/ubi/scan.h | 2 +- drivers/mtd/ubi/vtbl.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index fa5613de193b..b39c35a9b035 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -614,11 +614,11 @@ struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, } /** - * ubi_scan_rm_volume - delete attaching information about a volume. + * ubi_remove_av - delete attaching information about a volume. * @ai: attaching information * @av: the volume attaching information to delete */ -void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) +void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) { struct rb_node *rb; struct ubi_ainf_peb *aeb; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index b1eeb0bda0e7..7d7e65f11f14 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -161,7 +161,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, int vol_id); -void ubi_scan_rm_volume(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); +void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index e2644a403c02..d8ffc7d50dc4 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -738,7 +738,7 @@ static int check_scanning_info(const struct ubi_device *ubi, vol = ubi->volumes[i]; if (!vol) { if (av) - ubi_scan_rm_volume(ai, av); + ubi_remove_av(ai, av); continue; } @@ -756,7 +756,7 @@ static int check_scanning_info(const struct ubi_device *ubi, * these eraseblocks. */ ubi_msg("finish volume %d removal", av->vol_id); - ubi_scan_rm_volume(ai, av); + ubi_remove_av(ai, av); } else if (av) { err = check_av(vol, av); if (err) -- cgit v1.2.3 From fe5d16a7e46c5c072d3c377f5b7bd07598f28b81 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:38:56 +0300 Subject: UBI: rename ubi_scan_get_free_peb The old name is not logical anymore - rename it to 'ubi_early_get_peb()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 6 +++--- drivers/mtd/ubi/scan.h | 4 ++-- drivers/mtd/ubi/vtbl.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index b39c35a9b035..805781936e02 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -682,7 +682,7 @@ out_free: } /** - * ubi_scan_get_free_peb - get a free physical eraseblock. + * ubi_early_get_peb - get a free physical eraseblock. * @ubi: UBI device description object * @ai: attaching information * @@ -695,8 +695,8 @@ out_free: * This function returns scanning physical eraseblock information in case of * success and an error code in case of failure. */ -struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_attach_info *ai) +struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, + struct ubi_attach_info *ai) { int err = 0; struct ubi_ainf_peb *aeb, *tmp_aeb; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 7d7e65f11f14..72ba24a13a72 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -162,8 +162,8 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, int vol_id); void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); -struct ubi_ainf_peb *ubi_scan_get_free_peb(struct ubi_device *ubi, - struct ubi_attach_info *ai); +struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, + struct ubi_attach_info *ai); struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); void ubi_scan_destroy_ai(struct ubi_attach_info *ai); diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index d8ffc7d50dc4..b5a484c0bfac 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -312,7 +312,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai, return -ENOMEM; retry: - new_aeb = ubi_scan_get_free_peb(ubi, ai); + new_aeb = ubi_early_get_peb(ubi, ai); if (IS_ERR(new_aeb)) { err = PTR_ERR(new_aeb); goto out_free; -- cgit v1.2.3 From 20589f9e494ec8a7a13dd9fac6e9f074e433dc7c Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:41:12 +0300 Subject: UBI: rename ubi_scan_destroy_ai The old name is not logical anymore - rename it to 'ubi_destroy_ai()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 4 ++-- drivers/mtd/ubi/scan.c | 6 +++--- drivers/mtd/ubi/scan.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 404d26ad9020..1cd27b572859 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -608,7 +608,7 @@ static int attach_by_scanning(struct ubi_device *ubi) if (err) goto out_wl; - ubi_scan_destroy_ai(ai); + ubi_destroy_ai(ai); return 0; out_wl: @@ -617,7 +617,7 @@ out_vtbl: free_internal_volumes(ubi); vfree(ubi->vtbl); out_ai: - ubi_scan_destroy_ai(ai); + ubi_destroy_ai(ai); return err; } diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 805781936e02..8489b131f6d9 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1203,7 +1203,7 @@ out_vidh: out_ech: kfree(ech); out_ai: - ubi_scan_destroy_ai(ai); + ubi_destroy_ai(ai); return ERR_PTR(err); } @@ -1242,10 +1242,10 @@ static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) } /** - * ubi_scan_destroy_ai - destroy attaching information. + * ubi_destroy_ai - destroy attaching information. * @ai: attaching information */ -void ubi_scan_destroy_ai(struct ubi_attach_info *ai) +void ubi_destroy_ai(struct ubi_attach_info *ai) { struct ubi_ainf_peb *aeb, *aeb_tmp; struct ubi_ainf_volume *av; diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 72ba24a13a72..a406f5b4ffeb 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -165,6 +165,6 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); -void ubi_scan_destroy_ai(struct ubi_attach_info *ai); +void ubi_destroy_ai(struct ubi_attach_info *ai); #endif /* !__UBI_SCAN_H__ */ -- cgit v1.2.3 From 8f420e7c55d686ea4daaf2c0863a6c4e17ea65bb Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:53:10 +0300 Subject: UBI: rename ubi_scan_move_to_list The old name is not logical anymore - rename it to 'ubi_move_aeb_to_list()'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 2 +- drivers/mtd/ubi/scan.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index b177d7d51997..b6553a199716 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1256,7 +1256,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) * This may happen in case of an unclean reboot * during re-size. */ - ubi_scan_move_to_list(av, aeb, &ai->erase); + ubi_move_aeb_to_list(av, aeb, &ai->erase); vol->eba_tbl[aeb->lnum] = aeb->pnum; } } diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index a406f5b4ffeb..aa76b3b5c6b5 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -143,13 +143,13 @@ struct ubi_device; struct ubi_vid_hdr; /* - * ubi_scan_move_to_list - move a PEB from the volume tree to a list. + * ubi_move_aeb_to_list - move a PEB from the volume tree to a list. * * @av: volume attaching information * @aeb: scanning eraseblock information * @list: the list to move to */ -static inline void ubi_scan_move_to_list(struct ubi_ainf_volume *av, +static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av, struct ubi_ainf_peb *aeb, struct list_head *list) { -- cgit v1.2.3 From 7ce40acc68fd6598b94617bae182361c896ae699 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 15:56:03 +0300 Subject: UBI: rename ubi_scan_leb_slab The old name is not logical anymore - rename it to 'aeb_slab_cache'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 28 ++++++++++++++-------------- drivers/mtd/ubi/scan.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 8489b131f6d9..d59f26cb9039 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -125,7 +125,7 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, } else BUG(); - aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); if (!aeb) return -ENOMEM; @@ -154,7 +154,7 @@ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); - aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); if (!aeb) return -ENOMEM; @@ -562,7 +562,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, if (err) return err; - aeb = kmem_cache_alloc(ai->scan_leb_slab, GFP_KERNEL); + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); if (!aeb) return -ENOMEM; @@ -1133,10 +1133,10 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) ai->volumes = RB_ROOT; err = -ENOMEM; - ai->scan_leb_slab = kmem_cache_create("ubi_scan_leb_slab", - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->scan_leb_slab) + ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) goto out_ai; ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); @@ -1235,7 +1235,7 @@ static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) this->rb_right = NULL; } - kmem_cache_free(ai->scan_leb_slab, aeb); + kmem_cache_free(ai->aeb_slab_cache, aeb); } } kfree(av); @@ -1253,19 +1253,19 @@ void ubi_destroy_ai(struct ubi_attach_info *ai) list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { list_del(&aeb->u.list); - kmem_cache_free(ai->scan_leb_slab, aeb); + kmem_cache_free(ai->aeb_slab_cache, aeb); } list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { list_del(&aeb->u.list); - kmem_cache_free(ai->scan_leb_slab, aeb); + kmem_cache_free(ai->aeb_slab_cache, aeb); } list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { list_del(&aeb->u.list); - kmem_cache_free(ai->scan_leb_slab, aeb); + kmem_cache_free(ai->aeb_slab_cache, aeb); } list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { list_del(&aeb->u.list); - kmem_cache_free(ai->scan_leb_slab, aeb); + kmem_cache_free(ai->aeb_slab_cache, aeb); } /* Destroy the volume RB-tree */ @@ -1290,8 +1290,8 @@ void ubi_destroy_ai(struct ubi_attach_info *ai) } } - if (ai->scan_leb_slab) - kmem_cache_destroy(ai->scan_leb_slab); + if (ai->aeb_slab_cache) + kmem_cache_destroy(ai->aeb_slab_cache); kfree(ai); } diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index aa76b3b5c6b5..20bec7cf9ac8 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -110,7 +110,7 @@ struct ubi_ainf_volume { * @mean_ec: mean erase counter value * @ec_sum: a temporary variable used when calculating @mean_ec * @ec_count: a temporary variable used when calculating @mean_ec - * @scan_leb_slab: slab cache for &struct ubi_ainf_peb objects + * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects * * This data structure contains the result of attaching an MTD device and may * be used by other UBI sub-systems to build final UBI data structures, further @@ -136,7 +136,7 @@ struct ubi_attach_info { int mean_ec; uint64_t ec_sum; int ec_count; - struct kmem_cache *scan_leb_slab; + struct kmem_cache *aeb_slab_cache; }; struct ubi_device; -- cgit v1.2.3 From 2dcda46eacdb538db765bddb5fe13d0fba08557d Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 16:12:26 +0300 Subject: UBI: amend comments after all the renamings This patch amends commentaries in scan.[ch] to match the new logic. Reminder - we did the restructuring to prepare the code for adding the fastmap. This patch also renames a couple of functions - it was too difficult to separate out that change and I decided that it is not too bad to have it in the same patch with commentaries changes. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 12 ++--- drivers/mtd/ubi/io.c | 3 +- drivers/mtd/ubi/scan.c | 111 ++++++++++++++++++++++---------------------- drivers/mtd/ubi/scan.h | 2 +- drivers/mtd/ubi/ubi-media.h | 4 +- drivers/mtd/ubi/vtbl.c | 22 ++++----- 6 files changed, 73 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 1cd27b572859..7bf60f9ac96e 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -27,10 +27,6 @@ * module load parameters or the kernel boot parameters. If MTD devices were * specified, UBI does not attach any MTD device, but it is possible to do * later using the "UBI control device". - * - * At the moment we only attach UBI devices by scanning, which will become a - * bottleneck when flashes reach certain large size. Then one may improve UBI - * and add other methods, although it does not seem to be easy to do. */ #include @@ -790,11 +786,11 @@ static int io_init(struct ubi_device *ubi) ubi_msg("data offset: %d", ubi->leb_start); /* - * Note, ideally, we have to initialize ubi->bad_peb_count here. But + * Note, ideally, we have to initialize @ubi->bad_peb_count here. But * unfortunately, MTD does not provide this information. We should loop * over all physical eraseblocks and invoke mtd->block_is_bad() for - * each physical eraseblock. So, we skip ubi->bad_peb_count - * uninitialized and initialize it after scanning. + * each physical eraseblock. So, we leave @ubi->bad_peb_count + * uninitialized so far. */ return 0; @@ -805,7 +801,7 @@ static int io_init(struct ubi_device *ubi) * @ubi: UBI device description object * @vol_id: ID of the volume to re-size * - * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in + * This function re-sizes the volume marked by the %UBI_VTBL_AUTORESIZE_FLG in * the volume table to the largest possible size. See comments in ubi-header.h * for more description of the flag. Returns zero in case of success and a * negative error code in case of failure. diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 1f568ed96f40..172c72ad6d81 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -513,8 +513,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) * It is important to first invalidate the EC header, and then the VID * header. Otherwise a power cut may lead to valid EC header and * invalid VID header, in which case UBI will treat this PEB as - * corrupted and will try to preserve it, and print scary warnings (see - * the header comment in scan.c for more information). + * corrupted and will try to preserve it, and print scary warnings. */ addr = (loff_t)pnum * ubi->peb_size; err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index d59f26cb9039..24fdf733cec9 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -19,21 +19,21 @@ */ /* - * UBI scanning sub-system. + * UBI attaching sub-system. * - * This sub-system is responsible for scanning the flash media, checking UBI - * headers and providing complete information about the UBI flash image. + * This sub-system is responsible for attaching MTD devices and it also + * implements flash media scanning. * * The attaching information is represented by a &struct ubi_attach_info' - * object. Information about found volumes is represented by - * &struct ubi_ainf_volume objects which are kept in volume RB-tree with root - * at the @volumes field. The RB-tree is indexed by the volume ID. + * object. Information about volumes is represented by &struct ubi_ainf_volume + * objects which are kept in volume RB-tree with root at the @volumes field. + * The RB-tree is indexed by the volume ID. * - * Scanned logical eraseblocks are represented by &struct ubi_ainf_peb objects. - * These objects are kept in per-volume RB-trees with the root at the - * corresponding &struct ubi_ainf_volume object. To put it differently, we keep - * an RB-tree of per-volume objects and each of these objects is the root of - * RB-tree of per-eraseblock objects. + * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These + * objects are kept in per-volume RB-trees with the root at the corresponding + * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of + * per-volume objects and each of these objects is the root of RB-tree of + * per-LEB objects. * * Corrupted physical eraseblocks are put to the @corr list, free physical * eraseblocks are put to the @free list and the physical eraseblock to be @@ -51,28 +51,29 @@ * * 1. Corruptions caused by power cuts. These are expected corruptions and UBI * tries to handle them gracefully, without printing too many warnings and - * error messages. The idea is that we do not lose important data in these case - * - we may lose only the data which was being written to the media just before - * the power cut happened, and the upper layers (e.g., UBIFS) are supposed to - * handle such data losses (e.g., by using the FS journal). + * error messages. The idea is that we do not lose important data in these + * cases - we may lose only the data which were being written to the media just + * before the power cut happened, and the upper layers (e.g., UBIFS) are + * supposed to handle such data losses (e.g., by using the FS journal). * * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like * the reason is a power cut, UBI puts this PEB to the @erase list, and all * PEBs in the @erase list are scheduled for erasure later. * * 2. Unexpected corruptions which are not caused by power cuts. During - * scanning, such PEBs are put to the @corr list and UBI preserves them. + * attaching, such PEBs are put to the @corr list and UBI preserves them. * Obviously, this lessens the amount of available PEBs, and if at some point * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs * about such PEBs every time the MTD device is attached. * * However, it is difficult to reliably distinguish between these types of - * corruptions and UBI's strategy is as follows. UBI assumes corruption type 2 - * if the VID header is corrupted and the data area does not contain all 0xFFs, - * and there were no bit-flips or integrity errors while reading the data area. - * Otherwise UBI assumes corruption type 1. So the decision criteria are as - * follows. - * o If the data area contains only 0xFFs, there is no data, and it is safe + * corruptions and UBI's strategy is as follows (in case of attaching by + * scanning). UBI assumes corruption type 2 if the VID header is corrupted and + * the data area does not contain all 0xFFs, and there were no bit-flips or + * integrity errors (e.g., ECC errors in case of NAND) while reading the data + * area. Otherwise UBI assumes corruption type 1. So the decision criteria + * are as follows. + * o If the data area contains only 0xFFs, there are no data, and it is safe * to just erase this PEB - this is corruption type 1. * o If the data area has bit-flips or data integrity errors (ECC errors on * NAND), it is probably a PEB which was being erased when power cut @@ -102,7 +103,8 @@ static struct ubi_vid_hdr *vidh; * @to_head: if not zero, add to the head of the list * @list: the list to add to * - * This function adds physical eraseblock @pnum to free, erase, or alien lists. + * This function allocates a 'struct ubi_ainf_peb' object for physical + * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. * If @to_head is not zero, PEB will be added to the head of the list, which * basically means it will be processed first later. E.g., we add corrupted * PEBs (corrupted due to power cuts) to the head of the erase list to make @@ -144,9 +146,10 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, * @pnum: physical eraseblock number to add * @ec: erase counter of the physical eraseblock * - * This function adds corrupted physical eraseblock @pnum to the 'corr' list. - * The corruption was presumably not caused by a power cut. Returns zero in - * case of success and a negative error code in case of failure. + * This function allocates a 'struct ubi_ainf_peb' object for a corrupted + * physical eraseblock @pnum and adds it to the 'corr' list. The corruption + * was presumably not caused by a power cut. Returns zero in case of success + * and a negative error code in case of failure. */ static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) { @@ -241,8 +244,8 @@ bad: * If the volume corresponding to the @vid_hdr logical eraseblock is already * present in the attaching information, this function does nothing. Otherwise * it adds corresponding volume to the attaching information. Returns a pointer - * to the scanning volume object in case of success and a negative error code - * in case of failure. + * to the allocated "av" object in case of success and a negative error code in + * case of failure. */ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, int vol_id, int pnum, @@ -425,7 +428,7 @@ out_free_vidh: } /** - * ubi_add_to_av - add physical eraseblock to the attaching information. + * ubi_add_to_av - add used physical eraseblock to the attaching information. * @ubi: UBI device description object * @ai: attaching information * @pnum: the physical eraseblock number @@ -692,8 +695,8 @@ out_free: * the lists, writes the EC header if it is needed, and removes it from the * list. * - * This function returns scanning physical eraseblock information in case of - * success and an error code in case of failure. + * This function returns a pointer to the "aeb" of the found free PEB in case + * of success and an error code in case of failure. */ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, struct ubi_attach_info *ai) @@ -793,16 +796,18 @@ out_unlock: } /** - * process_eb - read, check UBI headers, and add them to attaching information. + * scan_peb - scan and process UBI headers of a PEB. * @ubi: UBI device description object * @ai: attaching information * @pnum: the physical eraseblock number * - * This function returns a zero if the physical eraseblock was successfully - * handled and a negative error code in case of failure. + * This function reads UBI headers of PEB @pnum, checks them, and adds + * information about this PEB to the corresponding list or RB-tree in the + * "attaching info" structure. Returns zero if the physical eraseblock was + * successfully handled and a negative error code in case of failure. */ -static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *ai, - int pnum) +static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, + int pnum) { long long uninitialized_var(ec); int err, bitflips = 0, vol_id, ec_err = 0; @@ -814,11 +819,6 @@ static int process_eb(struct ubi_device *ubi, struct ubi_attach_info *ai, if (err < 0) return err; else if (err) { - /* - * FIXME: this is actually duty of the I/O sub-system to - * initialize this, but MTD does not provide enough - * information. - */ ai->bad_peb_count += 1; return 0; } @@ -1033,18 +1033,17 @@ adjust_mean_ec: } /** - * check_what_we_have - check what PEB were found by scanning. + * late_analysis - analyze the overall situation with PEB. * @ubi: UBI device description object * @ai: attaching information * - * This is a helper function which takes a look what PEBs were found by - * scanning, and decides whether the flash is empty and should be formatted and - * whether there are too many corrupted PEBs and we should not attach this - * MTD device. Returns zero if we should proceed with attaching the MTD device, - * and %-EINVAL if we should not. + * This is a helper function which takes a look what PEBs we have after we + * gather information about all of them ("ai" is compete). It decides whether + * the flash is empty and should be formatted of whether there are too many + * corrupted PEBs and we should not attach this MTD device. Returns zero if we + * should proceed with attaching the MTD device, and %-EINVAL if we should not. */ -static int check_what_we_have(struct ubi_device *ubi, - struct ubi_attach_info *ai) +static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) { struct ubi_ainf_peb *aeb; int max_corr, peb_count; @@ -1112,7 +1111,8 @@ static int check_what_we_have(struct ubi_device *ubi, * @ubi: UBI device description object * * This function does full scanning of an MTD device and returns complete - * information about it. In case of failure, an error code is returned. + * information about it in form of a "struct ubi_attach_info" object. In case + * of failure, an error code is returned. */ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) { @@ -1151,7 +1151,7 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) cond_resched(); dbg_gen("process PEB %d", pnum); - err = process_eb(ubi, ai, pnum); + err = scan_peb(ubi, ai, pnum); if (err < 0) goto out_vidh; } @@ -1162,7 +1162,7 @@ struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) if (ai->ec_count) ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); - err = check_what_we_have(ubi, ai); + err = late_analysis(ubi, ai); if (err) goto out_vidh; @@ -1208,12 +1208,11 @@ out_ai: } /** - * destroy_av - free the scanning volume information - * @av: scanning volume information + * destroy_av - free volume attaching information. + * @av: volume attaching information * @ai: attaching information * - * This function destroys the volume RB-tree (@av->root) and the scanning - * volume information. + * This function destroys the volume attaching information. */ static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) { diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 20bec7cf9ac8..a794577d0f30 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -146,7 +146,7 @@ struct ubi_vid_hdr; * ubi_move_aeb_to_list - move a PEB from the volume tree to a list. * * @av: volume attaching information - * @aeb: scanning eraseblock information + * @aeb: attaching eraseblock information * @list: the list to move to */ static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av, diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 6fb8ec2174a5..07cd88f2b203 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h @@ -149,10 +149,10 @@ enum { * The @image_seq field is used to validate a UBI image that has been prepared * for a UBI device. The @image_seq value can be any value, but it must be the * same on all eraseblocks. UBI will ensure that all new erase counter headers - * also contain this value, and will check the value when scanning at start-up. + * also contain this value, and will check the value when attaching the flash. * One way to make use of @image_seq is to increase its value by one every time * an image is flashed over an existing image, then, if the flashing does not - * complete, UBI will detect the error when scanning. + * complete, UBI will detect the error when attaching the media. */ struct ubi_ec_hdr { __be32 magic; diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index b5a484c0bfac..39d6b63f20a5 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -37,16 +37,15 @@ * LEB 1. This scheme guarantees recoverability from unclean reboots. * * In this UBI implementation the on-flash volume table does not contain any - * information about how many data static volumes contain. This information may - * be found from the scanning data. + * information about how much data static volumes contain. * * But it would still be beneficial to store this information in the volume * table. For example, suppose we have a static volume X, and all its physical * eraseblocks became bad for some reasons. Suppose we are attaching the - * corresponding MTD device, the scanning has found no logical eraseblocks + * corresponding MTD device, for some reason we find no logical eraseblocks * corresponding to the volume X. According to the volume table volume X does * exist. So we don't know whether it is just empty or all its physical - * eraseblocks went bad. So we cannot alarm the user about this corruption. + * eraseblocks went bad. So we cannot alarm the user properly. * * The volume table also stores so-called "update marker", which is used for * volume updates. Before updating the volume, the update marker is set, and @@ -702,16 +701,16 @@ bad: } /** - * check_scanning_info - check that attaching information. + * check_attaching_info - check that attaching information. * @ubi: UBI device description object * @ai: attaching information * * Even though we protect on-flash data by CRC checksums, we still don't trust * the media. This function ensures that attaching information is consistent to - * the information read from the volume table. Returns zero if the scanning + * the information read from the volume table. Returns zero if the attaching * information is OK and %-EINVAL if it is not. */ -static int check_scanning_info(const struct ubi_device *ubi, +static int check_attaching_info(const struct ubi_device *ubi, struct ubi_attach_info *ai) { int err, i; @@ -719,15 +718,14 @@ static int check_scanning_info(const struct ubi_device *ubi, struct ubi_volume *vol; if (ai->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { - ubi_err("scanning found %d volumes, maximum is %d + %d", + ubi_err("found %d volumes while attaching, maximum is %d + %d", ai->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); return -EINVAL; } if (ai->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && ai->highest_vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("too large volume ID %d found by scanning", - ai->highest_vol_id); + ubi_err("too large volume ID %d found", ai->highest_vol_id); return -EINVAL; } @@ -749,7 +747,7 @@ static int check_scanning_info(const struct ubi_device *ubi, continue; /* - * During scanning we found a volume which does not + * During attaching we found a volume which does not * exist according to the information in the volume * table. This must have happened due to an unclean * reboot while the volume was being removed. Discard @@ -839,7 +837,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) * Make sure that the attaching information is consistent to the * information stored in the volume table. */ - err = check_scanning_info(ubi, ai); + err = check_attaching_info(ubi, ai); if (err) goto out_free; -- cgit v1.2.3 From a4995a6ab45c68806279690069f8cff116d6916e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 17 May 2012 21:05:33 +0300 Subject: UBI: rename _init_scan functions We have a couple of initialization funcntionsn left which have "_scan" suffic - rename them: ubi_eba_init_scan() -> ubi_eba_init() ubi_wl_init_scan() -> ubi_wl_init() Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 4 ++-- drivers/mtd/ubi/eba.c | 6 +++--- drivers/mtd/ubi/ubi.h | 4 ++-- drivers/mtd/ubi/wl.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 7bf60f9ac96e..cce7c314a996 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -596,11 +596,11 @@ static int attach_by_scanning(struct ubi_device *ubi) if (err) goto out_ai; - err = ubi_wl_init_scan(ubi, ai); + err = ubi_wl_init(ubi, ai); if (err) goto out_vtbl; - err = ubi_eba_init_scan(ubi, ai); + err = ubi_eba_init(ubi, ai); if (err) goto out_wl; diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index b6553a199716..f167a346bad9 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1167,7 +1167,7 @@ out_unlock_leb: * print_rsvd_warning - warn about not having enough reserved PEBs. * @ubi: UBI device description object * - * This is a helper function for 'ubi_eba_init_scan()' which is called when UBI + * This is a helper function for 'ubi_eba_init()' which is called when UBI * cannot reserve enough PEBs for bad block handling. This function makes a * decision whether we have to print a warning or not. The algorithm is as * follows: @@ -1205,14 +1205,14 @@ static void print_rsvd_warning(struct ubi_device *ubi, } /** - * ubi_eba_init_scan - initialize the EBA sub-system using attaching information. + * ubi_eba_init - initialize the EBA sub-system using attaching information. * @ubi: UBI device description object * @ai: attaching information * * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) +int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai) { int i, j, err, num_volumes; struct ubi_ainf_volume *av; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index faaf72933bcb..9563e1b04f19 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -529,14 +529,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, const void *buf, int len); int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr); -int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai); +int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); /* wl.c */ int ubi_wl_get_peb(struct ubi_device *ubi); int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); int ubi_wl_flush(struct ubi_device *ubi); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai); +int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); void ubi_wl_close(struct ubi_device *ubi); int ubi_thread(void *u); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 72fbae1f0a5d..c143e6112357 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1373,14 +1373,14 @@ static void cancel_pending(struct ubi_device *ubi) } /** - * ubi_wl_init_scan - initialize the WL sub-system using attaching information. + * ubi_wl_init - initialize the WL sub-system using attaching information. * @ubi: UBI device description object * @ai: attaching information * * This function returns zero in case of success, and a negative error code in * case of failure. */ -int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_attach_info *ai) +int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) { int err, i; struct rb_node *rb1, *rb2; -- cgit v1.2.3 From 21bcc5ad4b1dd04e755f44f6b03175278d7fea12 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 18 May 2012 12:41:17 +0300 Subject: UBI: move and rename attach_by_scanning Rename the 'attach_by_scanning()' function to 'ubi_attach()' and move it to scan.c. Richard will plug his fastmap stuff there. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 65 +++++-------------------------------------------- drivers/mtd/ubi/scan.c | 52 +++++++++++++++++++++++++++++++++++++-- drivers/mtd/ubi/scan.h | 2 +- drivers/mtd/ubi/ubi.h | 1 + 4 files changed, 58 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index cce7c314a996..da1088271392 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -550,10 +550,10 @@ static void uif_close(struct ubi_device *ubi) } /** - * free_internal_volumes - free internal volumes. + * ubi_free_internal_volumes - free internal volumes. * @ubi: UBI device description object */ -static void free_internal_volumes(struct ubi_device *ubi) +void ubi_free_internal_volumes(struct ubi_device *ubi) { int i; @@ -564,59 +564,6 @@ static void free_internal_volumes(struct ubi_device *ubi) } } -/** - * attach_by_scanning - attach an MTD device using scanning method. - * @ubi: UBI device descriptor - * - * This function returns zero in case of success and a negative error code in - * case of failure. - * - * Note, currently this is the only method to attach UBI devices. Hopefully in - * the future we'll have more scalable attaching methods and avoid full media - * scanning. But even in this case scanning will be needed as a fall-back - * attaching method if there are some on-flash table corruptions. - */ -static int attach_by_scanning(struct ubi_device *ubi) -{ - int err; - struct ubi_attach_info *ai; - - ai = ubi_scan(ubi); - if (IS_ERR(ai)) - return PTR_ERR(ai); - - ubi->bad_peb_count = ai->bad_peb_count; - ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; - ubi->corr_peb_count = ai->corr_peb_count; - ubi->max_ec = ai->max_ec; - ubi->mean_ec = ai->mean_ec; - ubi_msg("max. sequence number: %llu", ai->max_sqnum); - - err = ubi_read_volume_table(ubi, ai); - if (err) - goto out_ai; - - err = ubi_wl_init(ubi, ai); - if (err) - goto out_vtbl; - - err = ubi_eba_init(ubi, ai); - if (err) - goto out_wl; - - ubi_destroy_ai(ai); - return 0; - -out_wl: - ubi_wl_close(ubi); -out_vtbl: - free_internal_volumes(ubi); - vfree(ubi->vtbl); -out_ai: - ubi_destroy_ai(ai); - return err; -} - /** * io_init - initialize I/O sub-system for a given UBI device. * @ubi: UBI device description object @@ -949,9 +896,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_free; - err = attach_by_scanning(ubi); + err = ubi_attach(ubi); if (err) { - ubi_err("failed to attach by scanning, error %d", err); + ubi_err("failed to attach mtd%d, error %d", mtd->index, err); goto out_debugging; } @@ -1016,7 +963,7 @@ out_uif: uif_close(ubi); out_detach: ubi_wl_close(ubi); - free_internal_volumes(ubi); + ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); out_debugging: ubi_debugging_exit_dev(ubi); @@ -1088,7 +1035,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_debugfs_exit_dev(ubi); uif_close(ubi); ubi_wl_close(ubi); - free_internal_volumes(ubi); + ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 24fdf733cec9..abec8f0f5da7 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -1107,14 +1107,14 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) } /** - * ubi_scan - scan an MTD device. + * scan_all - scan entire MTD device. * @ubi: UBI device description object * * This function does full scanning of an MTD device and returns complete * information about it in form of a "struct ubi_attach_info" object. In case * of failure, an error code is returned. */ -struct ubi_attach_info *ubi_scan(struct ubi_device *ubi) +static struct ubi_attach_info *scan_all(struct ubi_device *ubi) { int err, pnum; struct rb_node *rb1, *rb2; @@ -1207,6 +1207,54 @@ out_ai: return ERR_PTR(err); } +/** + * ubi_attach - attach an MTD device. + * @ubi: UBI device descriptor + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_attach(struct ubi_device *ubi) +{ + int err; + struct ubi_attach_info *ai; + + ai = scan_all(ubi); + if (IS_ERR(ai)) + return PTR_ERR(ai); + + ubi->bad_peb_count = ai->bad_peb_count; + ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; + ubi->corr_peb_count = ai->corr_peb_count; + ubi->max_ec = ai->max_ec; + ubi->mean_ec = ai->mean_ec; + ubi_msg("max. sequence number: %llu", ai->max_sqnum); + + err = ubi_read_volume_table(ubi, ai); + if (err) + goto out_ai; + + err = ubi_wl_init(ubi, ai); + if (err) + goto out_vtbl; + + err = ubi_eba_init(ubi, ai); + if (err) + goto out_wl; + + ubi_destroy_ai(ai); + return 0; + +out_wl: + ubi_wl_close(ubi); +out_vtbl: + ubi_free_internal_volumes(ubi); + vfree(ubi->vtbl); +out_ai: + ubi_destroy_ai(ai); + return err; +} + /** * destroy_av - free volume attaching information. * @av: volume attaching information diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index a794577d0f30..3e0c4f494edf 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -164,7 +164,7 @@ struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); -struct ubi_attach_info *ubi_scan(struct ubi_device *ubi); +int ubi_attach(struct ubi_device *ubi); void ubi_destroy_ai(struct ubi_attach_info *ai); #endif /* !__UBI_SCAN_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 9563e1b04f19..e09e558bc539 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -569,6 +569,7 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_notify_all(struct ubi_device *ubi, int ntype, struct notifier_block *nb); int ubi_enumerate_volumes(struct notifier_block *nb); +void ubi_free_internal_volumes(struct ubi_device *ubi); /* kapi.c */ void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); -- cgit v1.2.3 From 4f6a57db7d736dbf03bbf0530fc52802b50a79c1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 18 May 2012 12:54:58 +0300 Subject: UBI: rename UBI_SCAN_UNKNOWN_EC Rename the constant to UBI_UNKNOWN, for the same reason that we are going to add nother attaching method and re-use the same data structures, so the "SCAN" in the name becomes incorrect. I've also removed the "_EC" part because Joel is going to use this constant for other fields in the attaching info data structures. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.c | 18 +++++++++--------- drivers/mtd/ubi/scan.h | 9 ++++++--- 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index abec8f0f5da7..1f76859e2c58 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -644,7 +644,7 @@ void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) * @ubi: UBI device description object * @ai: attaching information * @pnum: physical eraseblock number to erase; - * @ec: erase counter value to write (%UBI_SCAN_UNKNOWN_EC if it is unknown) + * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown) * * This function erases physical eraseblock 'pnum', and writes the erase * counter header to it. This function should only be used on UBI device @@ -718,7 +718,7 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, * they'll be handled later. */ list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { - if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + if (aeb->ec == UBI_UNKNOWN) aeb->ec = ai->mean_ec; err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); @@ -834,11 +834,11 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, break; case UBI_IO_FF: ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_SCAN_UNKNOWN_EC, 0, + return add_to_list(ai, pnum, UBI_UNKNOWN, 0, &ai->erase); case UBI_IO_FF_BITFLIPS: ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_SCAN_UNKNOWN_EC, 1, + return add_to_list(ai, pnum, UBI_UNKNOWN, 1, &ai->erase); case UBI_IO_BAD_HDR_EBADMSG: case UBI_IO_BAD_HDR: @@ -848,7 +848,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, * moved and EC be re-created. */ ec_err = err; - ec = UBI_SCAN_UNKNOWN_EC; + ec = UBI_UNKNOWN; bitflips = 1; break; default: @@ -1172,21 +1172,21 @@ static struct ubi_attach_info *scan_all(struct ubi_device *ubi) */ ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) - if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + if (aeb->ec == UBI_UNKNOWN) aeb->ec = ai->mean_ec; } list_for_each_entry(aeb, &ai->free, u.list) { - if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + if (aeb->ec == UBI_UNKNOWN) aeb->ec = ai->mean_ec; } list_for_each_entry(aeb, &ai->corr, u.list) - if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + if (aeb->ec == UBI_UNKNOWN) aeb->ec = ai->mean_ec; list_for_each_entry(aeb, &ai->erase, u.list) - if (aeb->ec == UBI_SCAN_UNKNOWN_EC) + if (aeb->ec == UBI_UNKNOWN) aeb->ec = ai->mean_ec; err = self_check_ai(ubi, ai); diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 3e0c4f494edf..e79524313d4b 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h @@ -21,12 +21,15 @@ #ifndef __UBI_SCAN_H__ #define __UBI_SCAN_H__ -/* The erase counter value for this physical eraseblock is unknown */ -#define UBI_SCAN_UNKNOWN_EC (-1) +/* + * When a field of the attaching information has this value - its real value is + * unknown. + */ +#define UBI_UNKNOWN (-1) /** * struct ubi_ainf_peb - attach information about a physical eraseblock. - * @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown) + * @ec: erase counter (%UBI_UNKNOWN if it is unknown) * @pnum: physical eraseblock number * @lnum: logical eraseblock number * @scrub: if this physical eraseblock needs scrubbing -- cgit v1.2.3 From 1292144e33dc86906b1a61d43f04dee934f49b31 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 18 May 2012 13:00:10 +0300 Subject: UBI: remove scan.h This file is small and it does not make sense to have it separate from where everything else lives, so merge it with ubi.h. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/scan.h | 173 ------------------------------------------------- drivers/mtd/ubi/ubi.h | 148 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 174 deletions(-) delete mode 100644 drivers/mtd/ubi/scan.h (limited to 'drivers') diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h deleted file mode 100644 index e79524313d4b..000000000000 --- a/drivers/mtd/ubi/scan.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Artem Bityutskiy (Битюцкий Артём) - */ - -#ifndef __UBI_SCAN_H__ -#define __UBI_SCAN_H__ - -/* - * When a field of the attaching information has this value - its real value is - * unknown. - */ -#define UBI_UNKNOWN (-1) - -/** - * struct ubi_ainf_peb - attach information about a physical eraseblock. - * @ec: erase counter (%UBI_UNKNOWN if it is unknown) - * @pnum: physical eraseblock number - * @lnum: logical eraseblock number - * @scrub: if this physical eraseblock needs scrubbing - * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB) - * @sqnum: sequence number - * @u: unions RB-tree or @list links - * @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects - * @u.list: link in one of the eraseblock lists - * - * One object of this type is allocated for each physical eraseblock when - * attaching an MTD device. - */ -struct ubi_ainf_peb { - int ec; - int pnum; - int lnum; - unsigned int scrub:1; - unsigned int copy_flag:1; - unsigned long long sqnum; - union { - struct rb_node rb; - struct list_head list; - } u; -}; - -/** - * struct ubi_ainf_volume - attaching information about a volume. - * @vol_id: volume ID - * @highest_lnum: highest logical eraseblock number in this volume - * @leb_count: number of logical eraseblocks in this volume - * @vol_type: volume type - * @used_ebs: number of used logical eraseblocks in this volume (only for - * static volumes) - * @last_data_size: amount of data in the last logical eraseblock of this - * volume (always equivalent to the usable logical eraseblock - * size in case of dynamic volumes) - * @data_pad: how many bytes at the end of logical eraseblocks of this volume - * are not used (due to volume alignment) - * @compat: compatibility flags of this volume - * @rb: link in the volume RB-tree - * @root: root of the RB-tree containing all the eraseblock belonging to this - * volume (&struct ubi_ainf_peb objects) - * - * One object of this type is allocated for each volume when attaching an MTD - * device. - */ -struct ubi_ainf_volume { - int vol_id; - int highest_lnum; - int leb_count; - int vol_type; - int used_ebs; - int last_data_size; - int data_pad; - int compat; - struct rb_node rb; - struct rb_root root; -}; - -/** - * struct ubi_attach_info - MTD device attaching information. - * @volumes: root of the volume RB-tree - * @corr: list of corrupted physical eraseblocks - * @free: list of free physical eraseblocks - * @erase: list of physical eraseblocks which have to be erased - * @alien: list of physical eraseblocks which should not be used by UBI (e.g., - * those belonging to "preserve"-compatible internal volumes) - * @corr_peb_count: count of PEBs in the @corr list - * @empty_peb_count: count of PEBs which are presumably empty (contain only - * 0xFF bytes) - * @alien_peb_count: count of PEBs in the @alien list - * @bad_peb_count: count of bad physical eraseblocks - * @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked - * as bad yet, but which look like bad - * @vols_found: number of volumes found - * @highest_vol_id: highest volume ID - * @is_empty: flag indicating whether the MTD device is empty or not - * @min_ec: lowest erase counter value - * @max_ec: highest erase counter value - * @max_sqnum: highest sequence number value - * @mean_ec: mean erase counter value - * @ec_sum: a temporary variable used when calculating @mean_ec - * @ec_count: a temporary variable used when calculating @mean_ec - * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects - * - * This data structure contains the result of attaching an MTD device and may - * be used by other UBI sub-systems to build final UBI data structures, further - * error-recovery and so on. - */ -struct ubi_attach_info { - struct rb_root volumes; - struct list_head corr; - struct list_head free; - struct list_head erase; - struct list_head alien; - int corr_peb_count; - int empty_peb_count; - int alien_peb_count; - int bad_peb_count; - int maybe_bad_peb_count; - int vols_found; - int highest_vol_id; - int is_empty; - int min_ec; - int max_ec; - unsigned long long max_sqnum; - int mean_ec; - uint64_t ec_sum; - int ec_count; - struct kmem_cache *aeb_slab_cache; -}; - -struct ubi_device; -struct ubi_vid_hdr; - -/* - * ubi_move_aeb_to_list - move a PEB from the volume tree to a list. - * - * @av: volume attaching information - * @aeb: attaching eraseblock information - * @list: the list to move to - */ -static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av, - struct ubi_ainf_peb *aeb, - struct list_head *list) -{ - rb_erase(&aeb->u.rb, &av->root); - list_add_tail(&aeb->u.list, list); -} - -int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, - int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); -struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, - int vol_id); -void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); -struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, - struct ubi_attach_info *ai); -int ubi_attach(struct ubi_device *ubi); -void ubi_destroy_ai(struct ubi_attach_info *ai); - -#endif /* !__UBI_SCAN_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index e09e558bc539..52756327827a 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -43,7 +43,6 @@ #include #include "ubi-media.h" -#include "scan.h" /* Maximum number of supported UBI devices */ #define UBI_MAX_DEVICES 32 @@ -82,6 +81,12 @@ */ #define UBI_PROT_QUEUE_LEN 10 +/* + * When a field of the attaching information has this value - its real value is + * unknown. + */ +#define UBI_UNKNOWN -1 + /* * Error codes returned by the I/O sub-system. * @@ -474,6 +479,121 @@ struct ubi_device { struct ubi_debug_info *dbg; }; +/** + * struct ubi_ainf_peb - attach information about a physical eraseblock. + * @ec: erase counter (%UBI_UNKNOWN if it is unknown) + * @pnum: physical eraseblock number + * @lnum: logical eraseblock number + * @scrub: if this physical eraseblock needs scrubbing + * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB) + * @sqnum: sequence number + * @u: unions RB-tree or @list links + * @u.rb: link in the per-volume RB-tree of &struct ubi_ainf_peb objects + * @u.list: link in one of the eraseblock lists + * + * One object of this type is allocated for each physical eraseblock when + * attaching an MTD device. + */ +struct ubi_ainf_peb { + int ec; + int pnum; + int lnum; + unsigned int scrub:1; + unsigned int copy_flag:1; + unsigned long long sqnum; + union { + struct rb_node rb; + struct list_head list; + } u; +}; + +/** + * struct ubi_ainf_volume - attaching information about a volume. + * @vol_id: volume ID + * @highest_lnum: highest logical eraseblock number in this volume + * @leb_count: number of logical eraseblocks in this volume + * @vol_type: volume type + * @used_ebs: number of used logical eraseblocks in this volume (only for + * static volumes) + * @last_data_size: amount of data in the last logical eraseblock of this + * volume (always equivalent to the usable logical eraseblock + * size in case of dynamic volumes) + * @data_pad: how many bytes at the end of logical eraseblocks of this volume + * are not used (due to volume alignment) + * @compat: compatibility flags of this volume + * @rb: link in the volume RB-tree + * @root: root of the RB-tree containing all the eraseblock belonging to this + * volume (&struct ubi_ainf_peb objects) + * + * One object of this type is allocated for each volume when attaching an MTD + * device. + */ +struct ubi_ainf_volume { + int vol_id; + int highest_lnum; + int leb_count; + int vol_type; + int used_ebs; + int last_data_size; + int data_pad; + int compat; + struct rb_node rb; + struct rb_root root; +}; + +/** + * struct ubi_attach_info - MTD device attaching information. + * @volumes: root of the volume RB-tree + * @corr: list of corrupted physical eraseblocks + * @free: list of free physical eraseblocks + * @erase: list of physical eraseblocks which have to be erased + * @alien: list of physical eraseblocks which should not be used by UBI (e.g., + * those belonging to "preserve"-compatible internal volumes) + * @corr_peb_count: count of PEBs in the @corr list + * @empty_peb_count: count of PEBs which are presumably empty (contain only + * 0xFF bytes) + * @alien_peb_count: count of PEBs in the @alien list + * @bad_peb_count: count of bad physical eraseblocks + * @maybe_bad_peb_count: count of bad physical eraseblocks which are not marked + * as bad yet, but which look like bad + * @vols_found: number of volumes found + * @highest_vol_id: highest volume ID + * @is_empty: flag indicating whether the MTD device is empty or not + * @min_ec: lowest erase counter value + * @max_ec: highest erase counter value + * @max_sqnum: highest sequence number value + * @mean_ec: mean erase counter value + * @ec_sum: a temporary variable used when calculating @mean_ec + * @ec_count: a temporary variable used when calculating @mean_ec + * @aeb_slab_cache: slab cache for &struct ubi_ainf_peb objects + * + * This data structure contains the result of attaching an MTD device and may + * be used by other UBI sub-systems to build final UBI data structures, further + * error-recovery and so on. + */ +struct ubi_attach_info { + struct rb_root volumes; + struct list_head corr; + struct list_head free; + struct list_head erase; + struct list_head alien; + int corr_peb_count; + int empty_peb_count; + int alien_peb_count; + int bad_peb_count; + int maybe_bad_peb_count; + int vols_found; + int highest_vol_id; + int is_empty; + int min_ec; + int max_ec; + unsigned long long max_sqnum; + int mean_ec; + uint64_t ec_sum; + int ec_count; + struct kmem_cache *aeb_slab_cache; +}; + #include "debug.h" extern struct kmem_cache *ubi_wl_entry_slab; @@ -484,6 +604,17 @@ extern struct class *ubi_class; extern struct mutex ubi_devices_mutex; extern struct blocking_notifier_head ubi_notifiers; +/* scan.c */ +int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, + int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); +struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, + int vol_id); +void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); +struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, + struct ubi_attach_info *ai); +int ubi_attach(struct ubi_device *ubi); +void ubi_destroy_ai(struct ubi_attach_info *ai); + /* vtbl.c */ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, struct ubi_vtbl_record *vtbl_rec); @@ -590,6 +721,21 @@ void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, rb = rb_next(rb), \ pos = (rb ? container_of(rb, typeof(*pos), member) : NULL)) +/* + * ubi_move_aeb_to_list - move a PEB from the volume tree to a list. + * + * @av: volume attaching information + * @aeb: attaching eraseblock information + * @list: the list to move to + */ +static inline void ubi_move_aeb_to_list(struct ubi_ainf_volume *av, + struct ubi_ainf_peb *aeb, + struct list_head *list) +{ + rb_erase(&aeb->u.rb, &av->root); + list_add_tail(&aeb->u.list, list); +} + /** * ubi_zalloc_vid_hdr - allocate a volume identifier header object. * @ubi: UBI device description object -- cgit v1.2.3 From b00131cbce8db5a7e6c8ba6db449e0abd889d445 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 18 May 2012 13:09:20 +0300 Subject: UBI: rename scan.c to attach.c Finally, rename the scan.c file. Now adding fastmap support won't look that hacky anymore. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Makefile | 2 +- drivers/mtd/ubi/attach.c | 1615 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/scan.c | 1615 ---------------------------------------------- 3 files changed, 1616 insertions(+), 1616 deletions(-) create mode 100644 drivers/mtd/ubi/attach.c delete mode 100644 drivers/mtd/ubi/scan.c (limited to 'drivers') diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index da71655e42db..a0803ac74712 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_MTD_UBI) += ubi.o -ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o scan.o +ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o ubi-y += misc.o debug.o obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c new file mode 100644 index 000000000000..1f76859e2c58 --- /dev/null +++ b/drivers/mtd/ubi/attach.c @@ -0,0 +1,1615 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * UBI attaching sub-system. + * + * This sub-system is responsible for attaching MTD devices and it also + * implements flash media scanning. + * + * The attaching information is represented by a &struct ubi_attach_info' + * object. Information about volumes is represented by &struct ubi_ainf_volume + * objects which are kept in volume RB-tree with root at the @volumes field. + * The RB-tree is indexed by the volume ID. + * + * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These + * objects are kept in per-volume RB-trees with the root at the corresponding + * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of + * per-volume objects and each of these objects is the root of RB-tree of + * per-LEB objects. + * + * Corrupted physical eraseblocks are put to the @corr list, free physical + * eraseblocks are put to the @free list and the physical eraseblock to be + * erased are put to the @erase list. + * + * About corruptions + * ~~~~~~~~~~~~~~~~~ + * + * UBI protects EC and VID headers with CRC-32 checksums, so it can detect + * whether the headers are corrupted or not. Sometimes UBI also protects the + * data with CRC-32, e.g., when it executes the atomic LEB change operation, or + * when it moves the contents of a PEB for wear-leveling purposes. + * + * UBI tries to distinguish between 2 types of corruptions. + * + * 1. Corruptions caused by power cuts. These are expected corruptions and UBI + * tries to handle them gracefully, without printing too many warnings and + * error messages. The idea is that we do not lose important data in these + * cases - we may lose only the data which were being written to the media just + * before the power cut happened, and the upper layers (e.g., UBIFS) are + * supposed to handle such data losses (e.g., by using the FS journal). + * + * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like + * the reason is a power cut, UBI puts this PEB to the @erase list, and all + * PEBs in the @erase list are scheduled for erasure later. + * + * 2. Unexpected corruptions which are not caused by power cuts. During + * attaching, such PEBs are put to the @corr list and UBI preserves them. + * Obviously, this lessens the amount of available PEBs, and if at some point + * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs + * about such PEBs every time the MTD device is attached. + * + * However, it is difficult to reliably distinguish between these types of + * corruptions and UBI's strategy is as follows (in case of attaching by + * scanning). UBI assumes corruption type 2 if the VID header is corrupted and + * the data area does not contain all 0xFFs, and there were no bit-flips or + * integrity errors (e.g., ECC errors in case of NAND) while reading the data + * area. Otherwise UBI assumes corruption type 1. So the decision criteria + * are as follows. + * o If the data area contains only 0xFFs, there are no data, and it is safe + * to just erase this PEB - this is corruption type 1. + * o If the data area has bit-flips or data integrity errors (ECC errors on + * NAND), it is probably a PEB which was being erased when power cut + * happened, so this is corruption type 1. However, this is just a guess, + * which might be wrong. + * o Otherwise this it corruption type 2. + */ + +#include +#include +#include +#include +#include +#include "ubi.h" + +static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai); + +/* Temporary variables used during scanning */ +static struct ubi_ec_hdr *ech; +static struct ubi_vid_hdr *vidh; + +/** + * add_to_list - add physical eraseblock to a list. + * @ai: attaching information + * @pnum: physical eraseblock number to add + * @ec: erase counter of the physical eraseblock + * @to_head: if not zero, add to the head of the list + * @list: the list to add to + * + * This function allocates a 'struct ubi_ainf_peb' object for physical + * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. + * If @to_head is not zero, PEB will be added to the head of the list, which + * basically means it will be processed first later. E.g., we add corrupted + * PEBs (corrupted due to power cuts) to the head of the erase list to make + * sure we erase them first and get rid of corruptions ASAP. This function + * returns zero in case of success and a negative error code in case of + * failure. + */ +static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, + int to_head, struct list_head *list) +{ + struct ubi_ainf_peb *aeb; + + if (list == &ai->free) { + dbg_bld("add to free: PEB %d, EC %d", pnum, ec); + } else if (list == &ai->erase) { + dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); + } else if (list == &ai->alien) { + dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); + ai->alien_peb_count += 1; + } else + BUG(); + + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); + if (!aeb) + return -ENOMEM; + + aeb->pnum = pnum; + aeb->ec = ec; + if (to_head) + list_add(&aeb->u.list, list); + else + list_add_tail(&aeb->u.list, list); + return 0; +} + +/** + * add_corrupted - add a corrupted physical eraseblock. + * @ai: attaching information + * @pnum: physical eraseblock number to add + * @ec: erase counter of the physical eraseblock + * + * This function allocates a 'struct ubi_ainf_peb' object for a corrupted + * physical eraseblock @pnum and adds it to the 'corr' list. The corruption + * was presumably not caused by a power cut. Returns zero in case of success + * and a negative error code in case of failure. + */ +static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) +{ + struct ubi_ainf_peb *aeb; + + dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); + + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); + if (!aeb) + return -ENOMEM; + + ai->corr_peb_count += 1; + aeb->pnum = pnum; + aeb->ec = ec; + list_add(&aeb->u.list, &ai->corr); + return 0; +} + +/** + * validate_vid_hdr - check volume identifier header. + * @vid_hdr: the volume identifier header to check + * @av: information about the volume this logical eraseblock belongs to + * @pnum: physical eraseblock number the VID header came from + * + * This function checks that data stored in @vid_hdr is consistent. Returns + * non-zero if an inconsistency was found and zero if not. + * + * Note, UBI does sanity check of everything it reads from the flash media. + * Most of the checks are done in the I/O sub-system. Here we check that the + * information in the VID header is consistent to the information in other VID + * headers of the same volume. + */ +static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, + const struct ubi_ainf_volume *av, int pnum) +{ + int vol_type = vid_hdr->vol_type; + int vol_id = be32_to_cpu(vid_hdr->vol_id); + int used_ebs = be32_to_cpu(vid_hdr->used_ebs); + int data_pad = be32_to_cpu(vid_hdr->data_pad); + + if (av->leb_count != 0) { + int av_vol_type; + + /* + * This is not the first logical eraseblock belonging to this + * volume. Ensure that the data in its VID header is consistent + * to the data in previous logical eraseblock headers. + */ + + if (vol_id != av->vol_id) { + ubi_err("inconsistent vol_id"); + goto bad; + } + + if (av->vol_type == UBI_STATIC_VOLUME) + av_vol_type = UBI_VID_STATIC; + else + av_vol_type = UBI_VID_DYNAMIC; + + if (vol_type != av_vol_type) { + ubi_err("inconsistent vol_type"); + goto bad; + } + + if (used_ebs != av->used_ebs) { + ubi_err("inconsistent used_ebs"); + goto bad; + } + + if (data_pad != av->data_pad) { + ubi_err("inconsistent data_pad"); + goto bad; + } + } + + return 0; + +bad: + ubi_err("inconsistent VID header at PEB %d", pnum); + ubi_dump_vid_hdr(vid_hdr); + ubi_dump_av(av); + return -EINVAL; +} + +/** + * add_volume - add volume to the attaching information. + * @ai: attaching information + * @vol_id: ID of the volume to add + * @pnum: physical eraseblock number + * @vid_hdr: volume identifier header + * + * If the volume corresponding to the @vid_hdr logical eraseblock is already + * present in the attaching information, this function does nothing. Otherwise + * it adds corresponding volume to the attaching information. Returns a pointer + * to the allocated "av" object in case of success and a negative error code in + * case of failure. + */ +static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, + int vol_id, int pnum, + const struct ubi_vid_hdr *vid_hdr) +{ + struct ubi_ainf_volume *av; + struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; + + ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); + + /* Walk the volume RB-tree to look if this volume is already present */ + while (*p) { + parent = *p; + av = rb_entry(parent, struct ubi_ainf_volume, rb); + + if (vol_id == av->vol_id) + return av; + + if (vol_id > av->vol_id) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + /* The volume is absent - add it */ + av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); + if (!av) + return ERR_PTR(-ENOMEM); + + av->highest_lnum = av->leb_count = 0; + av->vol_id = vol_id; + av->root = RB_ROOT; + av->used_ebs = be32_to_cpu(vid_hdr->used_ebs); + av->data_pad = be32_to_cpu(vid_hdr->data_pad); + av->compat = vid_hdr->compat; + av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME + : UBI_STATIC_VOLUME; + if (vol_id > ai->highest_vol_id) + ai->highest_vol_id = vol_id; + + rb_link_node(&av->rb, parent, p); + rb_insert_color(&av->rb, &ai->volumes); + ai->vols_found += 1; + dbg_bld("added volume %d", vol_id); + return av; +} + +/** + * compare_lebs - find out which logical eraseblock is newer. + * @ubi: UBI device description object + * @aeb: first logical eraseblock to compare + * @pnum: physical eraseblock number of the second logical eraseblock to + * compare + * @vid_hdr: volume identifier header of the second logical eraseblock + * + * This function compares 2 copies of a LEB and informs which one is newer. In + * case of success this function returns a positive value, in case of failure, a + * negative error code is returned. The success return codes use the following + * bits: + * o bit 0 is cleared: the first PEB (described by @aeb) is newer than the + * second PEB (described by @pnum and @vid_hdr); + * o bit 0 is set: the second PEB is newer; + * o bit 1 is cleared: no bit-flips were detected in the newer LEB; + * o bit 1 is set: bit-flips were detected in the newer LEB; + * o bit 2 is cleared: the older LEB is not corrupted; + * o bit 2 is set: the older LEB is corrupted. + */ +static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, + int pnum, const struct ubi_vid_hdr *vid_hdr) +{ + void *buf; + int len, err, second_is_newer, bitflips = 0, corrupted = 0; + uint32_t data_crc, crc; + struct ubi_vid_hdr *vh = NULL; + unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); + + if (sqnum2 == aeb->sqnum) { + /* + * This must be a really ancient UBI image which has been + * created before sequence numbers support has been added. At + * that times we used 32-bit LEB versions stored in logical + * eraseblocks. That was before UBI got into mainline. We do not + * support these images anymore. Well, those images still work, + * but only if no unclean reboots happened. + */ + ubi_err("unsupported on-flash UBI format\n"); + return -EINVAL; + } + + /* Obviously the LEB with lower sequence counter is older */ + second_is_newer = (sqnum2 > aeb->sqnum); + + /* + * Now we know which copy is newer. If the copy flag of the PEB with + * newer version is not set, then we just return, otherwise we have to + * check data CRC. For the second PEB we already have the VID header, + * for the first one - we'll need to re-read it from flash. + * + * Note: this may be optimized so that we wouldn't read twice. + */ + + if (second_is_newer) { + if (!vid_hdr->copy_flag) { + /* It is not a copy, so it is newer */ + dbg_bld("second PEB %d is newer, copy_flag is unset", + pnum); + return 1; + } + } else { + if (!aeb->copy_flag) { + /* It is not a copy, so it is newer */ + dbg_bld("first PEB %d is newer, copy_flag is unset", + pnum); + return bitflips << 1; + } + + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) + return -ENOMEM; + + pnum = aeb->pnum; + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); + if (err) { + if (err == UBI_IO_BITFLIPS) + bitflips = 1; + else { + ubi_err("VID of PEB %d header is bad, but it " + "was OK earlier, err %d", pnum, err); + if (err > 0) + err = -EIO; + + goto out_free_vidh; + } + } + + vid_hdr = vh; + } + + /* Read the data of the copy and check the CRC */ + + len = be32_to_cpu(vid_hdr->data_size); + buf = vmalloc(len); + if (!buf) { + err = -ENOMEM; + goto out_free_vidh; + } + + err = ubi_io_read_data(ubi, buf, pnum, 0, len); + if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) + goto out_free_buf; + + data_crc = be32_to_cpu(vid_hdr->data_crc); + crc = crc32(UBI_CRC32_INIT, buf, len); + if (crc != data_crc) { + dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", + pnum, crc, data_crc); + corrupted = 1; + bitflips = 0; + second_is_newer = !second_is_newer; + } else { + dbg_bld("PEB %d CRC is OK", pnum); + bitflips = !!err; + } + + vfree(buf); + ubi_free_vid_hdr(ubi, vh); + + if (second_is_newer) + dbg_bld("second PEB %d is newer, copy_flag is set", pnum); + else + dbg_bld("first PEB %d is newer, copy_flag is set", pnum); + + return second_is_newer | (bitflips << 1) | (corrupted << 2); + +out_free_buf: + vfree(buf); +out_free_vidh: + ubi_free_vid_hdr(ubi, vh); + return err; +} + +/** + * ubi_add_to_av - add used physical eraseblock to the attaching information. + * @ubi: UBI device description object + * @ai: attaching information + * @pnum: the physical eraseblock number + * @ec: erase counter + * @vid_hdr: the volume identifier header + * @bitflips: if bit-flips were detected when this physical eraseblock was read + * + * This function adds information about a used physical eraseblock to the + * 'used' tree of the corresponding volume. The function is rather complex + * because it has to handle cases when this is not the first physical + * eraseblock belonging to the same logical eraseblock, and the newer one has + * to be picked, while the older one has to be dropped. This function returns + * zero in case of success and a negative error code in case of failure. + */ +int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, + int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) +{ + int err, vol_id, lnum; + unsigned long long sqnum; + struct ubi_ainf_volume *av; + struct ubi_ainf_peb *aeb; + struct rb_node **p, *parent = NULL; + + vol_id = be32_to_cpu(vid_hdr->vol_id); + lnum = be32_to_cpu(vid_hdr->lnum); + sqnum = be64_to_cpu(vid_hdr->sqnum); + + dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", + pnum, vol_id, lnum, ec, sqnum, bitflips); + + av = add_volume(ai, vol_id, pnum, vid_hdr); + if (IS_ERR(av)) + return PTR_ERR(av); + + if (ai->max_sqnum < sqnum) + ai->max_sqnum = sqnum; + + /* + * Walk the RB-tree of logical eraseblocks of volume @vol_id to look + * if this is the first instance of this logical eraseblock or not. + */ + p = &av->root.rb_node; + while (*p) { + int cmp_res; + + parent = *p; + aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); + if (lnum != aeb->lnum) { + if (lnum < aeb->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + continue; + } + + /* + * There is already a physical eraseblock describing the same + * logical eraseblock present. + */ + + dbg_bld("this LEB already exists: PEB %d, sqnum %llu, EC %d", + aeb->pnum, aeb->sqnum, aeb->ec); + + /* + * Make sure that the logical eraseblocks have different + * sequence numbers. Otherwise the image is bad. + * + * However, if the sequence number is zero, we assume it must + * be an ancient UBI image from the era when UBI did not have + * sequence numbers. We still can attach these images, unless + * there is a need to distinguish between old and new + * eraseblocks, in which case we'll refuse the image in + * 'compare_lebs()'. In other words, we attach old clean + * images, but refuse attaching old images with duplicated + * logical eraseblocks because there was an unclean reboot. + */ + if (aeb->sqnum == sqnum && sqnum != 0) { + ubi_err("two LEBs with same sequence number %llu", + sqnum); + ubi_dump_aeb(aeb, 0); + ubi_dump_vid_hdr(vid_hdr); + return -EINVAL; + } + + /* + * Now we have to drop the older one and preserve the newer + * one. + */ + cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr); + if (cmp_res < 0) + return cmp_res; + + if (cmp_res & 1) { + /* + * This logical eraseblock is newer than the one + * found earlier. + */ + err = validate_vid_hdr(vid_hdr, av, pnum); + if (err) + return err; + + err = add_to_list(ai, aeb->pnum, aeb->ec, cmp_res & 4, + &ai->erase); + if (err) + return err; + + aeb->ec = ec; + aeb->pnum = pnum; + aeb->scrub = ((cmp_res & 2) || bitflips); + aeb->copy_flag = vid_hdr->copy_flag; + aeb->sqnum = sqnum; + + if (av->highest_lnum == lnum) + av->last_data_size = + be32_to_cpu(vid_hdr->data_size); + + return 0; + } else { + /* + * This logical eraseblock is older than the one found + * previously. + */ + return add_to_list(ai, pnum, ec, cmp_res & 4, + &ai->erase); + } + } + + /* + * We've met this logical eraseblock for the first time, add it to the + * attaching information. + */ + + err = validate_vid_hdr(vid_hdr, av, pnum); + if (err) + return err; + + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); + if (!aeb) + return -ENOMEM; + + aeb->ec = ec; + aeb->pnum = pnum; + aeb->lnum = lnum; + aeb->scrub = bitflips; + aeb->copy_flag = vid_hdr->copy_flag; + aeb->sqnum = sqnum; + + if (av->highest_lnum <= lnum) { + av->highest_lnum = lnum; + av->last_data_size = be32_to_cpu(vid_hdr->data_size); + } + + av->leb_count += 1; + rb_link_node(&aeb->u.rb, parent, p); + rb_insert_color(&aeb->u.rb, &av->root); + return 0; +} + +/** + * ubi_find_av - find volume in the attaching information. + * @ai: attaching information + * @vol_id: the requested volume ID + * + * This function returns a pointer to the volume description or %NULL if there + * are no data about this volume in the attaching information. + */ +struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, + int vol_id) +{ + struct ubi_ainf_volume *av; + struct rb_node *p = ai->volumes.rb_node; + + while (p) { + av = rb_entry(p, struct ubi_ainf_volume, rb); + + if (vol_id == av->vol_id) + return av; + + if (vol_id > av->vol_id) + p = p->rb_left; + else + p = p->rb_right; + } + + return NULL; +} + +/** + * ubi_remove_av - delete attaching information about a volume. + * @ai: attaching information + * @av: the volume attaching information to delete + */ +void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) +{ + struct rb_node *rb; + struct ubi_ainf_peb *aeb; + + dbg_bld("remove attaching information about volume %d", av->vol_id); + + while ((rb = rb_first(&av->root))) { + aeb = rb_entry(rb, struct ubi_ainf_peb, u.rb); + rb_erase(&aeb->u.rb, &av->root); + list_add_tail(&aeb->u.list, &ai->erase); + } + + rb_erase(&av->rb, &ai->volumes); + kfree(av); + ai->vols_found -= 1; +} + +/** + * early_erase_peb - erase a physical eraseblock. + * @ubi: UBI device description object + * @ai: attaching information + * @pnum: physical eraseblock number to erase; + * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown) + * + * This function erases physical eraseblock 'pnum', and writes the erase + * counter header to it. This function should only be used on UBI device + * initialization stages, when the EBA sub-system had not been yet initialized. + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int early_erase_peb(struct ubi_device *ubi, + const struct ubi_attach_info *ai, int pnum, int ec) +{ + int err; + struct ubi_ec_hdr *ec_hdr; + + if ((long long)ec >= UBI_MAX_ERASECOUNTER) { + /* + * Erase counter overflow. Upgrade UBI and use 64-bit + * erase counters internally. + */ + ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec); + 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); + if (err < 0) + goto out_free; + + err = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); + +out_free: + kfree(ec_hdr); + return err; +} + +/** + * ubi_early_get_peb - get a free physical eraseblock. + * @ubi: UBI device description object + * @ai: attaching information + * + * This function returns a free physical eraseblock. It is supposed to be + * called on the UBI initialization stages when the wear-leveling sub-system is + * not initialized yet. This function picks a physical eraseblocks from one of + * the lists, writes the EC header if it is needed, and removes it from the + * list. + * + * This function returns a pointer to the "aeb" of the found free PEB in case + * of success and an error code in case of failure. + */ +struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, + struct ubi_attach_info *ai) +{ + int err = 0; + struct ubi_ainf_peb *aeb, *tmp_aeb; + + if (!list_empty(&ai->free)) { + aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list); + list_del(&aeb->u.list); + dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec); + return aeb; + } + + /* + * We try to erase the first physical eraseblock from the erase list + * and pick it if we succeed, or try to erase the next one if not. And + * so forth. We don't want to take care about bad eraseblocks here - + * they'll be handled later. + */ + list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { + if (aeb->ec == UBI_UNKNOWN) + aeb->ec = ai->mean_ec; + + err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); + if (err) + continue; + + aeb->ec += 1; + list_del(&aeb->u.list); + dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec); + return aeb; + } + + ubi_err("no free eraseblocks"); + return ERR_PTR(-ENOSPC); +} + +/** + * check_corruption - check the data area of PEB. + * @ubi: UBI device description object + * @vid_hrd: the (corrupted) VID header of this PEB + * @pnum: the physical eraseblock number to check + * + * This is a helper function which is used to distinguish between VID header + * corruptions caused by power cuts and other reasons. If the PEB contains only + * 0xFF bytes in the data area, the VID header is most probably corrupted + * because of a power cut (%0 is returned in this case). Otherwise, it was + * probably corrupted for some other reasons (%1 is returned in this case). A + * negative error code is returned if a read error occurred. + * + * If the corruption reason was a power cut, UBI can safely erase this PEB. + * Otherwise, it should preserve it to avoid possibly destroying important + * information. + */ +static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, + int pnum) +{ + int err; + + mutex_lock(&ubi->buf_mutex); + memset(ubi->peb_buf, 0x00, ubi->leb_size); + + err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start, + ubi->leb_size); + if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { + /* + * Bit-flips or integrity errors while reading the data area. + * It is difficult to say for sure what type of corruption is + * this, but presumably a power cut happened while this PEB was + * erased, so it became unstable and corrupted, and should be + * erased. + */ + err = 0; + goto out_unlock; + } + + if (err) + goto out_unlock; + + if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) + goto out_unlock; + + ubi_err("PEB %d contains corrupted VID header, and the data does not " + "contain all 0xFF, this may be a non-UBI PEB or a severe VID " + "header corruption which requires manual inspection", pnum); + ubi_dump_vid_hdr(vid_hdr); + dbg_msg("hexdump of PEB %d offset %d, length %d", + pnum, ubi->leb_start, ubi->leb_size); + ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ubi->peb_buf, ubi->leb_size, 1); + err = 1; + +out_unlock: + mutex_unlock(&ubi->buf_mutex); + return err; +} + +/** + * scan_peb - scan and process UBI headers of a PEB. + * @ubi: UBI device description object + * @ai: attaching information + * @pnum: the physical eraseblock number + * + * This function reads UBI headers of PEB @pnum, checks them, and adds + * information about this PEB to the corresponding list or RB-tree in the + * "attaching info" structure. Returns zero if the physical eraseblock was + * successfully handled and a negative error code in case of failure. + */ +static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, + int pnum) +{ + long long uninitialized_var(ec); + int err, bitflips = 0, vol_id, ec_err = 0; + + dbg_bld("scan PEB %d", pnum); + + /* Skip bad physical eraseblocks */ + err = ubi_io_is_bad(ubi, pnum); + if (err < 0) + return err; + else if (err) { + ai->bad_peb_count += 1; + return 0; + } + + err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); + if (err < 0) + return err; + switch (err) { + case 0: + break; + case UBI_IO_BITFLIPS: + bitflips = 1; + break; + case UBI_IO_FF: + ai->empty_peb_count += 1; + return add_to_list(ai, pnum, UBI_UNKNOWN, 0, + &ai->erase); + case UBI_IO_FF_BITFLIPS: + ai->empty_peb_count += 1; + return add_to_list(ai, pnum, UBI_UNKNOWN, 1, + &ai->erase); + case UBI_IO_BAD_HDR_EBADMSG: + case UBI_IO_BAD_HDR: + /* + * We have to also look at the VID header, possibly it is not + * corrupted. Set %bitflips flag in order to make this PEB be + * moved and EC be re-created. + */ + ec_err = err; + ec = UBI_UNKNOWN; + bitflips = 1; + break; + default: + ubi_err("'ubi_io_read_ec_hdr()' returned unknown code %d", err); + return -EINVAL; + } + + if (!ec_err) { + int image_seq; + + /* Make sure UBI version is OK */ + if (ech->version != UBI_VERSION) { + ubi_err("this UBI version is %d, image version is %d", + UBI_VERSION, (int)ech->version); + return -EINVAL; + } + + ec = be64_to_cpu(ech->ec); + if (ec > UBI_MAX_ERASECOUNTER) { + /* + * Erase counter overflow. The EC headers have 64 bits + * reserved, but we anyway make use of only 31 bit + * values, as this seems to be enough for any existing + * flash. Upgrade UBI and use 64-bit erase counters + * internally. + */ + ubi_err("erase counter overflow, max is %d", + UBI_MAX_ERASECOUNTER); + ubi_dump_ec_hdr(ech); + return -EINVAL; + } + + /* + * Make sure that all PEBs have the same image sequence number. + * This allows us to detect situations when users flash UBI + * images incorrectly, so that the flash has the new UBI image + * and leftovers from the old one. This feature was added + * relatively recently, and the sequence number was always + * zero, because old UBI implementations always set it to zero. + * For this reasons, we do not panic if some PEBs have zero + * sequence number, while other PEBs have non-zero sequence + * number. + */ + image_seq = be32_to_cpu(ech->image_seq); + if (!ubi->image_seq && image_seq) + ubi->image_seq = image_seq; + if (ubi->image_seq && image_seq && + ubi->image_seq != image_seq) { + ubi_err("bad image sequence number %d in PEB %d, " + "expected %d", image_seq, pnum, ubi->image_seq); + ubi_dump_ec_hdr(ech); + return -EINVAL; + } + } + + /* OK, we've done with the EC header, let's look at the VID header */ + + err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); + if (err < 0) + return err; + switch (err) { + case 0: + break; + case UBI_IO_BITFLIPS: + bitflips = 1; + break; + case UBI_IO_BAD_HDR_EBADMSG: + if (ec_err == UBI_IO_BAD_HDR_EBADMSG) + /* + * Both EC and VID headers are corrupted and were read + * with data integrity error, probably this is a bad + * PEB, bit it is not marked as bad yet. This may also + * be a result of power cut during erasure. + */ + ai->maybe_bad_peb_count += 1; + case UBI_IO_BAD_HDR: + if (ec_err) + /* + * Both headers are corrupted. There is a possibility + * that this a valid UBI PEB which has corresponding + * LEB, but the headers are corrupted. However, it is + * impossible to distinguish it from a PEB which just + * contains garbage because of a power cut during erase + * operation. So we just schedule this PEB for erasure. + * + * Besides, in case of NOR flash, we deliberately + * corrupt both headers because NOR flash erasure is + * slow and can start from the end. + */ + err = 0; + else + /* + * The EC was OK, but the VID header is corrupted. We + * have to check what is in the data area. + */ + err = check_corruption(ubi, vidh, pnum); + + if (err < 0) + return err; + else if (!err) + /* This corruption is caused by a power cut */ + err = add_to_list(ai, pnum, ec, 1, &ai->erase); + else + /* This is an unexpected corruption */ + err = add_corrupted(ai, pnum, ec); + if (err) + return err; + goto adjust_mean_ec; + case UBI_IO_FF_BITFLIPS: + err = add_to_list(ai, pnum, ec, 1, &ai->erase); + if (err) + return err; + goto adjust_mean_ec; + case UBI_IO_FF: + if (ec_err) + err = add_to_list(ai, pnum, ec, 1, &ai->erase); + else + err = add_to_list(ai, pnum, ec, 0, &ai->free); + if (err) + return err; + goto adjust_mean_ec; + default: + ubi_err("'ubi_io_read_vid_hdr()' returned unknown code %d", + err); + return -EINVAL; + } + + vol_id = be32_to_cpu(vidh->vol_id); + if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { + int lnum = be32_to_cpu(vidh->lnum); + + /* Unsupported internal volume */ + switch (vidh->compat) { + case UBI_COMPAT_DELETE: + ubi_msg("\"delete\" compatible internal volume %d:%d" + " found, will remove it", vol_id, lnum); + err = add_to_list(ai, pnum, ec, 1, &ai->erase); + if (err) + return err; + return 0; + + case UBI_COMPAT_RO: + ubi_msg("read-only compatible internal volume %d:%d" + " found, switch to read-only mode", + vol_id, lnum); + ubi->ro_mode = 1; + break; + + case UBI_COMPAT_PRESERVE: + ubi_msg("\"preserve\" compatible internal volume %d:%d" + " found", vol_id, lnum); + err = add_to_list(ai, pnum, ec, 0, &ai->alien); + if (err) + return err; + return 0; + + case UBI_COMPAT_REJECT: + ubi_err("incompatible internal volume %d:%d found", + vol_id, lnum); + return -EINVAL; + } + } + + if (ec_err) + ubi_warn("valid VID header but corrupted EC header at PEB %d", + pnum); + err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); + if (err) + return err; + +adjust_mean_ec: + if (!ec_err) { + ai->ec_sum += ec; + ai->ec_count += 1; + if (ec > ai->max_ec) + ai->max_ec = ec; + if (ec < ai->min_ec) + ai->min_ec = ec; + } + + return 0; +} + +/** + * late_analysis - analyze the overall situation with PEB. + * @ubi: UBI device description object + * @ai: attaching information + * + * This is a helper function which takes a look what PEBs we have after we + * gather information about all of them ("ai" is compete). It decides whether + * the flash is empty and should be formatted of whether there are too many + * corrupted PEBs and we should not attach this MTD device. Returns zero if we + * should proceed with attaching the MTD device, and %-EINVAL if we should not. + */ +static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) +{ + struct ubi_ainf_peb *aeb; + int max_corr, peb_count; + + peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count; + max_corr = peb_count / 20 ?: 8; + + /* + * Few corrupted PEBs is not a problem and may be just a result of + * unclean reboots. However, many of them may indicate some problems + * with the flash HW or driver. + */ + if (ai->corr_peb_count) { + ubi_err("%d PEBs are corrupted and preserved", + ai->corr_peb_count); + printk(KERN_ERR "Corrupted PEBs are:"); + list_for_each_entry(aeb, &ai->corr, u.list) + printk(KERN_CONT " %d", aeb->pnum); + printk(KERN_CONT "\n"); + + /* + * If too many PEBs are corrupted, we refuse attaching, + * otherwise, only print a warning. + */ + if (ai->corr_peb_count >= max_corr) { + ubi_err("too many corrupted PEBs, refusing"); + return -EINVAL; + } + } + + if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) { + /* + * All PEBs are empty, or almost all - a couple PEBs look like + * they may be bad PEBs which were not marked as bad yet. + * + * This piece of code basically tries to distinguish between + * the following situations: + * + * 1. Flash is empty, but there are few bad PEBs, which are not + * marked as bad so far, and which were read with error. We + * want to go ahead and format this flash. While formatting, + * the faulty PEBs will probably be marked as bad. + * + * 2. Flash contains non-UBI data and we do not want to format + * it and destroy possibly important information. + */ + if (ai->maybe_bad_peb_count <= 2) { + ai->is_empty = 1; + ubi_msg("empty MTD device detected"); + get_random_bytes(&ubi->image_seq, + sizeof(ubi->image_seq)); + } else { + ubi_err("MTD device is not UBI-formatted and possibly " + "contains non-UBI data - refusing it"); + return -EINVAL; + } + + } + + return 0; +} + +/** + * scan_all - scan entire MTD device. + * @ubi: UBI device description object + * + * This function does full scanning of an MTD device and returns complete + * information about it in form of a "struct ubi_attach_info" object. In case + * of failure, an error code is returned. + */ +static struct ubi_attach_info *scan_all(struct ubi_device *ubi) +{ + int err, pnum; + struct rb_node *rb1, *rb2; + struct ubi_ainf_volume *av; + struct ubi_ainf_peb *aeb; + struct ubi_attach_info *ai; + + ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + if (!ai) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; + + err = -ENOMEM; + ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) + goto out_ai; + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) + goto out_ai; + + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vidh) + goto out_ech; + + for (pnum = 0; pnum < ubi->peb_count; pnum++) { + cond_resched(); + + dbg_gen("process PEB %d", pnum); + err = scan_peb(ubi, ai, pnum); + if (err < 0) + goto out_vidh; + } + + dbg_msg("scanning is finished"); + + /* Calculate mean erase counter */ + if (ai->ec_count) + ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); + + err = late_analysis(ubi, ai); + if (err) + goto out_vidh; + + /* + * In case of unknown erase counter we use the mean erase counter + * value. + */ + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) + if (aeb->ec == UBI_UNKNOWN) + aeb->ec = ai->mean_ec; + } + + list_for_each_entry(aeb, &ai->free, u.list) { + if (aeb->ec == UBI_UNKNOWN) + aeb->ec = ai->mean_ec; + } + + list_for_each_entry(aeb, &ai->corr, u.list) + if (aeb->ec == UBI_UNKNOWN) + aeb->ec = ai->mean_ec; + + list_for_each_entry(aeb, &ai->erase, u.list) + if (aeb->ec == UBI_UNKNOWN) + aeb->ec = ai->mean_ec; + + err = self_check_ai(ubi, ai); + if (err) + goto out_vidh; + + ubi_free_vid_hdr(ubi, vidh); + kfree(ech); + + return ai; + +out_vidh: + ubi_free_vid_hdr(ubi, vidh); +out_ech: + kfree(ech); +out_ai: + ubi_destroy_ai(ai); + return ERR_PTR(err); +} + +/** + * ubi_attach - attach an MTD device. + * @ubi: UBI device descriptor + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_attach(struct ubi_device *ubi) +{ + int err; + struct ubi_attach_info *ai; + + ai = scan_all(ubi); + if (IS_ERR(ai)) + return PTR_ERR(ai); + + ubi->bad_peb_count = ai->bad_peb_count; + ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; + ubi->corr_peb_count = ai->corr_peb_count; + ubi->max_ec = ai->max_ec; + ubi->mean_ec = ai->mean_ec; + ubi_msg("max. sequence number: %llu", ai->max_sqnum); + + err = ubi_read_volume_table(ubi, ai); + if (err) + goto out_ai; + + err = ubi_wl_init(ubi, ai); + if (err) + goto out_vtbl; + + err = ubi_eba_init(ubi, ai); + if (err) + goto out_wl; + + ubi_destroy_ai(ai); + return 0; + +out_wl: + ubi_wl_close(ubi); +out_vtbl: + ubi_free_internal_volumes(ubi); + vfree(ubi->vtbl); +out_ai: + ubi_destroy_ai(ai); + return err; +} + +/** + * destroy_av - free volume attaching information. + * @av: volume attaching information + * @ai: attaching information + * + * This function destroys the volume attaching information. + */ +static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) +{ + struct ubi_ainf_peb *aeb; + struct rb_node *this = av->root.rb_node; + + while (this) { + if (this->rb_left) + this = this->rb_left; + else if (this->rb_right) + this = this->rb_right; + else { + aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &aeb->u.rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + } + kfree(av); +} + +/** + * ubi_destroy_ai - destroy attaching information. + * @ai: attaching information + */ +void ubi_destroy_ai(struct ubi_attach_info *ai) +{ + struct ubi_ainf_peb *aeb, *aeb_tmp; + struct ubi_ainf_volume *av; + struct rb_node *rb; + + list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + + /* Destroy the volume RB-tree */ + rb = ai->volumes.rb_node; + while (rb) { + if (rb->rb_left) + rb = rb->rb_left; + else if (rb->rb_right) + rb = rb->rb_right; + else { + av = rb_entry(rb, struct ubi_ainf_volume, rb); + + rb = rb_parent(rb); + if (rb) { + if (rb->rb_left == &av->rb) + rb->rb_left = NULL; + else + rb->rb_right = NULL; + } + + destroy_av(ai, av); + } + } + + if (ai->aeb_slab_cache) + kmem_cache_destroy(ai->aeb_slab_cache); + + kfree(ai); +} + +/** + * self_check_ai - check the attaching information. + * @ubi: UBI device description object + * @ai: attaching information + * + * This function returns zero if the attaching information is all right, and a + * negative error code if not or if an error occurred. + */ +static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) +{ + int pnum, err, vols_found = 0; + struct rb_node *rb1, *rb2; + struct ubi_ainf_volume *av; + struct ubi_ainf_peb *aeb, *last_aeb; + uint8_t *buf; + + if (!ubi->dbg->chk_gen) + return 0; + + /* + * At first, check that attaching information is OK. + */ + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { + int leb_count = 0; + + cond_resched(); + + vols_found += 1; + + if (ai->is_empty) { + ubi_err("bad is_empty flag"); + goto bad_av; + } + + if (av->vol_id < 0 || av->highest_lnum < 0 || + av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || + av->data_pad < 0 || av->last_data_size < 0) { + ubi_err("negative values"); + goto bad_av; + } + + if (av->vol_id >= UBI_MAX_VOLUMES && + av->vol_id < UBI_INTERNAL_VOL_START) { + ubi_err("bad vol_id"); + goto bad_av; + } + + if (av->vol_id > ai->highest_vol_id) { + ubi_err("highest_vol_id is %d, but vol_id %d is there", + ai->highest_vol_id, av->vol_id); + goto out; + } + + if (av->vol_type != UBI_DYNAMIC_VOLUME && + av->vol_type != UBI_STATIC_VOLUME) { + ubi_err("bad vol_type"); + goto bad_av; + } + + if (av->data_pad > ubi->leb_size / 2) { + ubi_err("bad data_pad"); + goto bad_av; + } + + last_aeb = NULL; + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { + cond_resched(); + + last_aeb = aeb; + leb_count += 1; + + if (aeb->pnum < 0 || aeb->ec < 0) { + ubi_err("negative values"); + goto bad_aeb; + } + + if (aeb->ec < ai->min_ec) { + ubi_err("bad ai->min_ec (%d), %d found", + ai->min_ec, aeb->ec); + goto bad_aeb; + } + + if (aeb->ec > ai->max_ec) { + ubi_err("bad ai->max_ec (%d), %d found", + ai->max_ec, aeb->ec); + goto bad_aeb; + } + + if (aeb->pnum >= ubi->peb_count) { + ubi_err("too high PEB number %d, total PEBs %d", + aeb->pnum, ubi->peb_count); + goto bad_aeb; + } + + if (av->vol_type == UBI_STATIC_VOLUME) { + if (aeb->lnum >= av->used_ebs) { + ubi_err("bad lnum or used_ebs"); + goto bad_aeb; + } + } else { + if (av->used_ebs != 0) { + ubi_err("non-zero used_ebs"); + goto bad_aeb; + } + } + + if (aeb->lnum > av->highest_lnum) { + ubi_err("incorrect highest_lnum or lnum"); + goto bad_aeb; + } + } + + if (av->leb_count != leb_count) { + ubi_err("bad leb_count, %d objects in the tree", + leb_count); + goto bad_av; + } + + if (!last_aeb) + continue; + + aeb = last_aeb; + + if (aeb->lnum != av->highest_lnum) { + ubi_err("bad highest_lnum"); + goto bad_aeb; + } + } + + if (vols_found != ai->vols_found) { + ubi_err("bad ai->vols_found %d, should be %d", + ai->vols_found, vols_found); + goto out; + } + + /* Check that attaching information is correct */ + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { + last_aeb = NULL; + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { + int vol_type; + + cond_resched(); + + last_aeb = aeb; + + err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidh, 1); + if (err && err != UBI_IO_BITFLIPS) { + ubi_err("VID header is not OK (%d)", err); + if (err > 0) + err = -EIO; + return err; + } + + vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? + UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; + if (av->vol_type != vol_type) { + ubi_err("bad vol_type"); + goto bad_vid_hdr; + } + + if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { + ubi_err("bad sqnum %llu", aeb->sqnum); + goto bad_vid_hdr; + } + + if (av->vol_id != be32_to_cpu(vidh->vol_id)) { + ubi_err("bad vol_id %d", av->vol_id); + goto bad_vid_hdr; + } + + if (av->compat != vidh->compat) { + ubi_err("bad compat %d", vidh->compat); + goto bad_vid_hdr; + } + + if (aeb->lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad lnum %d", aeb->lnum); + goto bad_vid_hdr; + } + + if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { + ubi_err("bad used_ebs %d", av->used_ebs); + goto bad_vid_hdr; + } + + if (av->data_pad != be32_to_cpu(vidh->data_pad)) { + ubi_err("bad data_pad %d", av->data_pad); + goto bad_vid_hdr; + } + } + + if (!last_aeb) + continue; + + if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad highest_lnum %d", av->highest_lnum); + goto bad_vid_hdr; + } + + if (av->last_data_size != be32_to_cpu(vidh->data_size)) { + ubi_err("bad last_data_size %d", av->last_data_size); + goto bad_vid_hdr; + } + } + + /* + * Make sure that all the physical eraseblocks are in one of the lists + * or trees. + */ + buf = kzalloc(ubi->peb_count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (pnum = 0; pnum < ubi->peb_count; pnum++) { + err = ubi_io_is_bad(ubi, pnum); + if (err < 0) { + kfree(buf); + return err; + } else if (err) + buf[pnum] = 1; + } + + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) + buf[aeb->pnum] = 1; + + list_for_each_entry(aeb, &ai->free, u.list) + buf[aeb->pnum] = 1; + + list_for_each_entry(aeb, &ai->corr, u.list) + buf[aeb->pnum] = 1; + + list_for_each_entry(aeb, &ai->erase, u.list) + buf[aeb->pnum] = 1; + + list_for_each_entry(aeb, &ai->alien, u.list) + buf[aeb->pnum] = 1; + + err = 0; + for (pnum = 0; pnum < ubi->peb_count; pnum++) + if (!buf[pnum]) { + ubi_err("PEB %d is not referred", pnum); + err = 1; + } + + kfree(buf); + if (err) + goto out; + return 0; + +bad_aeb: + ubi_err("bad attaching information about LEB %d", aeb->lnum); + ubi_dump_aeb(aeb, 0); + ubi_dump_av(av); + goto out; + +bad_av: + ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_dump_av(av); + goto out; + +bad_vid_hdr: + ubi_err("bad attaching information about volume %d", av->vol_id); + ubi_dump_av(av); + ubi_dump_vid_hdr(vidh); + +out: + dump_stack(); + return -EINVAL; +} diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c deleted file mode 100644 index 1f76859e2c58..000000000000 --- a/drivers/mtd/ubi/scan.c +++ /dev/null @@ -1,1615 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Artem Bityutskiy (Битюцкий Артём) - */ - -/* - * UBI attaching sub-system. - * - * This sub-system is responsible for attaching MTD devices and it also - * implements flash media scanning. - * - * The attaching information is represented by a &struct ubi_attach_info' - * object. Information about volumes is represented by &struct ubi_ainf_volume - * objects which are kept in volume RB-tree with root at the @volumes field. - * The RB-tree is indexed by the volume ID. - * - * Logical eraseblocks are represented by &struct ubi_ainf_peb objects. These - * objects are kept in per-volume RB-trees with the root at the corresponding - * &struct ubi_ainf_volume object. To put it differently, we keep an RB-tree of - * per-volume objects and each of these objects is the root of RB-tree of - * per-LEB objects. - * - * Corrupted physical eraseblocks are put to the @corr list, free physical - * eraseblocks are put to the @free list and the physical eraseblock to be - * erased are put to the @erase list. - * - * About corruptions - * ~~~~~~~~~~~~~~~~~ - * - * UBI protects EC and VID headers with CRC-32 checksums, so it can detect - * whether the headers are corrupted or not. Sometimes UBI also protects the - * data with CRC-32, e.g., when it executes the atomic LEB change operation, or - * when it moves the contents of a PEB for wear-leveling purposes. - * - * UBI tries to distinguish between 2 types of corruptions. - * - * 1. Corruptions caused by power cuts. These are expected corruptions and UBI - * tries to handle them gracefully, without printing too many warnings and - * error messages. The idea is that we do not lose important data in these - * cases - we may lose only the data which were being written to the media just - * before the power cut happened, and the upper layers (e.g., UBIFS) are - * supposed to handle such data losses (e.g., by using the FS journal). - * - * When UBI detects a corruption (CRC-32 mismatch) in a PEB, and it looks like - * the reason is a power cut, UBI puts this PEB to the @erase list, and all - * PEBs in the @erase list are scheduled for erasure later. - * - * 2. Unexpected corruptions which are not caused by power cuts. During - * attaching, such PEBs are put to the @corr list and UBI preserves them. - * Obviously, this lessens the amount of available PEBs, and if at some point - * UBI runs out of free PEBs, it switches to R/O mode. UBI also loudly informs - * about such PEBs every time the MTD device is attached. - * - * However, it is difficult to reliably distinguish between these types of - * corruptions and UBI's strategy is as follows (in case of attaching by - * scanning). UBI assumes corruption type 2 if the VID header is corrupted and - * the data area does not contain all 0xFFs, and there were no bit-flips or - * integrity errors (e.g., ECC errors in case of NAND) while reading the data - * area. Otherwise UBI assumes corruption type 1. So the decision criteria - * are as follows. - * o If the data area contains only 0xFFs, there are no data, and it is safe - * to just erase this PEB - this is corruption type 1. - * o If the data area has bit-flips or data integrity errors (ECC errors on - * NAND), it is probably a PEB which was being erased when power cut - * happened, so this is corruption type 1. However, this is just a guess, - * which might be wrong. - * o Otherwise this it corruption type 2. - */ - -#include -#include -#include -#include -#include -#include "ubi.h" - -static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai); - -/* Temporary variables used during scanning */ -static struct ubi_ec_hdr *ech; -static struct ubi_vid_hdr *vidh; - -/** - * add_to_list - add physical eraseblock to a list. - * @ai: attaching information - * @pnum: physical eraseblock number to add - * @ec: erase counter of the physical eraseblock - * @to_head: if not zero, add to the head of the list - * @list: the list to add to - * - * This function allocates a 'struct ubi_ainf_peb' object for physical - * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. - * If @to_head is not zero, PEB will be added to the head of the list, which - * basically means it will be processed first later. E.g., we add corrupted - * PEBs (corrupted due to power cuts) to the head of the erase list to make - * sure we erase them first and get rid of corruptions ASAP. This function - * returns zero in case of success and a negative error code in case of - * failure. - */ -static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, - int to_head, struct list_head *list) -{ - struct ubi_ainf_peb *aeb; - - if (list == &ai->free) { - dbg_bld("add to free: PEB %d, EC %d", pnum, ec); - } else if (list == &ai->erase) { - dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); - } else if (list == &ai->alien) { - dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); - ai->alien_peb_count += 1; - } else - BUG(); - - aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); - if (!aeb) - return -ENOMEM; - - aeb->pnum = pnum; - aeb->ec = ec; - if (to_head) - list_add(&aeb->u.list, list); - else - list_add_tail(&aeb->u.list, list); - return 0; -} - -/** - * add_corrupted - add a corrupted physical eraseblock. - * @ai: attaching information - * @pnum: physical eraseblock number to add - * @ec: erase counter of the physical eraseblock - * - * This function allocates a 'struct ubi_ainf_peb' object for a corrupted - * physical eraseblock @pnum and adds it to the 'corr' list. The corruption - * was presumably not caused by a power cut. Returns zero in case of success - * and a negative error code in case of failure. - */ -static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) -{ - struct ubi_ainf_peb *aeb; - - dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); - - aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); - if (!aeb) - return -ENOMEM; - - ai->corr_peb_count += 1; - aeb->pnum = pnum; - aeb->ec = ec; - list_add(&aeb->u.list, &ai->corr); - return 0; -} - -/** - * validate_vid_hdr - check volume identifier header. - * @vid_hdr: the volume identifier header to check - * @av: information about the volume this logical eraseblock belongs to - * @pnum: physical eraseblock number the VID header came from - * - * This function checks that data stored in @vid_hdr is consistent. Returns - * non-zero if an inconsistency was found and zero if not. - * - * Note, UBI does sanity check of everything it reads from the flash media. - * Most of the checks are done in the I/O sub-system. Here we check that the - * information in the VID header is consistent to the information in other VID - * headers of the same volume. - */ -static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, - const struct ubi_ainf_volume *av, int pnum) -{ - int vol_type = vid_hdr->vol_type; - int vol_id = be32_to_cpu(vid_hdr->vol_id); - int used_ebs = be32_to_cpu(vid_hdr->used_ebs); - int data_pad = be32_to_cpu(vid_hdr->data_pad); - - if (av->leb_count != 0) { - int av_vol_type; - - /* - * This is not the first logical eraseblock belonging to this - * volume. Ensure that the data in its VID header is consistent - * to the data in previous logical eraseblock headers. - */ - - if (vol_id != av->vol_id) { - ubi_err("inconsistent vol_id"); - goto bad; - } - - if (av->vol_type == UBI_STATIC_VOLUME) - av_vol_type = UBI_VID_STATIC; - else - av_vol_type = UBI_VID_DYNAMIC; - - if (vol_type != av_vol_type) { - ubi_err("inconsistent vol_type"); - goto bad; - } - - if (used_ebs != av->used_ebs) { - ubi_err("inconsistent used_ebs"); - goto bad; - } - - if (data_pad != av->data_pad) { - ubi_err("inconsistent data_pad"); - goto bad; - } - } - - return 0; - -bad: - ubi_err("inconsistent VID header at PEB %d", pnum); - ubi_dump_vid_hdr(vid_hdr); - ubi_dump_av(av); - return -EINVAL; -} - -/** - * add_volume - add volume to the attaching information. - * @ai: attaching information - * @vol_id: ID of the volume to add - * @pnum: physical eraseblock number - * @vid_hdr: volume identifier header - * - * If the volume corresponding to the @vid_hdr logical eraseblock is already - * present in the attaching information, this function does nothing. Otherwise - * it adds corresponding volume to the attaching information. Returns a pointer - * to the allocated "av" object in case of success and a negative error code in - * case of failure. - */ -static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, - int vol_id, int pnum, - const struct ubi_vid_hdr *vid_hdr) -{ - struct ubi_ainf_volume *av; - struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; - - ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); - - /* Walk the volume RB-tree to look if this volume is already present */ - while (*p) { - parent = *p; - av = rb_entry(parent, struct ubi_ainf_volume, rb); - - if (vol_id == av->vol_id) - return av; - - if (vol_id > av->vol_id) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - - /* The volume is absent - add it */ - av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); - if (!av) - return ERR_PTR(-ENOMEM); - - av->highest_lnum = av->leb_count = 0; - av->vol_id = vol_id; - av->root = RB_ROOT; - av->used_ebs = be32_to_cpu(vid_hdr->used_ebs); - av->data_pad = be32_to_cpu(vid_hdr->data_pad); - av->compat = vid_hdr->compat; - av->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME - : UBI_STATIC_VOLUME; - if (vol_id > ai->highest_vol_id) - ai->highest_vol_id = vol_id; - - rb_link_node(&av->rb, parent, p); - rb_insert_color(&av->rb, &ai->volumes); - ai->vols_found += 1; - dbg_bld("added volume %d", vol_id); - return av; -} - -/** - * compare_lebs - find out which logical eraseblock is newer. - * @ubi: UBI device description object - * @aeb: first logical eraseblock to compare - * @pnum: physical eraseblock number of the second logical eraseblock to - * compare - * @vid_hdr: volume identifier header of the second logical eraseblock - * - * This function compares 2 copies of a LEB and informs which one is newer. In - * case of success this function returns a positive value, in case of failure, a - * negative error code is returned. The success return codes use the following - * bits: - * o bit 0 is cleared: the first PEB (described by @aeb) is newer than the - * second PEB (described by @pnum and @vid_hdr); - * o bit 0 is set: the second PEB is newer; - * o bit 1 is cleared: no bit-flips were detected in the newer LEB; - * o bit 1 is set: bit-flips were detected in the newer LEB; - * o bit 2 is cleared: the older LEB is not corrupted; - * o bit 2 is set: the older LEB is corrupted. - */ -static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, - int pnum, const struct ubi_vid_hdr *vid_hdr) -{ - void *buf; - int len, err, second_is_newer, bitflips = 0, corrupted = 0; - uint32_t data_crc, crc; - struct ubi_vid_hdr *vh = NULL; - unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); - - if (sqnum2 == aeb->sqnum) { - /* - * This must be a really ancient UBI image which has been - * created before sequence numbers support has been added. At - * that times we used 32-bit LEB versions stored in logical - * eraseblocks. That was before UBI got into mainline. We do not - * support these images anymore. Well, those images still work, - * but only if no unclean reboots happened. - */ - ubi_err("unsupported on-flash UBI format\n"); - return -EINVAL; - } - - /* Obviously the LEB with lower sequence counter is older */ - second_is_newer = (sqnum2 > aeb->sqnum); - - /* - * Now we know which copy is newer. If the copy flag of the PEB with - * newer version is not set, then we just return, otherwise we have to - * check data CRC. For the second PEB we already have the VID header, - * for the first one - we'll need to re-read it from flash. - * - * Note: this may be optimized so that we wouldn't read twice. - */ - - if (second_is_newer) { - if (!vid_hdr->copy_flag) { - /* It is not a copy, so it is newer */ - dbg_bld("second PEB %d is newer, copy_flag is unset", - pnum); - return 1; - } - } else { - if (!aeb->copy_flag) { - /* It is not a copy, so it is newer */ - dbg_bld("first PEB %d is newer, copy_flag is unset", - pnum); - return bitflips << 1; - } - - vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); - if (!vh) - return -ENOMEM; - - pnum = aeb->pnum; - err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); - if (err) { - if (err == UBI_IO_BITFLIPS) - bitflips = 1; - else { - ubi_err("VID of PEB %d header is bad, but it " - "was OK earlier, err %d", pnum, err); - if (err > 0) - err = -EIO; - - goto out_free_vidh; - } - } - - vid_hdr = vh; - } - - /* Read the data of the copy and check the CRC */ - - len = be32_to_cpu(vid_hdr->data_size); - buf = vmalloc(len); - if (!buf) { - err = -ENOMEM; - goto out_free_vidh; - } - - err = ubi_io_read_data(ubi, buf, pnum, 0, len); - if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) - goto out_free_buf; - - data_crc = be32_to_cpu(vid_hdr->data_crc); - crc = crc32(UBI_CRC32_INIT, buf, len); - if (crc != data_crc) { - dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", - pnum, crc, data_crc); - corrupted = 1; - bitflips = 0; - second_is_newer = !second_is_newer; - } else { - dbg_bld("PEB %d CRC is OK", pnum); - bitflips = !!err; - } - - vfree(buf); - ubi_free_vid_hdr(ubi, vh); - - if (second_is_newer) - dbg_bld("second PEB %d is newer, copy_flag is set", pnum); - else - dbg_bld("first PEB %d is newer, copy_flag is set", pnum); - - return second_is_newer | (bitflips << 1) | (corrupted << 2); - -out_free_buf: - vfree(buf); -out_free_vidh: - ubi_free_vid_hdr(ubi, vh); - return err; -} - -/** - * ubi_add_to_av - add used physical eraseblock to the attaching information. - * @ubi: UBI device description object - * @ai: attaching information - * @pnum: the physical eraseblock number - * @ec: erase counter - * @vid_hdr: the volume identifier header - * @bitflips: if bit-flips were detected when this physical eraseblock was read - * - * This function adds information about a used physical eraseblock to the - * 'used' tree of the corresponding volume. The function is rather complex - * because it has to handle cases when this is not the first physical - * eraseblock belonging to the same logical eraseblock, and the newer one has - * to be picked, while the older one has to be dropped. This function returns - * zero in case of success and a negative error code in case of failure. - */ -int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, - int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips) -{ - int err, vol_id, lnum; - unsigned long long sqnum; - struct ubi_ainf_volume *av; - struct ubi_ainf_peb *aeb; - struct rb_node **p, *parent = NULL; - - vol_id = be32_to_cpu(vid_hdr->vol_id); - lnum = be32_to_cpu(vid_hdr->lnum); - sqnum = be64_to_cpu(vid_hdr->sqnum); - - dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, bitflips %d", - pnum, vol_id, lnum, ec, sqnum, bitflips); - - av = add_volume(ai, vol_id, pnum, vid_hdr); - if (IS_ERR(av)) - return PTR_ERR(av); - - if (ai->max_sqnum < sqnum) - ai->max_sqnum = sqnum; - - /* - * Walk the RB-tree of logical eraseblocks of volume @vol_id to look - * if this is the first instance of this logical eraseblock or not. - */ - p = &av->root.rb_node; - while (*p) { - int cmp_res; - - parent = *p; - aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); - if (lnum != aeb->lnum) { - if (lnum < aeb->lnum) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - continue; - } - - /* - * There is already a physical eraseblock describing the same - * logical eraseblock present. - */ - - dbg_bld("this LEB already exists: PEB %d, sqnum %llu, EC %d", - aeb->pnum, aeb->sqnum, aeb->ec); - - /* - * Make sure that the logical eraseblocks have different - * sequence numbers. Otherwise the image is bad. - * - * However, if the sequence number is zero, we assume it must - * be an ancient UBI image from the era when UBI did not have - * sequence numbers. We still can attach these images, unless - * there is a need to distinguish between old and new - * eraseblocks, in which case we'll refuse the image in - * 'compare_lebs()'. In other words, we attach old clean - * images, but refuse attaching old images with duplicated - * logical eraseblocks because there was an unclean reboot. - */ - if (aeb->sqnum == sqnum && sqnum != 0) { - ubi_err("two LEBs with same sequence number %llu", - sqnum); - ubi_dump_aeb(aeb, 0); - ubi_dump_vid_hdr(vid_hdr); - return -EINVAL; - } - - /* - * Now we have to drop the older one and preserve the newer - * one. - */ - cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr); - if (cmp_res < 0) - return cmp_res; - - if (cmp_res & 1) { - /* - * This logical eraseblock is newer than the one - * found earlier. - */ - err = validate_vid_hdr(vid_hdr, av, pnum); - if (err) - return err; - - err = add_to_list(ai, aeb->pnum, aeb->ec, cmp_res & 4, - &ai->erase); - if (err) - return err; - - aeb->ec = ec; - aeb->pnum = pnum; - aeb->scrub = ((cmp_res & 2) || bitflips); - aeb->copy_flag = vid_hdr->copy_flag; - aeb->sqnum = sqnum; - - if (av->highest_lnum == lnum) - av->last_data_size = - be32_to_cpu(vid_hdr->data_size); - - return 0; - } else { - /* - * This logical eraseblock is older than the one found - * previously. - */ - return add_to_list(ai, pnum, ec, cmp_res & 4, - &ai->erase); - } - } - - /* - * We've met this logical eraseblock for the first time, add it to the - * attaching information. - */ - - err = validate_vid_hdr(vid_hdr, av, pnum); - if (err) - return err; - - aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); - if (!aeb) - return -ENOMEM; - - aeb->ec = ec; - aeb->pnum = pnum; - aeb->lnum = lnum; - aeb->scrub = bitflips; - aeb->copy_flag = vid_hdr->copy_flag; - aeb->sqnum = sqnum; - - if (av->highest_lnum <= lnum) { - av->highest_lnum = lnum; - av->last_data_size = be32_to_cpu(vid_hdr->data_size); - } - - av->leb_count += 1; - rb_link_node(&aeb->u.rb, parent, p); - rb_insert_color(&aeb->u.rb, &av->root); - return 0; -} - -/** - * ubi_find_av - find volume in the attaching information. - * @ai: attaching information - * @vol_id: the requested volume ID - * - * This function returns a pointer to the volume description or %NULL if there - * are no data about this volume in the attaching information. - */ -struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, - int vol_id) -{ - struct ubi_ainf_volume *av; - struct rb_node *p = ai->volumes.rb_node; - - while (p) { - av = rb_entry(p, struct ubi_ainf_volume, rb); - - if (vol_id == av->vol_id) - return av; - - if (vol_id > av->vol_id) - p = p->rb_left; - else - p = p->rb_right; - } - - return NULL; -} - -/** - * ubi_remove_av - delete attaching information about a volume. - * @ai: attaching information - * @av: the volume attaching information to delete - */ -void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) -{ - struct rb_node *rb; - struct ubi_ainf_peb *aeb; - - dbg_bld("remove attaching information about volume %d", av->vol_id); - - while ((rb = rb_first(&av->root))) { - aeb = rb_entry(rb, struct ubi_ainf_peb, u.rb); - rb_erase(&aeb->u.rb, &av->root); - list_add_tail(&aeb->u.list, &ai->erase); - } - - rb_erase(&av->rb, &ai->volumes); - kfree(av); - ai->vols_found -= 1; -} - -/** - * early_erase_peb - erase a physical eraseblock. - * @ubi: UBI device description object - * @ai: attaching information - * @pnum: physical eraseblock number to erase; - * @ec: erase counter value to write (%UBI_UNKNOWN if it is unknown) - * - * This function erases physical eraseblock 'pnum', and writes the erase - * counter header to it. This function should only be used on UBI device - * initialization stages, when the EBA sub-system had not been yet initialized. - * This function returns zero in case of success and a negative error code in - * case of failure. - */ -static int early_erase_peb(struct ubi_device *ubi, - const struct ubi_attach_info *ai, int pnum, int ec) -{ - int err; - struct ubi_ec_hdr *ec_hdr; - - if ((long long)ec >= UBI_MAX_ERASECOUNTER) { - /* - * Erase counter overflow. Upgrade UBI and use 64-bit - * erase counters internally. - */ - ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec); - 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); - if (err < 0) - goto out_free; - - err = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); - -out_free: - kfree(ec_hdr); - return err; -} - -/** - * ubi_early_get_peb - get a free physical eraseblock. - * @ubi: UBI device description object - * @ai: attaching information - * - * This function returns a free physical eraseblock. It is supposed to be - * called on the UBI initialization stages when the wear-leveling sub-system is - * not initialized yet. This function picks a physical eraseblocks from one of - * the lists, writes the EC header if it is needed, and removes it from the - * list. - * - * This function returns a pointer to the "aeb" of the found free PEB in case - * of success and an error code in case of failure. - */ -struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, - struct ubi_attach_info *ai) -{ - int err = 0; - struct ubi_ainf_peb *aeb, *tmp_aeb; - - if (!list_empty(&ai->free)) { - aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list); - list_del(&aeb->u.list); - dbg_bld("return free PEB %d, EC %d", aeb->pnum, aeb->ec); - return aeb; - } - - /* - * We try to erase the first physical eraseblock from the erase list - * and pick it if we succeed, or try to erase the next one if not. And - * so forth. We don't want to take care about bad eraseblocks here - - * they'll be handled later. - */ - list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { - if (aeb->ec == UBI_UNKNOWN) - aeb->ec = ai->mean_ec; - - err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); - if (err) - continue; - - aeb->ec += 1; - list_del(&aeb->u.list); - dbg_bld("return PEB %d, EC %d", aeb->pnum, aeb->ec); - return aeb; - } - - ubi_err("no free eraseblocks"); - return ERR_PTR(-ENOSPC); -} - -/** - * check_corruption - check the data area of PEB. - * @ubi: UBI device description object - * @vid_hrd: the (corrupted) VID header of this PEB - * @pnum: the physical eraseblock number to check - * - * This is a helper function which is used to distinguish between VID header - * corruptions caused by power cuts and other reasons. If the PEB contains only - * 0xFF bytes in the data area, the VID header is most probably corrupted - * because of a power cut (%0 is returned in this case). Otherwise, it was - * probably corrupted for some other reasons (%1 is returned in this case). A - * negative error code is returned if a read error occurred. - * - * If the corruption reason was a power cut, UBI can safely erase this PEB. - * Otherwise, it should preserve it to avoid possibly destroying important - * information. - */ -static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, - int pnum) -{ - int err; - - mutex_lock(&ubi->buf_mutex); - memset(ubi->peb_buf, 0x00, ubi->leb_size); - - err = ubi_io_read(ubi, ubi->peb_buf, pnum, ubi->leb_start, - ubi->leb_size); - if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { - /* - * Bit-flips or integrity errors while reading the data area. - * It is difficult to say for sure what type of corruption is - * this, but presumably a power cut happened while this PEB was - * erased, so it became unstable and corrupted, and should be - * erased. - */ - err = 0; - goto out_unlock; - } - - if (err) - goto out_unlock; - - if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) - goto out_unlock; - - ubi_err("PEB %d contains corrupted VID header, and the data does not " - "contain all 0xFF, this may be a non-UBI PEB or a severe VID " - "header corruption which requires manual inspection", pnum); - ubi_dump_vid_hdr(vid_hdr); - dbg_msg("hexdump of PEB %d offset %d, length %d", - pnum, ubi->leb_start, ubi->leb_size); - ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, - ubi->peb_buf, ubi->leb_size, 1); - err = 1; - -out_unlock: - mutex_unlock(&ubi->buf_mutex); - return err; -} - -/** - * scan_peb - scan and process UBI headers of a PEB. - * @ubi: UBI device description object - * @ai: attaching information - * @pnum: the physical eraseblock number - * - * This function reads UBI headers of PEB @pnum, checks them, and adds - * information about this PEB to the corresponding list or RB-tree in the - * "attaching info" structure. Returns zero if the physical eraseblock was - * successfully handled and a negative error code in case of failure. - */ -static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, - int pnum) -{ - long long uninitialized_var(ec); - int err, bitflips = 0, vol_id, ec_err = 0; - - dbg_bld("scan PEB %d", pnum); - - /* Skip bad physical eraseblocks */ - err = ubi_io_is_bad(ubi, pnum); - if (err < 0) - return err; - else if (err) { - ai->bad_peb_count += 1; - return 0; - } - - err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); - if (err < 0) - return err; - switch (err) { - case 0: - break; - case UBI_IO_BITFLIPS: - bitflips = 1; - break; - case UBI_IO_FF: - ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_UNKNOWN, 0, - &ai->erase); - case UBI_IO_FF_BITFLIPS: - ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_UNKNOWN, 1, - &ai->erase); - case UBI_IO_BAD_HDR_EBADMSG: - case UBI_IO_BAD_HDR: - /* - * We have to also look at the VID header, possibly it is not - * corrupted. Set %bitflips flag in order to make this PEB be - * moved and EC be re-created. - */ - ec_err = err; - ec = UBI_UNKNOWN; - bitflips = 1; - break; - default: - ubi_err("'ubi_io_read_ec_hdr()' returned unknown code %d", err); - return -EINVAL; - } - - if (!ec_err) { - int image_seq; - - /* Make sure UBI version is OK */ - if (ech->version != UBI_VERSION) { - ubi_err("this UBI version is %d, image version is %d", - UBI_VERSION, (int)ech->version); - return -EINVAL; - } - - ec = be64_to_cpu(ech->ec); - if (ec > UBI_MAX_ERASECOUNTER) { - /* - * Erase counter overflow. The EC headers have 64 bits - * reserved, but we anyway make use of only 31 bit - * values, as this seems to be enough for any existing - * flash. Upgrade UBI and use 64-bit erase counters - * internally. - */ - ubi_err("erase counter overflow, max is %d", - UBI_MAX_ERASECOUNTER); - ubi_dump_ec_hdr(ech); - return -EINVAL; - } - - /* - * Make sure that all PEBs have the same image sequence number. - * This allows us to detect situations when users flash UBI - * images incorrectly, so that the flash has the new UBI image - * and leftovers from the old one. This feature was added - * relatively recently, and the sequence number was always - * zero, because old UBI implementations always set it to zero. - * For this reasons, we do not panic if some PEBs have zero - * sequence number, while other PEBs have non-zero sequence - * number. - */ - image_seq = be32_to_cpu(ech->image_seq); - if (!ubi->image_seq && image_seq) - ubi->image_seq = image_seq; - if (ubi->image_seq && image_seq && - ubi->image_seq != image_seq) { - ubi_err("bad image sequence number %d in PEB %d, " - "expected %d", image_seq, pnum, ubi->image_seq); - ubi_dump_ec_hdr(ech); - return -EINVAL; - } - } - - /* OK, we've done with the EC header, let's look at the VID header */ - - err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); - if (err < 0) - return err; - switch (err) { - case 0: - break; - case UBI_IO_BITFLIPS: - bitflips = 1; - break; - case UBI_IO_BAD_HDR_EBADMSG: - if (ec_err == UBI_IO_BAD_HDR_EBADMSG) - /* - * Both EC and VID headers are corrupted and were read - * with data integrity error, probably this is a bad - * PEB, bit it is not marked as bad yet. This may also - * be a result of power cut during erasure. - */ - ai->maybe_bad_peb_count += 1; - case UBI_IO_BAD_HDR: - if (ec_err) - /* - * Both headers are corrupted. There is a possibility - * that this a valid UBI PEB which has corresponding - * LEB, but the headers are corrupted. However, it is - * impossible to distinguish it from a PEB which just - * contains garbage because of a power cut during erase - * operation. So we just schedule this PEB for erasure. - * - * Besides, in case of NOR flash, we deliberately - * corrupt both headers because NOR flash erasure is - * slow and can start from the end. - */ - err = 0; - else - /* - * The EC was OK, but the VID header is corrupted. We - * have to check what is in the data area. - */ - err = check_corruption(ubi, vidh, pnum); - - if (err < 0) - return err; - else if (!err) - /* This corruption is caused by a power cut */ - err = add_to_list(ai, pnum, ec, 1, &ai->erase); - else - /* This is an unexpected corruption */ - err = add_corrupted(ai, pnum, ec); - if (err) - return err; - goto adjust_mean_ec; - case UBI_IO_FF_BITFLIPS: - err = add_to_list(ai, pnum, ec, 1, &ai->erase); - if (err) - return err; - goto adjust_mean_ec; - case UBI_IO_FF: - if (ec_err) - err = add_to_list(ai, pnum, ec, 1, &ai->erase); - else - err = add_to_list(ai, pnum, ec, 0, &ai->free); - if (err) - return err; - goto adjust_mean_ec; - default: - ubi_err("'ubi_io_read_vid_hdr()' returned unknown code %d", - err); - return -EINVAL; - } - - vol_id = be32_to_cpu(vidh->vol_id); - if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { - int lnum = be32_to_cpu(vidh->lnum); - - /* Unsupported internal volume */ - switch (vidh->compat) { - case UBI_COMPAT_DELETE: - ubi_msg("\"delete\" compatible internal volume %d:%d" - " found, will remove it", vol_id, lnum); - err = add_to_list(ai, pnum, ec, 1, &ai->erase); - if (err) - return err; - return 0; - - case UBI_COMPAT_RO: - ubi_msg("read-only compatible internal volume %d:%d" - " found, switch to read-only mode", - vol_id, lnum); - ubi->ro_mode = 1; - break; - - case UBI_COMPAT_PRESERVE: - ubi_msg("\"preserve\" compatible internal volume %d:%d" - " found", vol_id, lnum); - err = add_to_list(ai, pnum, ec, 0, &ai->alien); - if (err) - return err; - return 0; - - case UBI_COMPAT_REJECT: - ubi_err("incompatible internal volume %d:%d found", - vol_id, lnum); - return -EINVAL; - } - } - - if (ec_err) - ubi_warn("valid VID header but corrupted EC header at PEB %d", - pnum); - err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); - if (err) - return err; - -adjust_mean_ec: - if (!ec_err) { - ai->ec_sum += ec; - ai->ec_count += 1; - if (ec > ai->max_ec) - ai->max_ec = ec; - if (ec < ai->min_ec) - ai->min_ec = ec; - } - - return 0; -} - -/** - * late_analysis - analyze the overall situation with PEB. - * @ubi: UBI device description object - * @ai: attaching information - * - * This is a helper function which takes a look what PEBs we have after we - * gather information about all of them ("ai" is compete). It decides whether - * the flash is empty and should be formatted of whether there are too many - * corrupted PEBs and we should not attach this MTD device. Returns zero if we - * should proceed with attaching the MTD device, and %-EINVAL if we should not. - */ -static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) -{ - struct ubi_ainf_peb *aeb; - int max_corr, peb_count; - - peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count; - max_corr = peb_count / 20 ?: 8; - - /* - * Few corrupted PEBs is not a problem and may be just a result of - * unclean reboots. However, many of them may indicate some problems - * with the flash HW or driver. - */ - if (ai->corr_peb_count) { - ubi_err("%d PEBs are corrupted and preserved", - ai->corr_peb_count); - printk(KERN_ERR "Corrupted PEBs are:"); - list_for_each_entry(aeb, &ai->corr, u.list) - printk(KERN_CONT " %d", aeb->pnum); - printk(KERN_CONT "\n"); - - /* - * If too many PEBs are corrupted, we refuse attaching, - * otherwise, only print a warning. - */ - if (ai->corr_peb_count >= max_corr) { - ubi_err("too many corrupted PEBs, refusing"); - return -EINVAL; - } - } - - if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) { - /* - * All PEBs are empty, or almost all - a couple PEBs look like - * they may be bad PEBs which were not marked as bad yet. - * - * This piece of code basically tries to distinguish between - * the following situations: - * - * 1. Flash is empty, but there are few bad PEBs, which are not - * marked as bad so far, and which were read with error. We - * want to go ahead and format this flash. While formatting, - * the faulty PEBs will probably be marked as bad. - * - * 2. Flash contains non-UBI data and we do not want to format - * it and destroy possibly important information. - */ - if (ai->maybe_bad_peb_count <= 2) { - ai->is_empty = 1; - ubi_msg("empty MTD device detected"); - get_random_bytes(&ubi->image_seq, - sizeof(ubi->image_seq)); - } else { - ubi_err("MTD device is not UBI-formatted and possibly " - "contains non-UBI data - refusing it"); - return -EINVAL; - } - - } - - return 0; -} - -/** - * scan_all - scan entire MTD device. - * @ubi: UBI device description object - * - * This function does full scanning of an MTD device and returns complete - * information about it in form of a "struct ubi_attach_info" object. In case - * of failure, an error code is returned. - */ -static struct ubi_attach_info *scan_all(struct ubi_device *ubi) -{ - int err, pnum; - struct rb_node *rb1, *rb2; - struct ubi_ainf_volume *av; - struct ubi_ainf_peb *aeb; - struct ubi_attach_info *ai; - - ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); - if (!ai) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; - - err = -ENOMEM; - ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) - goto out_ai; - - ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); - if (!ech) - goto out_ai; - - vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); - if (!vidh) - goto out_ech; - - for (pnum = 0; pnum < ubi->peb_count; pnum++) { - cond_resched(); - - dbg_gen("process PEB %d", pnum); - err = scan_peb(ubi, ai, pnum); - if (err < 0) - goto out_vidh; - } - - dbg_msg("scanning is finished"); - - /* Calculate mean erase counter */ - if (ai->ec_count) - ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); - - err = late_analysis(ubi, ai); - if (err) - goto out_vidh; - - /* - * In case of unknown erase counter we use the mean erase counter - * value. - */ - ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { - ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) - if (aeb->ec == UBI_UNKNOWN) - aeb->ec = ai->mean_ec; - } - - list_for_each_entry(aeb, &ai->free, u.list) { - if (aeb->ec == UBI_UNKNOWN) - aeb->ec = ai->mean_ec; - } - - list_for_each_entry(aeb, &ai->corr, u.list) - if (aeb->ec == UBI_UNKNOWN) - aeb->ec = ai->mean_ec; - - list_for_each_entry(aeb, &ai->erase, u.list) - if (aeb->ec == UBI_UNKNOWN) - aeb->ec = ai->mean_ec; - - err = self_check_ai(ubi, ai); - if (err) - goto out_vidh; - - ubi_free_vid_hdr(ubi, vidh); - kfree(ech); - - return ai; - -out_vidh: - ubi_free_vid_hdr(ubi, vidh); -out_ech: - kfree(ech); -out_ai: - ubi_destroy_ai(ai); - return ERR_PTR(err); -} - -/** - * ubi_attach - attach an MTD device. - * @ubi: UBI device descriptor - * - * This function returns zero in case of success and a negative error code in - * case of failure. - */ -int ubi_attach(struct ubi_device *ubi) -{ - int err; - struct ubi_attach_info *ai; - - ai = scan_all(ubi); - if (IS_ERR(ai)) - return PTR_ERR(ai); - - ubi->bad_peb_count = ai->bad_peb_count; - ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; - ubi->corr_peb_count = ai->corr_peb_count; - ubi->max_ec = ai->max_ec; - ubi->mean_ec = ai->mean_ec; - ubi_msg("max. sequence number: %llu", ai->max_sqnum); - - err = ubi_read_volume_table(ubi, ai); - if (err) - goto out_ai; - - err = ubi_wl_init(ubi, ai); - if (err) - goto out_vtbl; - - err = ubi_eba_init(ubi, ai); - if (err) - goto out_wl; - - ubi_destroy_ai(ai); - return 0; - -out_wl: - ubi_wl_close(ubi); -out_vtbl: - ubi_free_internal_volumes(ubi); - vfree(ubi->vtbl); -out_ai: - ubi_destroy_ai(ai); - return err; -} - -/** - * destroy_av - free volume attaching information. - * @av: volume attaching information - * @ai: attaching information - * - * This function destroys the volume attaching information. - */ -static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) -{ - struct ubi_ainf_peb *aeb; - struct rb_node *this = av->root.rb_node; - - while (this) { - if (this->rb_left) - this = this->rb_left; - else if (this->rb_right) - this = this->rb_right; - else { - aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); - this = rb_parent(this); - if (this) { - if (this->rb_left == &aeb->u.rb) - this->rb_left = NULL; - else - this->rb_right = NULL; - } - - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - } - kfree(av); -} - -/** - * ubi_destroy_ai - destroy attaching information. - * @ai: attaching information - */ -void ubi_destroy_ai(struct ubi_attach_info *ai) -{ - struct ubi_ainf_peb *aeb, *aeb_tmp; - struct ubi_ainf_volume *av; - struct rb_node *rb; - - list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - - /* Destroy the volume RB-tree */ - rb = ai->volumes.rb_node; - while (rb) { - if (rb->rb_left) - rb = rb->rb_left; - else if (rb->rb_right) - rb = rb->rb_right; - else { - av = rb_entry(rb, struct ubi_ainf_volume, rb); - - rb = rb_parent(rb); - if (rb) { - if (rb->rb_left == &av->rb) - rb->rb_left = NULL; - else - rb->rb_right = NULL; - } - - destroy_av(ai, av); - } - } - - if (ai->aeb_slab_cache) - kmem_cache_destroy(ai->aeb_slab_cache); - - kfree(ai); -} - -/** - * self_check_ai - check the attaching information. - * @ubi: UBI device description object - * @ai: attaching information - * - * This function returns zero if the attaching information is all right, and a - * negative error code if not or if an error occurred. - */ -static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) -{ - int pnum, err, vols_found = 0; - struct rb_node *rb1, *rb2; - struct ubi_ainf_volume *av; - struct ubi_ainf_peb *aeb, *last_aeb; - uint8_t *buf; - - if (!ubi->dbg->chk_gen) - return 0; - - /* - * At first, check that attaching information is OK. - */ - ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { - int leb_count = 0; - - cond_resched(); - - vols_found += 1; - - if (ai->is_empty) { - ubi_err("bad is_empty flag"); - goto bad_av; - } - - if (av->vol_id < 0 || av->highest_lnum < 0 || - av->leb_count < 0 || av->vol_type < 0 || av->used_ebs < 0 || - av->data_pad < 0 || av->last_data_size < 0) { - ubi_err("negative values"); - goto bad_av; - } - - if (av->vol_id >= UBI_MAX_VOLUMES && - av->vol_id < UBI_INTERNAL_VOL_START) { - ubi_err("bad vol_id"); - goto bad_av; - } - - if (av->vol_id > ai->highest_vol_id) { - ubi_err("highest_vol_id is %d, but vol_id %d is there", - ai->highest_vol_id, av->vol_id); - goto out; - } - - if (av->vol_type != UBI_DYNAMIC_VOLUME && - av->vol_type != UBI_STATIC_VOLUME) { - ubi_err("bad vol_type"); - goto bad_av; - } - - if (av->data_pad > ubi->leb_size / 2) { - ubi_err("bad data_pad"); - goto bad_av; - } - - last_aeb = NULL; - ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { - cond_resched(); - - last_aeb = aeb; - leb_count += 1; - - if (aeb->pnum < 0 || aeb->ec < 0) { - ubi_err("negative values"); - goto bad_aeb; - } - - if (aeb->ec < ai->min_ec) { - ubi_err("bad ai->min_ec (%d), %d found", - ai->min_ec, aeb->ec); - goto bad_aeb; - } - - if (aeb->ec > ai->max_ec) { - ubi_err("bad ai->max_ec (%d), %d found", - ai->max_ec, aeb->ec); - goto bad_aeb; - } - - if (aeb->pnum >= ubi->peb_count) { - ubi_err("too high PEB number %d, total PEBs %d", - aeb->pnum, ubi->peb_count); - goto bad_aeb; - } - - if (av->vol_type == UBI_STATIC_VOLUME) { - if (aeb->lnum >= av->used_ebs) { - ubi_err("bad lnum or used_ebs"); - goto bad_aeb; - } - } else { - if (av->used_ebs != 0) { - ubi_err("non-zero used_ebs"); - goto bad_aeb; - } - } - - if (aeb->lnum > av->highest_lnum) { - ubi_err("incorrect highest_lnum or lnum"); - goto bad_aeb; - } - } - - if (av->leb_count != leb_count) { - ubi_err("bad leb_count, %d objects in the tree", - leb_count); - goto bad_av; - } - - if (!last_aeb) - continue; - - aeb = last_aeb; - - if (aeb->lnum != av->highest_lnum) { - ubi_err("bad highest_lnum"); - goto bad_aeb; - } - } - - if (vols_found != ai->vols_found) { - ubi_err("bad ai->vols_found %d, should be %d", - ai->vols_found, vols_found); - goto out; - } - - /* Check that attaching information is correct */ - ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { - last_aeb = NULL; - ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) { - int vol_type; - - cond_resched(); - - last_aeb = aeb; - - err = ubi_io_read_vid_hdr(ubi, aeb->pnum, vidh, 1); - if (err && err != UBI_IO_BITFLIPS) { - ubi_err("VID header is not OK (%d)", err); - if (err > 0) - err = -EIO; - return err; - } - - vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? - UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; - if (av->vol_type != vol_type) { - ubi_err("bad vol_type"); - goto bad_vid_hdr; - } - - if (aeb->sqnum != be64_to_cpu(vidh->sqnum)) { - ubi_err("bad sqnum %llu", aeb->sqnum); - goto bad_vid_hdr; - } - - if (av->vol_id != be32_to_cpu(vidh->vol_id)) { - ubi_err("bad vol_id %d", av->vol_id); - goto bad_vid_hdr; - } - - if (av->compat != vidh->compat) { - ubi_err("bad compat %d", vidh->compat); - goto bad_vid_hdr; - } - - if (aeb->lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad lnum %d", aeb->lnum); - goto bad_vid_hdr; - } - - if (av->used_ebs != be32_to_cpu(vidh->used_ebs)) { - ubi_err("bad used_ebs %d", av->used_ebs); - goto bad_vid_hdr; - } - - if (av->data_pad != be32_to_cpu(vidh->data_pad)) { - ubi_err("bad data_pad %d", av->data_pad); - goto bad_vid_hdr; - } - } - - if (!last_aeb) - continue; - - if (av->highest_lnum != be32_to_cpu(vidh->lnum)) { - ubi_err("bad highest_lnum %d", av->highest_lnum); - goto bad_vid_hdr; - } - - if (av->last_data_size != be32_to_cpu(vidh->data_size)) { - ubi_err("bad last_data_size %d", av->last_data_size); - goto bad_vid_hdr; - } - } - - /* - * Make sure that all the physical eraseblocks are in one of the lists - * or trees. - */ - buf = kzalloc(ubi->peb_count, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - for (pnum = 0; pnum < ubi->peb_count; pnum++) { - err = ubi_io_is_bad(ubi, pnum); - if (err < 0) { - kfree(buf); - return err; - } else if (err) - buf[pnum] = 1; - } - - ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) - ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) - buf[aeb->pnum] = 1; - - list_for_each_entry(aeb, &ai->free, u.list) - buf[aeb->pnum] = 1; - - list_for_each_entry(aeb, &ai->corr, u.list) - buf[aeb->pnum] = 1; - - list_for_each_entry(aeb, &ai->erase, u.list) - buf[aeb->pnum] = 1; - - list_for_each_entry(aeb, &ai->alien, u.list) - buf[aeb->pnum] = 1; - - err = 0; - for (pnum = 0; pnum < ubi->peb_count; pnum++) - if (!buf[pnum]) { - ubi_err("PEB %d is not referred", pnum); - err = 1; - } - - kfree(buf); - if (err) - goto out; - return 0; - -bad_aeb: - ubi_err("bad attaching information about LEB %d", aeb->lnum); - ubi_dump_aeb(aeb, 0); - ubi_dump_av(av); - goto out; - -bad_av: - ubi_err("bad attaching information about volume %d", av->vol_id); - ubi_dump_av(av); - goto out; - -bad_vid_hdr: - ubi_err("bad attaching information about volume %d", av->vol_id); - ubi_dump_av(av); - ubi_dump_vid_hdr(vidh); - -out: - dump_stack(); - return -EINVAL; -} -- cgit v1.2.3 From b1fdcbd51bef532d540a86bef305068796b2ae35 Mon Sep 17 00:00:00 2001 From: Joel Reardon Date: Sun, 20 May 2012 13:42:29 +0200 Subject: UBI: add in hex the value for UBI_INTERNAL_VOL_START to comment Explicitly provide the first internal volume ID value in the comment for UBI_INTERNAL_VOL_START. This allows developers who, when adding features related to volume ids and observe unexpected very large volume ids, to grep for the observed value in the source code and find out immediately that it is expected behaviour. Signed-off-by: Joel Reardon Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi-media.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 07cd88f2b203..468ffbc0eabd 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h @@ -298,8 +298,8 @@ struct ubi_vid_hdr { #define UBI_INT_VOL_COUNT 1 /* - * Starting ID of internal volumes. There is reserved room for 4096 internal - * volumes. + * Starting ID of internal volumes: 0x7fffefff. + * There is reserved room for 4096 internal volumes. */ #define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) -- cgit v1.2.3 From 03c0b2b2136a4530529c6a98138945ecf682337b Mon Sep 17 00:00:00 2001 From: Joel Reardon Date: Wed, 16 May 2012 14:20:56 +0200 Subject: UBI: add volume id struct ubi_ainf_peb This patch adds the volume id to struct ubi_ainf_peb when scanning the LEBs at startup. PEBs now added to the erase queue will know their original LEB number and volume id, if available, and will be -1 otherwise (for instance, if the VID header is unreadable). This was tested by creating an ubi device with 3 volumes and disabiling the ubi_thread's do_work functionality. The different ubi volumes were formatted to ubifs and had files created and erased. The ubi modules was reloaded and the list of LEB's added to the erased list was outputted, confirming the volume ids and LEB numbers were appropriate. Signed-off-by: Joel Reardon Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 46 +++++++++++++++++++++++++++++++--------------- drivers/mtd/ubi/ubi.h | 5 ++++- 2 files changed, 35 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 1f76859e2c58..efdbd98b64f2 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -99,12 +99,16 @@ static struct ubi_vid_hdr *vidh; * add_to_list - add physical eraseblock to a list. * @ai: attaching information * @pnum: physical eraseblock number to add + * @vol_id: the last used volume id for the PEB + * @lnum: the last used LEB number for the PEB * @ec: erase counter of the physical eraseblock * @to_head: if not zero, add to the head of the list * @list: the list to add to * * This function allocates a 'struct ubi_ainf_peb' object for physical * eraseblock @pnum and adds it to the "free", "erase", or "alien" lists. + * It stores the @lnum and @vol_id alongside, which can both be + * %UBI_UNKNOWN if they are not available, not readable, or not assigned. * If @to_head is not zero, PEB will be added to the head of the list, which * basically means it will be processed first later. E.g., we add corrupted * PEBs (corrupted due to power cuts) to the head of the erase list to make @@ -112,8 +116,8 @@ static struct ubi_vid_hdr *vidh; * returns zero in case of success and a negative error code in case of * failure. */ -static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, - int to_head, struct list_head *list) +static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id, + int lnum, int ec, int to_head, struct list_head *list) { struct ubi_ainf_peb *aeb; @@ -132,6 +136,8 @@ static int add_to_list(struct ubi_attach_info *ai, int pnum, int ec, return -ENOMEM; aeb->pnum = pnum; + aeb->vol_id = vol_id; + aeb->lnum = lnum; aeb->ec = ec; if (to_head) list_add(&aeb->u.list, list); @@ -530,13 +536,16 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, if (err) return err; - err = add_to_list(ai, aeb->pnum, aeb->ec, cmp_res & 4, + err = add_to_list(ai, aeb->pnum, aeb->vol_id, + aeb->lnum, aeb->ec, cmp_res & 4, &ai->erase); if (err) return err; aeb->ec = ec; aeb->pnum = pnum; + aeb->vol_id = vol_id; + aeb->lnum = lnum; aeb->scrub = ((cmp_res & 2) || bitflips); aeb->copy_flag = vid_hdr->copy_flag; aeb->sqnum = sqnum; @@ -551,8 +560,8 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * This logical eraseblock is older than the one found * previously. */ - return add_to_list(ai, pnum, ec, cmp_res & 4, - &ai->erase); + return add_to_list(ai, pnum, vol_id, lnum, ec, + cmp_res & 4, &ai->erase); } } @@ -571,6 +580,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, aeb->ec = ec; aeb->pnum = pnum; + aeb->vol_id = vol_id; aeb->lnum = lnum; aeb->scrub = bitflips; aeb->copy_flag = vid_hdr->copy_flag; @@ -834,12 +844,12 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, break; case UBI_IO_FF: ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_UNKNOWN, 0, - &ai->erase); + return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, + UBI_UNKNOWN, 0, &ai->erase); case UBI_IO_FF_BITFLIPS: ai->empty_peb_count += 1; - return add_to_list(ai, pnum, UBI_UNKNOWN, 1, - &ai->erase); + return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, + UBI_UNKNOWN, 1, &ai->erase); case UBI_IO_BAD_HDR_EBADMSG: case UBI_IO_BAD_HDR: /* @@ -950,7 +960,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; else if (!err) /* This corruption is caused by a power cut */ - err = add_to_list(ai, pnum, ec, 1, &ai->erase); + err = add_to_list(ai, pnum, UBI_UNKNOWN, + UBI_UNKNOWN, ec, 1, &ai->erase); else /* This is an unexpected corruption */ err = add_corrupted(ai, pnum, ec); @@ -958,15 +969,18 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; goto adjust_mean_ec; case UBI_IO_FF_BITFLIPS: - err = add_to_list(ai, pnum, ec, 1, &ai->erase); + err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, + ec, 1, &ai->erase); if (err) return err; goto adjust_mean_ec; case UBI_IO_FF: if (ec_err) - err = add_to_list(ai, pnum, ec, 1, &ai->erase); + err = add_to_list(ai, pnum, UBI_UNKNOWN, + UBI_UNKNOWN, ec, 1, &ai->erase); else - err = add_to_list(ai, pnum, ec, 0, &ai->free); + err = add_to_list(ai, pnum, UBI_UNKNOWN, + UBI_UNKNOWN, ec, 0, &ai->free); if (err) return err; goto adjust_mean_ec; @@ -985,7 +999,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, case UBI_COMPAT_DELETE: ubi_msg("\"delete\" compatible internal volume %d:%d" " found, will remove it", vol_id, lnum); - err = add_to_list(ai, pnum, ec, 1, &ai->erase); + err = add_to_list(ai, pnum, vol_id, lnum, + ec, 1, &ai->erase); if (err) return err; return 0; @@ -1000,7 +1015,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, case UBI_COMPAT_PRESERVE: ubi_msg("\"preserve\" compatible internal volume %d:%d" " found", vol_id, lnum); - err = add_to_list(ai, pnum, ec, 0, &ai->alien); + err = add_to_list(ai, pnum, vol_id, lnum, + ec, 0, &ai->alien); if (err) return err; return 0; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 52756327827a..b4b3913f1df4 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -483,6 +483,7 @@ struct ubi_device { * struct ubi_ainf_peb - attach information about a physical eraseblock. * @ec: erase counter (%UBI_UNKNOWN if it is unknown) * @pnum: physical eraseblock number + * @vol_id: ID of the volume this LEB belongs to * @lnum: logical eraseblock number * @scrub: if this physical eraseblock needs scrubbing * @copy_flag: this LEB is a copy (@copy_flag is set in VID header of this LEB) @@ -492,11 +493,13 @@ struct ubi_device { * @u.list: link in one of the eraseblock lists * * One object of this type is allocated for each physical eraseblock when - * attaching an MTD device. + * attaching an MTD device. Note, if this PEB does not belong to any LEB / + * volume, the @vol_id and @lnum fields are initialized to %UBI_UNKNOWN. */ struct ubi_ainf_peb { int ec; int pnum; + int vol_id; int lnum; unsigned int scrub:1; unsigned int copy_flag:1; -- cgit v1.2.3 From 4d4a91e82585eca5890454ce46931f615410cd1f Mon Sep 17 00:00:00 2001 From: Joel Reardon Date: Fri, 18 May 2012 15:40:24 +0200 Subject: UBI: add lnum and vol_id to struct ubi_work This is part of a multipart patch to allow UBI to force the erasure of particular logical eraseblock numbers. In this patch, the volume id and LEB number are added to ubi_work data structure, and both are also passed as a parameter to schedule erase to set it appropriately. Whenever ubi_wl_put_peb is called, the lnum is also passed to be forwarded to schedule erase. Later, a new ubi_sync_lnum will be added to execute immediately all work related to that lnum. This was tested by outputting the vol_id and lnum during the schedule of erasure. The ubi thread was disabled and two ubifs drives on separate partitions repeated changed a small number of LEBs. The ubi module was readded, and all the erased LEBs, corresponding to the volumes, were added to the schedule erase queue. Artem: minor tweaks Signed-off-by: Joel Reardon Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 16 ++++++++-------- drivers/mtd/ubi/ubi.h | 3 ++- drivers/mtd/ubi/wl.c | 32 +++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index f167a346bad9..385b1f0dd73f 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -341,7 +341,7 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; - err = ubi_wl_put_peb(ubi, pnum, 0); + err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); out_unlock: leb_write_unlock(ubi, vol_id, lnum); @@ -550,7 +550,7 @@ retry: ubi_free_vid_hdr(ubi, vid_hdr); vol->eba_tbl[lnum] = new_pnum; - ubi_wl_put_peb(ubi, pnum, 1); + ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); ubi_msg("data was successfully recovered"); return 0; @@ -558,7 +558,7 @@ retry: out_unlock: mutex_unlock(&ubi->buf_mutex); out_put: - ubi_wl_put_peb(ubi, new_pnum, 1); + ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -568,7 +568,7 @@ write_error: * get another one. */ ubi_warn("failed to write to PEB %d", new_pnum); - ubi_wl_put_peb(ubi, new_pnum, 1); + ubi_wl_put_peb(ubi, vol_id, lnum, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -686,7 +686,7 @@ write_error: * eraseblock, so just put it and request a new one. We assume that if * this physical eraseblock went bad, the erase code will handle that. */ - err = ubi_wl_put_peb(ubi, pnum, 1); + err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); @@ -804,7 +804,7 @@ write_error: return err; } - err = ubi_wl_put_peb(ubi, pnum, 1); + err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); @@ -901,7 +901,7 @@ retry: } if (vol->eba_tbl[lnum] >= 0) { - err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 0); + err = ubi_wl_put_peb(ubi, vol_id, lnum, vol->eba_tbl[lnum], 0); if (err) goto out_leb_unlock; } @@ -926,7 +926,7 @@ write_error: goto out_leb_unlock; } - err = ubi_wl_put_peb(ubi, pnum, 1); + err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); goto out_leb_unlock; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index b4b3913f1df4..5e1182ca289b 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -667,7 +667,8 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); /* wl.c */ int ubi_wl_get_peb(struct ubi_device *ubi); -int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); +int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, + int pnum, int torture); int ubi_wl_flush(struct ubi_device *ubi); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index c143e6112357..70ebfa7bc384 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -140,6 +140,8 @@ * @list: a link in the list of pending works * @func: worker function * @e: physical eraseblock to erase + * @vol_id: the volume ID on which this erasure is being performed + * @lnum: the logical eraseblock number * @torture: if the physical eraseblock has to be tortured * * The @func pointer points to the worker function. If the @cancel argument is @@ -152,6 +154,8 @@ struct ubi_work { int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); /* The below fields are only relevant to erasure works */ struct ubi_wl_entry *e; + int vol_id; + int lnum; int torture; }; @@ -579,13 +583,15 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, * schedule_erase - schedule an erase work. * @ubi: UBI device description object * @e: the WL entry of the physical eraseblock to erase + * @vol_id: the volume ID that last used this PEB + * @lnum: the last used logical eraseblock number for the PEB * @torture: if the physical eraseblock has to be tortured * * This function returns zero in case of success and a %-ENOMEM in case of * failure. */ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, - int torture) + int vol_id, int lnum, int torture) { struct ubi_work *wl_wrk; @@ -598,6 +604,8 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, wl_wrk->func = &erase_worker; wl_wrk->e = e; + wl_wrk->vol_id = vol_id; + wl_wrk->lnum = lnum; wl_wrk->torture = torture; schedule_ubi_work(ubi, wl_wrk); @@ -798,7 +806,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi->move_to_put = ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); - err = schedule_erase(ubi, e1, 0); + err = schedule_erase(ubi, e1, vol_id, lnum, 0); if (err) { kmem_cache_free(ubi_wl_entry_slab, e1); if (e2) @@ -813,7 +821,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, */ dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", e2->pnum, vol_id, lnum); - err = schedule_erase(ubi, e2, 0); + err = schedule_erase(ubi, e2, vol_id, lnum, 0); if (err) { kmem_cache_free(ubi_wl_entry_slab, e2); goto out_ro; @@ -852,7 +860,7 @@ out_not_moved: spin_unlock(&ubi->wl_lock); ubi_free_vid_hdr(ubi, vid_hdr); - err = schedule_erase(ubi, e2, torture); + err = schedule_erase(ubi, e2, vol_id, lnum, torture); if (err) { kmem_cache_free(ubi_wl_entry_slab, e2); goto out_ro; @@ -971,6 +979,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, { struct ubi_wl_entry *e = wl_wrk->e; int pnum = e->pnum, err, need; + int vol_id = wl_wrk->vol_id; + int lnum = wl_wrk->lnum; if (cancel) { dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); @@ -979,7 +989,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, return 0; } - dbg_wl("erase PEB %d EC %d", pnum, e->ec); + dbg_wl("erase PEB %d EC %d LEB %d:%d", + pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); err = sync_erase(ubi, e, wl_wrk->torture); if (!err) { @@ -1009,7 +1020,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, int err1; /* Re-schedule the LEB for erasure */ - err1 = schedule_erase(ubi, e, 0); + err1 = schedule_erase(ubi, e, vol_id, lnum, 0); if (err1) { err = err1; goto out_ro; @@ -1077,6 +1088,8 @@ out_ro: /** * ubi_wl_put_peb - return a PEB to the wear-leveling sub-system. * @ubi: UBI device description object + * @vol_id: the volume ID that last used this PEB + * @lnum: the last used logical eraseblock number for the PEB * @pnum: physical eraseblock to return * @torture: if this physical eraseblock has to be tortured * @@ -1085,7 +1098,8 @@ out_ro: * occurred to this @pnum and it has to be tested. This function returns zero * in case of success, and a negative error code in case of failure. */ -int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) +int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, + int pnum, int torture) { int err; struct ubi_wl_entry *e; @@ -1151,7 +1165,7 @@ retry: } spin_unlock(&ubi->wl_lock); - err = schedule_erase(ubi, e, torture); + err = schedule_erase(ubi, e, vol_id, lnum, torture); if (err) { spin_lock(&ubi->wl_lock); wl_tree_add(e, &ubi->used); @@ -1416,7 +1430,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; ubi->lookuptbl[e->pnum] = e; - if (schedule_erase(ubi, e, 0)) { + if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) { kmem_cache_free(ubi_wl_entry_slab, e); goto out_free; } -- cgit v1.2.3 From cc1dd2d091b1882375f0a02b7c7d88cba128dc69 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 20 May 2012 21:14:22 +0300 Subject: UBI: introduce UBI_ALL constant Joel will use it in his 'ubi_flush()' extention to specify all eraseblocks. Also amend the comment for UBI_UNKNOWN - it is used beyond attaching info structure now. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 5e1182ca289b..38cfb0f2adf2 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -65,7 +65,10 @@ /* Background thread name pattern */ #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" -/* This marker in the EBA table means that the LEB is um-mapped */ +/* + * This marker in the EBA table means that the LEB is um-mapped. + * NOTE! It has to have the same value as %UBI_ALL. + */ #define UBI_LEB_UNMAPPED -1 /* @@ -81,10 +84,7 @@ */ #define UBI_PROT_QUEUE_LEN 10 -/* - * When a field of the attaching information has this value - its real value is - * unknown. - */ +/* The volume ID/LEB number/erase counter is unknown */ #define UBI_UNKNOWN -1 /* -- cgit v1.2.3 From a9259de54e6a20c840ebdb08b0383e01bc4877df Mon Sep 17 00:00:00 2001 From: Joel Reardon Date: Sun, 20 May 2012 21:27:11 +0200 Subject: UBI: modify ubi_wl_flush function to clear work queue for a lnum This patch modifies ubi_wl_flush to force the erasure of particular volume id / logical eraseblock number pairs. Previous functionality is preserved when passing UBI_ALL for both values. The locations where ubi_wl_flush were called are appropriately changed: ubi_leb_erase only flushes for the erased LEB, and ubi_create_volume forces only flushing for its volume id. External code can call this new feature via the new function ubi_flush() added to kapi.c, which simply passes through to ubi_wl_flush(). This was tested by disabling the call to do_work in ubi thread, which results in the work queue remaining unless explicitly called to remove. UBIFS was changed to call ubifs_leb_change 50 times for four different LEBs. Then the new function was called to clear the queue: passing wrong volume ids / lnum, correct ones, and finally UBI_ALL for both to ensure it was finally all cleard. The work queue was dumped each time and the selective removal of the particular LEB numbers was observed. Extra checks were enabled and ubifs's integck was also run. Finally, the drive was repeatedly filled and emptied to ensure that the queue was cleared normally. Artem: amended the patch. Signed-off-by: Joel Reardon Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 2 +- drivers/mtd/ubi/kapi.c | 29 +++++++++++++++++++++++- drivers/mtd/ubi/ubi.h | 2 +- drivers/mtd/ubi/upd.c | 4 ++-- drivers/mtd/ubi/vmt.c | 2 +- drivers/mtd/ubi/wl.c | 61 +++++++++++++++++++++++++++++--------------------- 6 files changed, 69 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 2364c00f66d0..acec85deb6af 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -514,7 +514,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, if (err) break; - err = ubi_wl_flush(ubi); + err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); break; } diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 2edcba3d7cf3..0a2b16b43b3f 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -551,7 +551,7 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) if (err) return err; - return ubi_wl_flush(ubi); + return ubi_wl_flush(ubi, vol->vol_id, lnum); } EXPORT_SYMBOL_GPL(ubi_leb_erase); @@ -706,6 +706,33 @@ int ubi_sync(int ubi_num) } EXPORT_SYMBOL_GPL(ubi_sync); +/** + * ubi_flush - flush UBI work queue. + * @ubi_num: UBI device to flush work queue + * @vol_id: volume id to flush for + * @lnum: logical eraseblock number to flush for + * + * This function executes all pending works for a particular volume id / logical + * eraseblock number pair. If either value is set to %UBI_ALL, then it acts as + * a wildcard for all of the corresponding volume numbers or logical + * eraseblock numbers. It returns zero in case of success and a negative error + * code in case of failure. + */ +int ubi_flush(int ubi_num, int vol_id, int lnum) +{ + struct ubi_device *ubi; + int err = 0; + + ubi = ubi_get_device(ubi_num); + if (!ubi) + return -ENODEV; + + err = ubi_wl_flush(ubi, vol_id, lnum); + ubi_put_device(ubi); + return err; +} +EXPORT_SYMBOL_GPL(ubi_flush); + BLOCKING_NOTIFIER_HEAD(ubi_notifiers); /** diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 38cfb0f2adf2..a1a81c9ea8ce 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -669,7 +669,7 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); int ubi_wl_get_peb(struct ubi_device *ubi); int ubi_wl_put_peb(struct ubi_device *ubi, int vol_id, int lnum, int pnum, int torture); -int ubi_wl_flush(struct ubi_device *ubi); +int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); void ubi_wl_close(struct ubi_device *ubi); diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 11a28f9ce0db..9f2ebd8750e7 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -147,7 +147,7 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, } if (bytes == 0) { - err = ubi_wl_flush(ubi); + err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); if (err) return err; @@ -361,7 +361,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, ubi_assert(vol->upd_received <= vol->upd_bytes); if (vol->upd_received == vol->upd_bytes) { - err = ubi_wl_flush(ubi); + err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); if (err) return err; /* The update is finished, clear the update marker */ diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 192140566b72..f0457c6c40f2 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -279,7 +279,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) * Finish all pending erases because there may be some LEBs belonging * to the same volume ID. */ - err = ubi_wl_flush(ubi); + err = ubi_wl_flush(ubi, vol_id, UBI_ALL); if (err) goto out_acc; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 70ebfa7bc384..9df100a4ec38 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1241,44 +1241,55 @@ retry: /** * ubi_wl_flush - flush all pending works. * @ubi: UBI device description object + * @vol_id: the volume id to flush for + * @lnum: the logical eraseblock number to flush for * - * This function returns zero in case of success and a negative error code in - * case of failure. + * This function executes all pending works for a particular volume id / + * logical eraseblock number pair. If either value is set to %UBI_ALL, then it + * acts as a wildcard for all of the corresponding volume numbers or logical + * eraseblock numbers. It returns zero in case of success and a negative error + * code in case of failure. */ -int ubi_wl_flush(struct ubi_device *ubi) +int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) { - int err; + int err = 0; + int found = 1; /* * Erase while the pending works queue is not empty, but not more than * the number of currently pending works. */ - dbg_wl("flush (%d pending works)", ubi->works_count); - while (ubi->works_count) { - err = do_work(ubi); - if (err) - return err; - } + dbg_wl("flush pending work for LEB %d:%d (%d pending works)", + vol_id, lnum, ubi->works_count); - /* - * Make sure all the works which have been done in parallel are - * finished. - */ down_write(&ubi->work_sem); - up_write(&ubi->work_sem); + while (found) { + struct ubi_work *wrk; + found = 0; - /* - * And in case last was the WL worker and it canceled the LEB - * movement, flush again. - */ - while (ubi->works_count) { - dbg_wl("flush more (%d pending works)", ubi->works_count); - err = do_work(ubi); - if (err) - return err; + spin_lock(&ubi->wl_lock); + list_for_each_entry(wrk, &ubi->works, list) { + if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && + (lnum == UBI_ALL || wrk->lnum == lnum)) { + list_del(&wrk->list); + ubi->works_count -= 1; + ubi_assert(ubi->works_count >= 0); + spin_unlock(&ubi->wl_lock); + + err = wrk->func(ubi, wrk, 0); + if (err) + goto out; + spin_lock(&ubi->wl_lock); + found = 1; + break; + } + } + spin_unlock(&ubi->wl_lock); } - return 0; +out: + up_write(&ubi->work_sem); + return err; } /** -- cgit v1.2.3 From 6a05c0160284b8427cec5248950ee33b49009060 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 6 Jun 2012 15:22:41 +0300 Subject: UBI: fix debugfs-less systems support Commit "aa44d1d UBI: remove Kconfig debugging option" broke UBI and it refuses to initialize if debugfs (CONFIG_DEBUG_FS) is disabled. I incorrectly assumed that debugfs files creation function will return success if debugfs is disabled, but they actually return -ENODEV. This patch fixes the issue. Reported-by: Paul Parsons Signed-off-by: Artem Bityutskiy Tested-by: Paul Parsons --- drivers/mtd/ubi/debug.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index d8411f814ce3..8026e9ab29c7 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,6 +264,9 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { + if (!IS_ENABLED(DEBUG_FS)) + return 0; + dfs_rootdir = debugfs_create_dir("ubi", NULL); if (IS_ERR_OR_NULL(dfs_rootdir)) { int err = dfs_rootdir ? -ENODEV : PTR_ERR(dfs_rootdir); @@ -281,7 +284,8 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - debugfs_remove(dfs_rootdir); + if (IS_ENABLED(DEBUG_FS)) + debugfs_remove(dfs_rootdir); } /* Read an UBI debugfs file */ @@ -411,6 +415,9 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; + if (!IS_ENABLED(DEBUG_FS)) + return 0; + n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, ubi->ubi_num); if (n == UBI_DFS_DIR_LEN) { @@ -478,5 +485,6 @@ out: */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - debugfs_remove_recursive(ubi->dbg->dfs_dir); + if (IS_ENABLED(DEBUG_FS)) + debugfs_remove_recursive(ubi->dbg->dfs_dir); } -- cgit v1.2.3 From b86e992800f48eeb391f383de73424e459a4b906 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 7 Jun 2012 15:15:30 +0300 Subject: UBI: correct ubi_wl_flush locking Commit "62f38455 UBI: modify ubi_wl_flush function to clear work queue for a lnum" takes the 'work_sem' semaphore in write mode for the entire loop, which is not very good because it will block other workers for potentially long time. We do not need to have it in write mode - read mode is enough, and we do not need to hole it over the entire loop. So this patch turns changes the locking: takes 'work_sem' in read mode and pushes it down to the loop. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 9df100a4ec38..b6be644e7b85 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1262,11 +1262,11 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) dbg_wl("flush pending work for LEB %d:%d (%d pending works)", vol_id, lnum, ubi->works_count); - down_write(&ubi->work_sem); while (found) { struct ubi_work *wrk; found = 0; + down_read(&ubi->work_sem); spin_lock(&ubi->wl_lock); list_for_each_entry(wrk, &ubi->works, list) { if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && @@ -1277,18 +1277,27 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) spin_unlock(&ubi->wl_lock); err = wrk->func(ubi, wrk, 0); - if (err) - goto out; + if (err) { + up_read(&ubi->work_sem); + return err; + } + spin_lock(&ubi->wl_lock); found = 1; break; } } spin_unlock(&ubi->wl_lock); + up_read(&ubi->work_sem); } -out: + /* + * Make sure all the works which have been done in parallel are + * finished. + */ + down_write(&ubi->work_sem); up_write(&ubi->work_sem); + return err; } -- cgit v1.2.3 From 52719b477383c6de4360ebf08aa957f5fb9287da Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 18 Jun 2012 16:31:23 -0700 Subject: UBI: correct usage of IS_ENABLED() Commit "e9b4cf2 UBI: fix debugfs-less systems support" fixed one regression but introduced a different regression - the debugfs is now always compiled out. Root cause: IS_ENABLED() arguments should be used with the CONFIG_* prefix. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 8026e9ab29c7..2da10ea51eec 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,7 +264,7 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; dfs_rootdir = debugfs_create_dir("ubi", NULL); @@ -284,7 +284,7 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove(dfs_rootdir); } @@ -415,7 +415,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, @@ -485,6 +485,6 @@ out: */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(ubi->dbg->dfs_dir); } -- cgit v1.2.3 From e69ed16744857ef261f653a36370170322c4fe2e Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 29 Jun 2012 08:57:41 +0200 Subject: UBI: Change the default percentage of reserved PEB The actual value (1%) is too low for actual NAND devices, a huge majority of device has 2% maximum bad blocks (SLC or MLC). (Actually it's 20 blocks on a 1024 blocks device, 40/2048...) Signed-off-by: Richard Genoud --- drivers/mtd/ubi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 738ee8dc16cd..ea4b95b5451c 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -29,7 +29,7 @@ config MTD_UBI_WL_THRESHOLD config MTD_UBI_BEB_RESERVE int "Percentage of reserved eraseblocks for bad eraseblocks handling" - default 1 + default 2 range 0 25 help If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI -- cgit v1.2.3 From ac7d84f8b9153ad04aaac35a976dac6183475c36 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 2 Jul 2012 23:38:17 +0200 Subject: UBI: fix spelling of detach in debug output Signed-off-by: Peter Meerwald Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index acec85deb6af..fb5567878181 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1026,7 +1026,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, { int ubi_num; - dbg_gen("dettach MTD device"); + dbg_gen("detach MTD device"); err = get_user(ubi_num, (__user int32_t *)argp); if (err) { err = -EFAULT; -- cgit v1.2.3 From 4ea91040b913458bfc8b029d1cc549d709bfce20 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 4 Jul 2012 11:06:03 +0300 Subject: UBI: trivial: fix comment of ubi_calculate_reserved function The function name within the comment was not aligned with the actual function name. Signed-off-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index ff2a65c37f69..a5fc0212e304 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -92,7 +92,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id) } /** - * ubi_calculate_rsvd_pool - calculate how many PEBs must be reserved for bad + * ubi_calculate_reserved - calculate how many PEBs must be reserved for bad * eraseblock handling. * @ubi: UBI device description object */ -- cgit v1.2.3 From 01d4ce763595a6b4ce9177bc5698345dbd6f44d9 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 4 Jul 2012 11:06:04 +0300 Subject: UBI: harmonize the update of ubi->beb_rsvd_pebs Currently, there are several locations where an attempt to reserve more PEBs for bad PEB handling is made, with the same code being duplicated. Harmonize it by introducing 'ubi_update_reserved()'. Also, improve the debug message issued, making it more descriptive. Artem: amended the patch a little. Signed-off-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/misc.c | 23 +++++++++++++++++++++++ drivers/mtd/ubi/ubi.h | 1 + drivers/mtd/ubi/vmt.c | 20 ++------------------ 3 files changed, 26 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index a5fc0212e304..c587ee150fff 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -91,6 +91,29 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id) return err; } +/** + * ubi_update_reserved - update bad eraseblock handling accounting data. + * @ubi: UBI device description object + * + * This function calculates the gap between current number of PEBs reserved for + * bad eraseblock handling and the required level of PEBs that must be + * reserved, and if necessary, reserves more PEBs to fill that gap, according + * to availability. Should be called with ubi->volumes_lock held. + */ +void ubi_update_reserved(struct ubi_device *ubi) +{ + int need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; + + if (need <= 0 || ubi->avail_pebs == 0) + return; + + need = min_t(int, need, ubi->avail_pebs); + ubi->avail_pebs -= need; + ubi->rsvd_pebs += need; + ubi->beb_rsvd_pebs += need; + ubi_msg("reserved more %d PEBs for bad PEB handling", need); +} + /** * ubi_calculate_reserved - calculate how many PEBs must be reserved for bad * eraseblock handling. diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index a1a81c9ea8ce..84f66e3fa05d 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -647,6 +647,7 @@ int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, int length); int ubi_check_volume(struct ubi_device *ubi, int vol_id); +void ubi_update_reserved(struct ubi_device *ubi); void ubi_calculate_reserved(struct ubi_device *ubi); int ubi_check_pattern(const void *buf, uint8_t patt, int size); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index f0457c6c40f2..04ba8bc7f1ca 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -442,15 +442,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs -= reserved_pebs; ubi->avail_pebs += reserved_pebs; - i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; - if (i > 0) { - i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; - ubi->avail_pebs -= i; - ubi->rsvd_pebs += i; - ubi->beb_rsvd_pebs += i; - if (i > 0) - ubi_msg("reserve more %d PEBs", i); - } + ubi_update_reserved(ubi); ubi->vol_count -= 1; spin_unlock(&ubi->volumes_lock); @@ -557,15 +549,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs += pebs; ubi->avail_pebs -= pebs; - pebs = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; - if (pebs > 0) { - pebs = ubi->avail_pebs >= pebs ? pebs : ubi->avail_pebs; - ubi->avail_pebs -= pebs; - ubi->rsvd_pebs += pebs; - ubi->beb_rsvd_pebs += pebs; - if (pebs > 0) - ubi_msg("reserve more %d PEBs", pebs); - } + ubi_update_reserved(ubi); for (i = 0; i < reserved_pebs; i++) new_mapping[i] = vol->eba_tbl[i]; kfree(vol->eba_tbl); -- cgit v1.2.3 From ec0ca60ab4521bcbfc9e4c35cfdef120079544f4 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 Jan 2012 00:06:03 -0800 Subject: mtd: m25p80: set writebufsize Using UBI on m25p80 can give messages like: UBI error: io_init: bad write buffer size 0 for 1 min. I/O unit We need to initialize writebufsize; I think "page_size" is the correct "bufsize", although I'm not sure. Comments? Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 35180e475c4c..9fad104d4aab 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -930,6 +930,7 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; + flash->mtd.writebufsize = flash->page_size; if (info->addr_width) flash->addr_width = info->addr_width; -- cgit v1.2.3 From 393ff468e42637ef5fbbf84c3500da14592d681b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:32:44 +0200 Subject: mtd: block2mtd: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. However, we forgot to set this parameter for block2mtd. Set it to PAGE_SIZE because this is actually the amount of data we write at a time. Signed-off-by: Artem Bityutskiy Acked-by: Joern Engel Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/block2mtd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index b78f23169d4e..8cd983cdc643 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -284,6 +284,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; dev->mtd.writesize = 1; + dev->mtd.writebufsize = PAGE_SIZE; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; dev->mtd.erase = block2mtd_erase; -- cgit v1.2.3 From 8c7c4f3463d1f165df60abd97a10e790bc64b84b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:38:43 +0200 Subject: mtd: doc2000: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index f7fbf6025ef2..b249e1300c0c 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -567,7 +567,7 @@ void DoC2k_init(struct mtd_info *mtd) mtd->flags = MTD_CAP_NANDFLASH; mtd->size = 0; mtd->erasesize = 0; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->erase = doc_erase; -- cgit v1.2.3 From a9452ac7cdc2243e5ffb911c2737b3ef27ef580f Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:42:39 +0200 Subject: mtd: doc2001: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2001.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 241192f05bc8..236af0f01002 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -349,7 +349,7 @@ void DoCMil_init(struct mtd_info *mtd) /* FIXME: erase size is not always 8KiB */ mtd->erasesize = 0x2000; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->erase = doc_erase; -- cgit v1.2.3 From 923609a91162a9f28bb923d8b2a23fcf2f8a3bcb Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:43:14 +0200 Subject: mtd: doc2001plus: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set it to be equivalent to mtd->writesize because this is the maximum amount of data the driver writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/doc2001plus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 09ae0adc3ad0..fed491f4b6f8 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -471,7 +471,7 @@ void DoCMilPlus_init(struct mtd_info *mtd) mtd->size = 0; mtd->erasesize = 0; - mtd->writesize = 512; + mtd->writebufsize = mtd->writesize = 512; mtd->oobsize = 16; mtd->owner = THIS_MODULE; mtd->erase = doc_erase; -- cgit v1.2.3 From 2a1a4e3d76296bdea4479cc72833cb9f8fa5c4f6 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 09:53:28 +0200 Subject: mtd: lart: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set writebufsize to 4 because this drivers writes at max 4 bytes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/lart.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 772a0ff89e0f..09d5b5aaea57 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -636,6 +636,7 @@ static int __init lart_flash_init (void) mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; + mtd.writebufsize = 4; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; -- cgit v1.2.3 From cb642b5997dcbb297e8e980e12ad6aa435278ef4 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 3 Feb 2012 10:16:50 +0200 Subject: mtd: sst25l: initialize writebufsize The writebufsize concept was introduce by commit "0e4ca7e mtd: add writebufsize field to mtd_info struct" and it represents the maximum amount of data the device writes to the media at a time. This is an important parameter for UBIFS which is used during recovery and which basically defines how big a corruption caused by a power cut can be. Set writebufsize to the flash page size because it is the maximum amount of data it writes at a time. Signed-off-by: Artem Bityutskiy Cc: stable@kernel.org [2.6.38+] Signed-off-by: David Woodhouse --- drivers/mtd/devices/sst25l.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 83e80c65d6e7..ea22ae366ff1 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -406,6 +406,7 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; + flash->mtd.writebufsize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; flash->mtd.erase = sst25l_erase; flash->mtd.read = sst25l_read; -- cgit v1.2.3 From 17636ef93691f5d3e9c9850b9e319e180e0b7ed1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 3 Sep 2012 17:12:29 +0300 Subject: UBI: fix a horrible memory deallocation bug UBI was mistakingly using 'kfree()' instead of 'kmem_cache_free()' when freeing "attach eraseblock" structures in vtbl.c. Thankfully, this happened only when we were doing auto-format, so many systems were unaffected. However, there are still many users affected. It is strange, but the system did not crash and nothing bad happened when the SLUB memory allocator was used. However, in case of SLOB we observed an crash right away. This problem was introduced in 2.6.39 by commit "6c1e875 UBI: add slab cache for ubi_scan_leb objects" A note for stable trees: Because variable were renamed, this won't cleanly apply to older kernels. Changing names like this should help: 1. ai -> si 2. aeb_slab_cache -> seb_slab_cache 3. new_aeb -> new_seb Reported-by: Richard Genoud Tested-by: Richard Genoud Tested-by: Artem Bityutskiy Cc: stable@vger.kernel.org [v2.6.39+] Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/vtbl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 39d6b63f20a5..f37f5dfd5ca3 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -340,7 +340,7 @@ retry: * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. */ err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); - kfree(new_aeb); + kmem_cache_free(ai->aeb_slab_cache, new_aeb); ubi_free_vid_hdr(ubi, vid_hdr); return err; @@ -353,7 +353,7 @@ write_error: list_add(&new_aeb->u.list, &ai->erase); goto retry; } - kfree(new_aeb); + kmem_cache_free(ai->aeb_slab_cache, new_aeb); out_free: ubi_free_vid_hdr(ubi, vid_hdr); return err; -- cgit v1.2.3 From a1913c9f623eaf8e4fff32b1554d70704b5de9fe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 22 Aug 2012 16:28:18 +0300 Subject: UBI: print image sequence number as unsigned integer Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index da1088271392..8e802a2ba58b 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -940,7 +940,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) ubi_msg("number of PEBs reserved for bad PEB handling: %d", ubi->beb_rsvd_pebs); ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); - ubi_msg("image sequence number: %d", ubi->image_seq); + ubi_msg("image sequence number: %u", ubi->image_seq); /* * The below lock makes sure we do not race with 'ubi_thread()' which -- cgit v1.2.3 From 744f78f841f072062e468a721771a2ebb96e8805 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 22 Aug 2012 16:40:05 +0300 Subject: UBI: print PID in debug messages Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/debug.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index d5d2645b51a7..d9e89ec90983 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -39,7 +39,8 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); print_hex_dump(l, ps, pt, r, g, b, len, a) #define ubi_dbg_msg(type, fmt, ...) \ - pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__) + pr_debug("UBI DBG " type " (pid %d): " fmt "\n", current->pid, \ + ##__VA_ARGS__) /* Just a debugging messages not related to any specific UBI subsystem */ #define dbg_msg(fmt, ...) \ -- cgit v1.2.3 From e3ab809ab2a59f8c9c12b6277c193a5c55424ab8 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 4 Jul 2012 11:06:00 +0300 Subject: UBI: introduce new bad PEB limit Introduce 'ubi->bad_peb_limit', which specifies an upper limit of PEBs UBI expects to go bad. Currently, it is initialized to a fixed percentage of total PEBs in the UBI device (configurable via CONFIG_MTD_UBI_BEB_LIMIT). The 'bad_peb_limit' is intended to be used for calculating the amount of PEBs UBI needs to reserve for bad eraseblock handling. Artem: minor amendments. Signed-off-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 26 +++++++++++++++++++------- drivers/mtd/ubi/build.c | 12 +++++++++++- drivers/mtd/ubi/ubi.h | 2 ++ 3 files changed, 32 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index ea4b95b5451c..76195ac90e51 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -34,13 +34,25 @@ config MTD_UBI_BEB_RESERVE help If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI reserves some amount of physical eraseblocks to handle new bad - eraseblocks. For example, if a flash physical eraseblock becomes bad, - UBI uses these reserved physical eraseblocks to relocate the bad one. - This option specifies how many physical eraseblocks will be reserved - for bad eraseblock handling (percents of total number of good flash - eraseblocks). If the underlying flash does not admit of bad - eraseblocks (e.g. NOR flash), this value is ignored and nothing is - reserved. Leave the default value if unsure. + eraseblocks. When a physical eraseblock becomes bad, UBI uses these + reserved physical eraseblocks to relocate the bad one. This + configuration option specifies how many physical eraseblocks will be + reserved for bad eraseblock handling (percents of total number of + good physical eraseblocks on this MTD partition). If the underlying + flash does not admit of bad eraseblocks (e.g. NOR flash), this value + is ignored and nothing is reserved. Leave the default value if + unsure. + +config MTD_UBI_BEB_LIMIT + int "Percentage of maximum expected bad eraseblocks" + default 2 + range 0 25 + help + This option specifies the maximum bad physical eraseblocks UBI + expects on the UBI device (percents of total number of physical + eraseblocks on this MTD partition). If the underlying flash does not + admit of bad eraseblocks (e.g. NOR flash), this value is ignored. + Leave the default value if unsure. config MTD_UBI_GLUEBI tristate "MTD devices emulation driver (gluebi)" diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 8e802a2ba58b..0d14ae1f72dc 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -607,8 +607,18 @@ static int io_init(struct ubi_device *ubi) ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd); ubi->flash_size = ubi->mtd->size; - if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) + if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) { ubi->bad_allowed = 1; + if (CONFIG_MTD_UBI_BEB_LIMIT > 0) { + int percent = CONFIG_MTD_UBI_BEB_LIMIT; + int limit = mult_frac(ubi->peb_count, percent, 100); + + /* Round it up */ + if (mult_frac(limit, 100, percent) < ubi->peb_count) + limit += 1; + ubi->bad_peb_limit = limit; + } + } if (ubi->mtd->type == MTD_NORFLASH) { ubi_assert(ubi->mtd->writesize == 1); diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 84f66e3fa05d..aeb459eb7e42 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -363,6 +363,7 @@ struct ubi_wl_entry; * @flash_size: underlying MTD device size (in bytes) * @peb_count: count of physical eraseblocks on the MTD device * @peb_size: physical eraseblock size + * @bad_peb_limit: top limit of expected bad physical eraseblocks * @bad_peb_count: count of bad physical eraseblocks * @good_peb_count: count of good physical eraseblocks * @corr_peb_count: count of corrupted physical eraseblocks (preserved and not @@ -410,6 +411,7 @@ struct ubi_device { int avail_pebs; int beb_rsvd_pebs; int beb_rsvd_level; + int bad_peb_limit; int autoresize_vol_id; int vtbl_slots; -- cgit v1.2.3 From 39b6f4b2d08d5d07558ad39b91fb8e0297f8e025 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 4 Jul 2012 11:06:01 +0300 Subject: UBI: limit amount of reserved eraseblocks for bad PEB handling The existing mechanism of reserving PEBs for bad PEB handling has two flaws: - It is calculated as a percentage of good PEBs instead of total PEBs. - There's no limit on the amount of PEBs UBI reserves for future bad eraseblock handling. This patch changes the mechanism to overcome these flaws. The desired level of PEBs reserved for bad PEB handling (beb_rsvd_level) is set to the maximum expected bad eraseblocks (bad_peb_limit) minus the existing number of bad eraseblocks (bad_peb_count). The actual amount of PEBs reserved for bad PEB handling is usually set to the desired level (but in some circumstances may be lower than the desired level, e.g. when attaching to a device that has too few available PEBs to satisfy the desired level). In the case where the device has too many bad PEBs (above the expected limit), then the desired level, and the actual amount of PEBs reserved are set to zero. No PEBs will be set aside for future bad eraseblock handling - even if some PEBs are made available (e.g. by shrinking a volume). If another PEB goes bad, and there are available PEBs, then the eraseblock will be marked bad (consuming one available PEB). But if there are no available PEBs, ubi will go into readonly mode. Signed-off-by: Shmulik Ladkani --- drivers/mtd/ubi/misc.c | 16 ++++++++++++---- drivers/mtd/ubi/wl.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index c587ee150fff..e73f31ba8259 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -121,10 +121,18 @@ void ubi_update_reserved(struct ubi_device *ubi) */ void ubi_calculate_reserved(struct ubi_device *ubi) { - ubi->beb_rsvd_level = ubi->good_peb_count/100; - ubi->beb_rsvd_level *= CONFIG_MTD_UBI_BEB_RESERVE; - if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS) - ubi->beb_rsvd_level = MIN_RESEVED_PEBS; + /* + * Calculate the actual number of PEBs currently needed to be reserved + * for future bad eraseblock handling. + */ + ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count; + if (ubi->beb_rsvd_level < 0) { + ubi->beb_rsvd_level = 0; + ubi_warn("number of bad PEBs (%d) is above the expected limit " + "(%d), not reserving any PEBs for bad PEB handling, " + "will use available PEBs (if any)", + ubi->bad_peb_count, ubi->bad_peb_limit); + } } /** diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index b6be644e7b85..bd05276252fb 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -978,9 +978,10 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, int cancel) { struct ubi_wl_entry *e = wl_wrk->e; - int pnum = e->pnum, err, need; + int pnum = e->pnum; int vol_id = wl_wrk->vol_id; int lnum = wl_wrk->lnum; + int err, available_consumed = 0; if (cancel) { dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); @@ -1045,20 +1046,14 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, } spin_lock(&ubi->volumes_lock); - need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1; - if (need > 0) { - need = ubi->avail_pebs >= need ? need : ubi->avail_pebs; - ubi->avail_pebs -= need; - ubi->rsvd_pebs += need; - ubi->beb_rsvd_pebs += need; - if (need > 0) - ubi_msg("reserve more %d PEBs", need); - } - if (ubi->beb_rsvd_pebs == 0) { - spin_unlock(&ubi->volumes_lock); - ubi_err("no reserved physical eraseblocks"); - goto out_ro; + if (ubi->avail_pebs == 0) { + spin_unlock(&ubi->volumes_lock); + ubi_err("no reserved/available physical eraseblocks"); + goto out_ro; + } + ubi->avail_pebs -= 1; + available_consumed = 1; } spin_unlock(&ubi->volumes_lock); @@ -1068,19 +1063,36 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, goto out_ro; spin_lock(&ubi->volumes_lock); - ubi->beb_rsvd_pebs -= 1; + if (ubi->beb_rsvd_pebs > 0) { + if (available_consumed) { + /* + * The amount of reserved PEBs increased since we last + * checked. + */ + ubi->avail_pebs += 1; + available_consumed = 0; + } + ubi->beb_rsvd_pebs -= 1; + } ubi->bad_peb_count += 1; ubi->good_peb_count -= 1; ubi_calculate_reserved(ubi); - if (ubi->beb_rsvd_pebs) + if (available_consumed) + ubi_warn("no PEBs in the reserved pool, used an available PEB"); + else if (ubi->beb_rsvd_pebs) ubi_msg("%d PEBs left in the reserve", ubi->beb_rsvd_pebs); else - ubi_warn("last PEB from the reserved pool was used"); + ubi_warn("last PEB from the reserve was used"); spin_unlock(&ubi->volumes_lock); return err; out_ro: + if (available_consumed) { + spin_lock(&ubi->volumes_lock); + ubi->avail_pebs += 1; + spin_unlock(&ubi->volumes_lock); + } ubi_ro_mode(ubi); return err; } -- cgit v1.2.3 From 1b876dd228fdf242a617b3bd42a9129b7cdf7fef Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 4 Jul 2012 11:06:02 +0300 Subject: UBI: kill CONFIG_MTD_UBI_BEB_RESERVE CONFIG_MTD_UBI_BEB_RESERVE and MIN_RESEVED_PEBS are no longer used, since the amount of reserved eraseblocks for bad PEB handling is now derived from 'ubi->bad_peb_limit' (ubi's maximum expected bad eraseblocks). Signed-off-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 16 ---------------- drivers/mtd/ubi/ubi.h | 3 --- 2 files changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 76195ac90e51..b2f4f0f032f1 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -27,22 +27,6 @@ config MTD_UBI_WL_THRESHOLD life-cycle less than 10000, the threshold should be lessened (e.g., to 128 or 256, although it does not have to be power of 2). -config MTD_UBI_BEB_RESERVE - int "Percentage of reserved eraseblocks for bad eraseblocks handling" - default 2 - range 0 25 - help - If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI - reserves some amount of physical eraseblocks to handle new bad - eraseblocks. When a physical eraseblock becomes bad, UBI uses these - reserved physical eraseblocks to relocate the bad one. This - configuration option specifies how many physical eraseblocks will be - reserved for bad eraseblock handling (percents of total number of - good physical eraseblocks on this MTD partition). If the underlying - flash does not admit of bad eraseblocks (e.g. NOR flash), this value - is ignored and nothing is reserved. Leave the default value if - unsure. - config MTD_UBI_BEB_LIMIT int "Percentage of maximum expected bad eraseblocks" default 2 diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index aeb459eb7e42..c94612e67c47 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -59,9 +59,6 @@ #define ubi_err(fmt, ...) printk(KERN_ERR "UBI error: %s: " fmt "\n", \ __func__, ##__VA_ARGS__) -/* Lowest number PEBs reserved for bad PEB handling */ -#define MIN_RESEVED_PEBS 2 - /* Background thread name pattern */ #define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" -- cgit v1.2.3 From 66a5b91075c983921638470c5a148d6ad550c133 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 10 Jul 2012 18:23:39 +0200 Subject: mtd: mark mtd_is_partition argument as constant 'struct mtd_info' is not modified by 'mtd_is_partition()' so it can be marked as "const". Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/mtdpart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 630be3e7da04..ae18e4d92f29 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -735,7 +735,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, } EXPORT_SYMBOL_GPL(parse_mtd_partitions); -int mtd_is_partition(struct mtd_info *mtd) +int mtd_is_partition(const struct mtd_info *mtd) { struct mtd_part *part; int ispart = 0; -- cgit v1.2.3 From e29b98673203102d2cd363362ff503d41c702456 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 10 Jul 2012 18:23:40 +0200 Subject: mtd: mtdparts: introduce mtd_get_device_size 'mtd_get_device_size()' returns the size of the whole MTD device, that is the mtd_info master size. This will be used by UBI to calculate the maximum number of bad blocks (MBB) on a MTD device. Artem: amended the patch a bit. Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/mtdpart.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index ae18e4d92f29..dd8cfa903b79 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -751,3 +751,13 @@ int mtd_is_partition(const struct mtd_info *mtd) return ispart; } EXPORT_SYMBOL_GPL(mtd_is_partition); + +/* Returns the size of the entire flash chip */ +uint64_t mtd_get_device_size(const struct mtd_info *mtd) +{ + if (!mtd_is_partition(mtd)) + return mtd->size; + + return PART(mtd)->master->size; +} +EXPORT_SYMBOL_GPL(mtd_get_device_size); -- cgit v1.2.3 From a007265ee0532eb07126a53e0868e94c7230dabc Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 10 Jul 2012 18:23:41 +0200 Subject: UBI: use the whole MTD device size to get bad_peb_limit On NAND flash devices, UBI reserves some physical erase blocks (PEB) for bad block handling. Today, the number of reserved PEB can only be set as a percentage of the total number of PEB in each MTD partition. For example, for a NAND flash with 128KiB PEB, 2 MTD partition of 20MiB (mtd0) and 100MiB (mtd1) and 2% reserved PEB: - the UBI device on mtd0 will have 2 PEB reserved - the UBI device on mtd1 will have 16 PEB reserved The problem with this behaviour is that NAND flash manufacturers give a minimum number of valid block (NVB) during the endurance life of the device, e.g.: Parameter Symbol Min Max Unit Notes -------------------------------------------------------------- Valid block number NVB 1004 1024 Blocks 1 From this number we can deduce the maximum number of bad PEB that a device will contain during its endurance life: a 128MiB NAND flash (1024 PEB) will not have less than 20 bad blocks during the flash endurance life. But the manufacturer doesn't tell where those bad block will appear. He doesn't say either if they will be equally disposed on the whole device (and I'm pretty sure they won't). So, according to the datasheets, we should reserve the maximum number of bad PEB for each UBI device (worst case scenario: 20 bad blocks appears on the smallest MTD partition). So this patch make UBI use the whole MTD device size to calculate the maximum bad expected eraseblocks. The Kconfig option is in per1024 blocks, thus it can have a default value of 20 which is *very* common for NAND devices. Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 27 +++++++++++++++++++++------ drivers/mtd/ubi/build.c | 21 ++++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index b2f4f0f032f1..dcbaae3ead63 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -28,14 +28,29 @@ config MTD_UBI_WL_THRESHOLD to 128 or 256, although it does not have to be power of 2). config MTD_UBI_BEB_LIMIT - int "Percentage of maximum expected bad eraseblocks" - default 2 - range 0 25 + int "Maximum expected bad eraseblock count per 1024 eraseblocks" + default 20 + range 0 768 help This option specifies the maximum bad physical eraseblocks UBI - expects on the UBI device (percents of total number of physical - eraseblocks on this MTD partition). If the underlying flash does not - admit of bad eraseblocks (e.g. NOR flash), this value is ignored. + expects on the MTD device (per 1024 eraseblocks). If the underlying + flash does not admit of bad eraseblocks (e.g. NOR flash), this value + is ignored. + + NAND datasheets often specify the minimum and maximum NVM (Number of + Valid Blocks) for the flashes' endurance lifetime. The maximum + expected bad eraseblocks per 1024 eraseblocks then can be calculated + as "1024 * (1 - MinNVB / MaxNVB)", which gives 20 for most NANDs + (MaxNVB is basically the total count of eraseblocks on the chip). + + To put it differently, if this value is 20, UBI will try to reserve + about 1.9% of physical eraseblocks for bad blocks handling. And that + will be 1.9% of eraseblocks on the entire NAND chip, not just the MTD + partition UBI attaches. This means that if you have, say, a NAND + flash chip admits maximum 40 bad eraseblocks, and it is split on two + MTD partitions of the same size, UBI will reserve 40 eraseblocks when + attaching a partition. + Leave the default value if unsure. config MTD_UBI_GLUEBI diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 0d14ae1f72dc..c77384cd4d46 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -610,11 +611,25 @@ static int io_init(struct ubi_device *ubi) if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) { ubi->bad_allowed = 1; if (CONFIG_MTD_UBI_BEB_LIMIT > 0) { - int percent = CONFIG_MTD_UBI_BEB_LIMIT; - int limit = mult_frac(ubi->peb_count, percent, 100); + int per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + int limit, device_pebs; + uint64_t device_size; + + /* + * Here we are using size of the entire flash chip and + * not just the MTD partition size because the maximum + * number of bad eraseblocks is a percentage of the + * whole device and bad eraseblocks are not fairly + * distributed over the flash chip. So the worst case + * is that all the bad eraseblocks of the chip are in + * the MTD partition we are attaching (ubi->mtd). + */ + device_size = mtd_get_device_size(ubi->mtd); + device_pebs = mtd_div_by_eb(device_size, ubi->mtd); + limit = mult_frac(device_pebs, per1024, 1024); /* Round it up */ - if (mult_frac(limit, 100, percent) < ubi->peb_count) + if (mult_frac(limit, 1024, per1024) < device_pebs) limit += 1; ubi->bad_peb_limit = limit; } -- cgit v1.2.3 From 7ba7c83c786902bd337300e30d9f4598619f71bd Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 17 Aug 2012 16:35:18 +0200 Subject: UBI: separate bad_peb_limit in a function No functional changes here, just to prepare for next patch. Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 54 ++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index c77384cd4d46..41ef717e25c8 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -565,6 +565,34 @@ void ubi_free_internal_volumes(struct ubi_device *ubi) } } +static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) +{ + int limit, device_pebs; + uint64_t device_size; + + if (!max_beb_per1024) + return 0; + + /* + * Here we are using size of the entire flash chip and + * not just the MTD partition size because the maximum + * number of bad eraseblocks is a percentage of the + * whole device and bad eraseblocks are not fairly + * distributed over the flash chip. So the worst case + * is that all the bad eraseblocks of the chip are in + * the MTD partition we are attaching (ubi->mtd). + */ + device_size = mtd_get_device_size(ubi->mtd); + device_pebs = mtd_div_by_eb(device_size, ubi->mtd); + limit = mult_frac(device_pebs, max_beb_per1024, 1024); + + /* Round it up */ + if (mult_frac(limit, 1024, max_beb_per1024) < device_pebs) + limit += 1; + + return limit; +} + /** * io_init - initialize I/O sub-system for a given UBI device. * @ubi: UBI device description object @@ -582,6 +610,8 @@ void ubi_free_internal_volumes(struct ubi_device *ubi) */ static int io_init(struct ubi_device *ubi) { + const int max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + if (ubi->mtd->numeraseregions != 0) { /* * Some flashes have several erase regions. Different regions @@ -610,29 +640,7 @@ static int io_init(struct ubi_device *ubi) if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) { ubi->bad_allowed = 1; - if (CONFIG_MTD_UBI_BEB_LIMIT > 0) { - int per1024 = CONFIG_MTD_UBI_BEB_LIMIT; - int limit, device_pebs; - uint64_t device_size; - - /* - * Here we are using size of the entire flash chip and - * not just the MTD partition size because the maximum - * number of bad eraseblocks is a percentage of the - * whole device and bad eraseblocks are not fairly - * distributed over the flash chip. So the worst case - * is that all the bad eraseblocks of the chip are in - * the MTD partition we are attaching (ubi->mtd). - */ - device_size = mtd_get_device_size(ubi->mtd); - device_pebs = mtd_div_by_eb(device_size, ubi->mtd); - limit = mult_frac(device_pebs, per1024, 1024); - - /* Round it up */ - if (mult_frac(limit, 1024, per1024) < device_pebs) - limit += 1; - ubi->bad_peb_limit = limit; - } + ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024); } if (ubi->mtd->type == MTD_NORFLASH) { -- cgit v1.2.3 From f20283a021a9b43f530923f0d1baa687d34b7c63 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 17 Aug 2012 16:35:19 +0200 Subject: UBI: introduce MTD_PARAM_MAX_COUNT Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 41ef717e25c8..6dc817d2a042 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -46,6 +46,9 @@ /* Maximum length of the 'mtd=' parameter */ #define MTD_PARAM_LEN_MAX 64 +/* Maximum number of comma-separated items in the 'mtd=' parameter */ +#define MTD_PARAM_MAX_COUNT 2 + #ifdef CONFIG_MTD_UBI_MODULE #define ubi_is_module() 1 #else @@ -1324,7 +1327,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; - char *tokens[2] = {NULL, NULL}; + char *tokens[MTD_PARAM_MAX_COUNT]; if (!val) return -EINVAL; @@ -1354,7 +1357,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (buf[len - 1] == '\n') buf[len - 1] = '\0'; - for (i = 0; i < 2; i++) + for (i = 0; i < MTD_PARAM_MAX_COUNT; i++) tokens[i] = strsep(&pbuf, ","); if (pbuf) { -- cgit v1.2.3 From b099b9e9ce6d98caaa9af240175a7f861d8da259 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 20 Aug 2012 18:00:11 +0200 Subject: UBI: prepare for max_beb_per1024 module parameter addition This patch prepare the way for the addition of max_beb_per1024 module parameter. There's no functional change. Signed-off-by: Richard Genoud Reviewed-by: Shmulik Ladkani Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 14 ++++++++------ drivers/mtd/ubi/cdev.c | 3 ++- drivers/mtd/ubi/ubi.h | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6dc817d2a042..4c88aef037e9 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -599,6 +599,7 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) /** * io_init - initialize I/O sub-system for a given UBI device. * @ubi: UBI device description object + * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are * assumed: @@ -611,10 +612,8 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) * This function returns zero in case of success and a negative error code in * case of failure. */ -static int io_init(struct ubi_device *ubi) +static int io_init(struct ubi_device *ubi, int max_beb_per1024) { - const int max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; - if (ubi->mtd->numeraseregions != 0) { /* * Some flashes have several erase regions. Different regions @@ -836,6 +835,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * @mtd: MTD device description object * @ubi_num: number to assign to the new UBI device * @vid_hdr_offset: VID header offset + * @max_beb_per1024: maximum number of expected bad blocks per 1024 PEBs * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in @@ -846,7 +846,8 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * Note, the invocations of this function has to be serialized by the * @ubi_devices_mutex. */ -int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) +int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, + int vid_hdr_offset, int max_beb_per1024) { struct ubi_device *ubi; int i, err, ref = 0; @@ -919,7 +920,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); - err = io_init(ubi); + err = io_init(ubi, max_beb_per1024); if (err) goto out_free; @@ -1208,7 +1209,8 @@ static int __init ubi_init(void) mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, - p->vid_hdr_offs); + p->vid_hdr_offs, + CONFIG_MTD_UBI_BEB_LIMIT); mutex_unlock(&ubi_devices_mutex); if (err < 0) { ubi_err("cannot attach mtd%d", mtd->index); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index fb5567878181..619f9144f990 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1010,7 +1010,8 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, * 'ubi_attach_mtd_dev()'. */ mutex_lock(&ubi_devices_mutex); - err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset); + err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, + CONFIG_MTD_UBI_BEB_LIMIT); mutex_unlock(&ubi_devices_mutex); if (err < 0) put_mtd_device(mtd); diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index c94612e67c47..2a2475b9ec54 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -693,7 +693,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr); /* build.c */ -int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset); +int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, + int vid_hdr_offset, int max_beb_per1024); int ubi_detach_mtd_dev(int ubi_num, int anyway); struct ubi_device *ubi_get_device(int ubi_num); void ubi_put_device(struct ubi_device *ubi); -- cgit v1.2.3 From 1990ed2651f4bca93f386138f39c67a512a889e1 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 20 Aug 2012 18:00:13 +0200 Subject: UBI: check max_beb_per1024 value in ubi_attach_mtd_dev max_beb_per1024 shouldn't be negative, and a 0 value will be treated as the default value. For the upper bound, 768/1024 should be enough. Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 4c88aef037e9..cf017c37fa53 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -49,6 +49,9 @@ /* Maximum number of comma-separated items in the 'mtd=' parameter */ #define MTD_PARAM_MAX_COUNT 2 +/* Maximum value for the number of bad PEBs per 1024 PEBs */ +#define MAX_MTD_UBI_BEB_LIMIT 768 + #ifdef CONFIG_MTD_UBI_MODULE #define ubi_is_module() 1 #else @@ -852,6 +855,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, struct ubi_device *ubi; int i, err, ref = 0; + if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT) + return -EINVAL; + + if (!max_beb_per1024) + max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + /* * Check if we already have the same MTD device attached. * -- cgit v1.2.3 From 52aa7c8bca4f303a180281c71306093857354b0e Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 20 Aug 2012 18:00:14 +0200 Subject: UBI: allow specifying bad PEBs limit using module parameter This patch provides the possibility to adjust the "maximum expected number of bad blocks per 1024 blocks" (max_beb_per1024) for each mtd device. The majority of NAND devices have their max_beb_per1024 equal to 20, but sometimes it's more. Now, we can adjust that via a kernel parameter: ubi.mtd=[,[,max_beb_per1024]] Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 2 ++ drivers/mtd/ubi/build.c | 40 +++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index dcbaae3ead63..3e185e46cf6c 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -51,6 +51,8 @@ config MTD_UBI_BEB_LIMIT MTD partitions of the same size, UBI will reserve 40 eraseblocks when attaching a partition. + This option can be overridden by the "mtd=" UBI module parameter. + Leave the default value if unsure. config MTD_UBI_GLUEBI diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index cf017c37fa53..423e1f2654dc 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -47,7 +47,7 @@ #define MTD_PARAM_LEN_MAX 64 /* Maximum number of comma-separated items in the 'mtd=' parameter */ -#define MTD_PARAM_MAX_COUNT 2 +#define MTD_PARAM_MAX_COUNT 3 /* Maximum value for the number of bad PEBs per 1024 PEBs */ #define MAX_MTD_UBI_BEB_LIMIT 768 @@ -63,10 +63,12 @@ * @name: MTD character device node path, MTD device name, or MTD device number * string * @vid_hdr_offs: VID header offset + * @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; int vid_hdr_offs; + int max_beb_per1024; }; /* Numbers of elements set in the @mtd_dev_param array */ @@ -838,7 +840,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * @mtd: MTD device description object * @ubi_num: number to assign to the new UBI device * @vid_hdr_offset: VID header offset - * @max_beb_per1024: maximum number of expected bad blocks per 1024 PEBs + * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in @@ -1218,8 +1220,7 @@ static int __init ubi_init(void) mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, - p->vid_hdr_offs, - CONFIG_MTD_UBI_BEB_LIMIT); + p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { ubi_err("cannot attach mtd%d", mtd->index); @@ -1386,23 +1387,32 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (p->vid_hdr_offs < 0) return p->vid_hdr_offs; + if (tokens[2]) { + int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); + + if (err) { + printk(KERN_ERR "UBI error: bad value for " + "max_beb_per1024 parameter: %s", tokens[2]); + return -EINVAL; + } + } + mtd_devs += 1; return 0; } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " - "mtd=[,].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=[,[,max_beb_per1024]].\n" "Multiple \"mtd\" parameters may be specified.\n" - "MTD devices may be specified by their number, name, or " - "path to the MTD character device node.\n" - "Optional \"vid_hdr_offs\" parameter specifies UBI VID " - "header position to be used by UBI.\n" - "Example 1: mtd=/dev/mtd0 - attach MTD device " - "/dev/mtd0.\n" - "Example 2: mtd=content,1984 mtd=4 - attach MTD device " - "with name \"content\" using VID header offset 1984, and " - "MTD device number 4 with default VID header offset."); + "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" + "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" + "Optional \"max_beb_per1024\" parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value (" + __stringify(CONFIG_MTD_UBI_BEB_LIMIT) ") if 0)\n" + "\n" + "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" + "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" + "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_DESCRIPTION("UBI - Unsorted Block Images"); -- cgit v1.2.3 From 072f08afcca6644e86cb4124fc9de7539ee1bac7 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 20 Aug 2012 18:00:15 +0200 Subject: UBI: add max_beb_per1024 to attach ioctl This patch provides a possibility to set the "maximum expected number of bad blocks per 1024 blocks" (max_beb_per1024) for each mtd device using the UBI_IOCATT ioctl. Signed-off-by: Richard Genoud Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 3 ++- drivers/mtd/ubi/cdev.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 3e185e46cf6c..271a842f8c39 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -51,7 +51,8 @@ config MTD_UBI_BEB_LIMIT MTD partitions of the same size, UBI will reserve 40 eraseblocks when attaching a partition. - This option can be overridden by the "mtd=" UBI module parameter. + This option can be overridden by the "mtd=" UBI module parameter or + by the "attach" ioctl. Leave the default value if unsure. diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 619f9144f990..7885dc0934ce 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1011,7 +1011,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, */ mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, - CONFIG_MTD_UBI_BEB_LIMIT); + req.max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) put_mtd_device(mtd); -- cgit v1.2.3 From 0aebf9c036c61c2f9b30a6a89ae6d8485b59124b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sat, 18 Aug 2012 14:11:42 +0200 Subject: UBI: fix autoresize handling in R/O mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently UBI fails in autoresize when it is in R/O mode (e.g., because the underlying MTD device is R/O). This patch fixes the issue - we just skip autoresize and print a warning. Reported-by: Pali Rohár Cc: stable@vger.kernel.org Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 423e1f2654dc..6988b7273f5e 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -799,6 +799,11 @@ static int autoresize(struct ubi_device *ubi, int vol_id) struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; + if (ubi->ro_mode) { + ubi_warn("skip auto-resize because of R/O mode"); + return 0; + } + /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propagate this change -- cgit v1.2.3 From c40f51d8921867fefad4967e8376ea5f1e624030 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Wed, 22 Aug 2012 16:03:46 +0200 Subject: UBI: erase free PEB with bitflip in EC header Without this patch, these PEB are not scrubbed until we put data in them. Bitflip can accumulate latter and we can loose the EC header (but VID header should be intact and allow to recover data). Signed-off-by: Matthieu Castet Cc: stable@vger.kernel.org Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index efdbd98b64f2..f5941c48f6b7 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -975,7 +975,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; goto adjust_mean_ec; case UBI_IO_FF: - if (ec_err) + if (ec_err || bitflips) err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, ec, 1, &ai->erase); else -- cgit v1.2.3 From 408a719e4267c98c93976cf43087519a22699ce6 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 27 Aug 2012 14:43:54 +0300 Subject: UBI: comply with coding style Join all the split printk lines in order to stop checkpatch complaining. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 28 ++++++++--------- drivers/mtd/ubi/build.c | 22 +++++++------- drivers/mtd/ubi/cdev.c | 9 +++--- drivers/mtd/ubi/debug.c | 4 +-- drivers/mtd/ubi/eba.c | 33 ++++++++++---------- drivers/mtd/ubi/gluebi.c | 28 ++++++++--------- drivers/mtd/ubi/io.c | 78 +++++++++++++++++++++++------------------------- drivers/mtd/ubi/misc.c | 4 +-- drivers/mtd/ubi/vtbl.c | 8 ++--- 9 files changed, 101 insertions(+), 113 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index f5941c48f6b7..a5ad8e9de3e4 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -378,8 +378,8 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, if (err == UBI_IO_BITFLIPS) bitflips = 1; else { - ubi_err("VID of PEB %d header is bad, but it " - "was OK earlier, err %d", pnum, err); + ubi_err("VID of PEB %d header is bad, but it was OK earlier, err %d", + pnum, err); if (err > 0) err = -EIO; @@ -790,9 +790,9 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) goto out_unlock; - ubi_err("PEB %d contains corrupted VID header, and the data does not " - "contain all 0xFF, this may be a non-UBI PEB or a severe VID " - "header corruption which requires manual inspection", pnum); + ubi_err("PEB %d contains corrupted VID header, and the data does not contain all 0xFF", + pnum); + ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); ubi_dump_vid_hdr(vid_hdr); dbg_msg("hexdump of PEB %d offset %d, length %d", pnum, ubi->leb_start, ubi->leb_size); @@ -907,8 +907,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, ubi->image_seq = image_seq; if (ubi->image_seq && image_seq && ubi->image_seq != image_seq) { - ubi_err("bad image sequence number %d in PEB %d, " - "expected %d", image_seq, pnum, ubi->image_seq); + ubi_err("bad image sequence number %d in PEB %d, expected %d", + image_seq, pnum, ubi->image_seq); ubi_dump_ec_hdr(ech); return -EINVAL; } @@ -997,8 +997,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, /* Unsupported internal volume */ switch (vidh->compat) { case UBI_COMPAT_DELETE: - ubi_msg("\"delete\" compatible internal volume %d:%d" - " found, will remove it", vol_id, lnum); + ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", + vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 1, &ai->erase); if (err) @@ -1006,15 +1006,14 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_RO: - ubi_msg("read-only compatible internal volume %d:%d" - " found, switch to read-only mode", + ubi_msg("read-only compatible internal volume %d:%d found, switch to read-only mode", vol_id, lnum); ubi->ro_mode = 1; break; case UBI_COMPAT_PRESERVE: - ubi_msg("\"preserve\" compatible internal volume %d:%d" - " found", vol_id, lnum); + ubi_msg("\"preserve\" compatible internal volume %d:%d found", + vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 0, &ai->alien); if (err) @@ -1112,8 +1111,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); } else { - ubi_err("MTD device is not UBI-formatted and possibly " - "contains non-UBI data - refusing it"); + ubi_err("MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); return -EINVAL; } diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6988b7273f5e..ffc257f0c6c8 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -748,16 +748,15 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) * read-only mode. */ if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { - ubi_warn("EC and VID headers are in the same minimal I/O unit, " - "switch to read-only mode"); + ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); ubi->ro_mode = 1; } ubi->leb_size = ubi->peb_size - ubi->leb_start; if (!(ubi->mtd->flags & MTD_WRITEABLE)) { - ubi_msg("MTD device %d is write-protected, attach in " - "read-only mode", ubi->mtd->index); + ubi_msg("MTD device %d is write-protected, attach in read-only mode", + ubi->mtd->index); ubi->ro_mode = 1; } @@ -892,8 +891,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, * no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type == MTD_UBIVOLUME) { - ubi_err("refuse attaching mtd%d - it is already emulated on " - "top of UBI", mtd->index); + ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI", + mtd->index); return -EINVAL; } @@ -1357,14 +1356,13 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - printk(KERN_ERR "UBI error: parameter \"%s\" is too long, " - "max. is %d\n", val, MTD_PARAM_LEN_MAX); + printk(KERN_ERR "UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } if (len == 0) { - printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - " - "ignored\n"); + printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - ignored\n"); return 0; } @@ -1396,8 +1394,8 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); if (err) { - printk(KERN_ERR "UBI error: bad value for " - "max_beb_per1024 parameter: %s", tokens[2]); + printk(KERN_ERR "UBI error: bad value for max_beb_per1024 parameter: %s", + tokens[2]); return -EINVAL; } } diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 7885dc0934ce..540d2db492ee 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -140,9 +140,9 @@ static int vol_cdev_release(struct inode *inode, struct file *file) vol->updating = 0; vfree(vol->upd_buf); } else if (vol->changing_leb) { - dbg_gen("only %lld of %lld bytes received for atomic LEB change" - " for volume %d:%d, cancel", vol->upd_received, - vol->upd_bytes, vol->ubi->ubi_num, vol->vol_id); + dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel", + vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num, + vol->vol_id); vol->changing_leb = 0; vfree(vol->upd_buf); } @@ -189,7 +189,8 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) return new_offset; } -static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync) +static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, + int datasync) { struct ubi_volume_desc *desc = file->private_data; struct ubi_device *ubi = desc->vol->ubi; diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 2da10ea51eec..f56c9b295da6 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -43,8 +43,8 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) return; err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, " - "read %zd bytes", err, len, pnum, offset, read); + ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + err, len, pnum, offset, read); goto out; } diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 385b1f0dd73f..6cbc9e7298a7 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -420,9 +420,8 @@ retry: */ if (err == UBI_IO_BAD_HDR_EBADMSG || err == UBI_IO_BAD_HDR) { - ubi_warn("corrupted VID header at PEB " - "%d, LEB %d:%d", pnum, vol_id, - lnum); + ubi_warn("corrupted VID header at PEB %d, LEB %d:%d", + pnum, vol_id, lnum); err = -EBADMSG; } else ubi_ro_mode(ubi); @@ -660,9 +659,8 @@ retry: if (len) { err = ubi_io_write_data(ubi, buf, pnum, offset, len); if (err) { - ubi_warn("failed to write %d bytes at offset %d of " - "LEB %d:%d, PEB %d", len, offset, vol_id, - lnum, pnum); + ubi_warn("failed to write %d bytes at offset %d of LEB %d:%d, PEB %d", + len, offset, vol_id, lnum, pnum); goto write_error; } } @@ -1040,9 +1038,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, * cancel it. */ if (vol->eba_tbl[lnum] != from) { - dbg_wl("LEB %d:%d is no longer mapped to PEB %d, mapped to " - "PEB %d, cancel", vol_id, lnum, from, - vol->eba_tbl[lnum]); + dbg_wl("LEB %d:%d is no longer mapped to PEB %d, mapped to PEB %d, cancel", + vol_id, lnum, from, vol->eba_tbl[lnum]); err = MOVE_CANCEL_RACE; goto out_unlock_leb; } @@ -1107,8 +1104,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading VID header back from " - "PEB %d", err, to); + ubi_warn("error %d while reading VID header back from PEB %d", + err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; } else @@ -1134,8 +1131,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, err = ubi_io_read_data(ubi, ubi->peb_buf, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) { - ubi_warn("error %d while reading data back " - "from PEB %d", err, to); + ubi_warn("error %d while reading data back from PEB %d", + err, to); if (is_error_sane(err)) err = MOVE_TARGET_RD_ERR; } else @@ -1146,8 +1143,8 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); if (crc != crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size)) { - ubi_warn("read data back from PEB %d and it is " - "different", to); + ubi_warn("read data back from PEB %d and it is different", + to); err = -EINVAL; goto out_unlock_buf; } @@ -1197,11 +1194,11 @@ static void print_rsvd_warning(struct ubi_device *ubi, return; } - ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d," - " need %d", ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); + ubi_warn("cannot reserve enough PEBs for bad PEB handling, reserved %d, need %d", + ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); if (ubi->corr_peb_count) ubi_warn("%d PEBs are corrupted and not used", - ubi->corr_peb_count); + ubi->corr_peb_count); } /** diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 9eb07fb92ad8..388428291af1 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -360,9 +360,8 @@ static int gluebi_create(struct ubi_device_info *di, mutex_lock(&devices_mutex); g = find_gluebi_nolock(vi->ubi_num, vi->vol_id); if (g) - err_msg("gluebi MTD device %d form UBI device %d volume %d " - "already exists", g->mtd.index, vi->ubi_num, - vi->vol_id); + err_msg("gluebi MTD device %d form UBI device %d volume %d already exists", + g->mtd.index, vi->ubi_num, vi->vol_id); mutex_unlock(&devices_mutex); if (mtd_device_register(mtd, NULL, 0)) { @@ -395,8 +394,8 @@ static int gluebi_remove(struct ubi_volume_info *vi) mutex_lock(&devices_mutex); gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id); if (!gluebi) { - err_msg("got remove notification for unknown UBI device %d " - "volume %d", vi->ubi_num, vi->vol_id); + err_msg("got remove notification for unknown UBI device %d volume %d", + vi->ubi_num, vi->vol_id); err = -ENOENT; } else if (gluebi->refcnt) err = -EBUSY; @@ -409,9 +408,8 @@ static int gluebi_remove(struct ubi_volume_info *vi) mtd = &gluebi->mtd; err = mtd_device_unregister(mtd); if (err) { - err_msg("cannot remove fake MTD device %d, UBI device %d, " - "volume %d, error %d", mtd->index, gluebi->ubi_num, - gluebi->vol_id, err); + err_msg("cannot remove fake MTD device %d, UBI device %d, volume %d, error %d", + mtd->index, gluebi->ubi_num, gluebi->vol_id, err); mutex_lock(&devices_mutex); list_add_tail(&gluebi->list, &gluebi_devices); mutex_unlock(&devices_mutex); @@ -441,8 +439,8 @@ static int gluebi_updated(struct ubi_volume_info *vi) gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id); if (!gluebi) { mutex_unlock(&devices_mutex); - err_msg("got update notification for unknown UBI device %d " - "volume %d", vi->ubi_num, vi->vol_id); + err_msg("got update notification for unknown UBI device %d volume %d", + vi->ubi_num, vi->vol_id); return -ENOENT; } @@ -468,8 +466,8 @@ static int gluebi_resized(struct ubi_volume_info *vi) gluebi = find_gluebi_nolock(vi->ubi_num, vi->vol_id); if (!gluebi) { mutex_unlock(&devices_mutex); - err_msg("got update notification for unknown UBI device %d " - "volume %d", vi->ubi_num, vi->vol_id); + err_msg("got update notification for unknown UBI device %d volume %d", + vi->ubi_num, vi->vol_id); return -ENOENT; } gluebi->mtd.size = vi->used_bytes; @@ -526,9 +524,9 @@ static void __exit ubi_gluebi_exit(void) err = mtd_device_unregister(mtd); if (err) - err_msg("error %d while removing gluebi MTD device %d, " - "UBI device %d, volume %d - ignoring", err, - mtd->index, gluebi->ubi_num, gluebi->vol_id); + err_msg("error %d while removing gluebi MTD device %d, UBI device %d, volume %d - ignoring", + err, mtd->index, gluebi->ubi_num, + gluebi->vol_id); kfree(mtd->name); kfree(gluebi); } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 172c72ad6d81..823b255ea742 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -183,15 +183,14 @@ retry: } if (retries++ < UBI_IO_RETRIES) { - ubi_warn("error %d%s while reading %d bytes from PEB " - "%d:%d, read only %zd bytes, retry", + ubi_warn("error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; } - ubi_err("error %d%s while reading %d bytes from PEB %d:%d, " - "read %zd bytes", err, errstr, len, pnum, offset, read); + ubi_err("error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", + err, errstr, len, pnum, offset, read); dump_stack(); /* @@ -274,8 +273,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, } if (ubi_dbg_is_write_failure(ubi)) { - ubi_err("cannot write %d bytes to PEB %d:%d " - "(emulated)", len, pnum, offset); + ubi_err("cannot write %d bytes to PEB %d:%d (emulated)", + len, pnum, offset); dump_stack(); return -EIO; } @@ -283,8 +282,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, addr = (loff_t)pnum * ubi->peb_size + offset; err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); if (err) { - ubi_err("error %d while writing %d bytes to PEB %d:%d, written " - "%zd bytes", err, len, pnum, offset, written); + ubi_err("error %d while writing %d bytes to PEB %d:%d, written %zd bytes", + err, len, pnum, offset, written); dump_stack(); ubi_dump_flash(ubi, pnum, offset, len); } else @@ -686,8 +685,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi, leb_start = be32_to_cpu(ec_hdr->data_offset); if (ec_hdr->version != UBI_VERSION) { - ubi_err("node with incompatible UBI version found: " - "this UBI version is %d, image version is %d", + ubi_err("node with incompatible UBI version found: this UBI version is %d, image version is %d", UBI_VERSION, (int)ec_hdr->version); goto bad; } @@ -778,10 +776,10 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { /* The physical eraseblock is supposedly empty */ if (verbose) - ubi_warn("no EC header found at PEB %d, " - "only 0xFF bytes", pnum); - dbg_bld("no EC header found at PEB %d, " - "only 0xFF bytes", pnum); + ubi_warn("no EC header found at PEB %d, only 0xFF bytes", + pnum); + dbg_bld("no EC header found at PEB %d, only 0xFF bytes", + pnum); if (!read_err) return UBI_IO_FF; else @@ -793,12 +791,12 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, * 0xFF bytes. Report that the header is corrupted. */ if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of " - "%08x", pnum, magic, UBI_EC_HDR_MAGIC); + ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + pnum, magic, UBI_EC_HDR_MAGIC); ubi_dump_ec_hdr(ec_hdr); } - dbg_bld("bad magic number at PEB %d: %08x instead of " - "%08x", pnum, magic, UBI_EC_HDR_MAGIC); + dbg_bld("bad magic number at PEB %d: %08x instead of %08x", + pnum, magic, UBI_EC_HDR_MAGIC); return UBI_IO_BAD_HDR; } @@ -807,12 +805,12 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad EC header CRC at PEB %d, calculated " - "%#08x, read %#08x", pnum, crc, hdr_crc); + ubi_warn("bad EC header CRC at PEB %d, calculated %#08x, read %#08x", + pnum, crc, hdr_crc); ubi_dump_ec_hdr(ec_hdr); } - dbg_bld("bad EC header CRC at PEB %d, calculated " - "%#08x, read %#08x", pnum, crc, hdr_crc); + dbg_bld("bad EC header CRC at PEB %d, calculated %#08x, read %#08x", + pnum, crc, hdr_crc); if (!read_err) return UBI_IO_BAD_HDR; @@ -1033,10 +1031,10 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (ubi_check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { if (verbose) - ubi_warn("no VID header found at PEB %d, " - "only 0xFF bytes", pnum); - dbg_bld("no VID header found at PEB %d, " - "only 0xFF bytes", pnum); + ubi_warn("no VID header found at PEB %d, only 0xFF bytes", + pnum); + dbg_bld("no VID header found at PEB %d, only 0xFF bytes", + pnum); if (!read_err) return UBI_IO_FF; else @@ -1044,12 +1042,12 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, } if (verbose) { - ubi_warn("bad magic number at PEB %d: %08x instead of " - "%08x", pnum, magic, UBI_VID_HDR_MAGIC); + ubi_warn("bad magic number at PEB %d: %08x instead of %08x", + pnum, magic, UBI_VID_HDR_MAGIC); ubi_dump_vid_hdr(vid_hdr); } - dbg_bld("bad magic number at PEB %d: %08x instead of " - "%08x", pnum, magic, UBI_VID_HDR_MAGIC); + dbg_bld("bad magic number at PEB %d: %08x instead of %08x", + pnum, magic, UBI_VID_HDR_MAGIC); return UBI_IO_BAD_HDR; } @@ -1058,12 +1056,12 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, if (hdr_crc != crc) { if (verbose) { - ubi_warn("bad CRC at PEB %d, calculated %#08x, " - "read %#08x", pnum, crc, hdr_crc); + ubi_warn("bad CRC at PEB %d, calculated %#08x, read %#08x", + pnum, crc, hdr_crc); ubi_dump_vid_hdr(vid_hdr); } - dbg_bld("bad CRC at PEB %d, calculated %#08x, " - "read %#08x", pnum, crc, hdr_crc); + dbg_bld("bad CRC at PEB %d, calculated %#08x, read %#08x", + pnum, crc, hdr_crc); if (!read_err) return UBI_IO_BAD_HDR; else @@ -1301,8 +1299,8 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); if (hdr_crc != crc) { - ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " - "read %#08x", pnum, crc, hdr_crc); + ubi_err("bad VID header CRC at PEB %d, calculated %#08x, read %#08x", + pnum, crc, hdr_crc); ubi_err("self-check failed for PEB %d", pnum); ubi_dump_vid_hdr(vid_hdr); dump_stack(); @@ -1412,15 +1410,15 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, " - "read %zd bytes", err, len, pnum, offset, read); + ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + err, len, pnum, offset, read); goto error; } err = ubi_check_pattern(buf, 0xFF, len); if (err == 0) { - ubi_err("flash region at PEB %d:%d, length %d does not " - "contain all 0xFF bytes", pnum, offset, len); + ubi_err("flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", + pnum, offset, len); goto fail; } diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index e73f31ba8259..554867dfd18b 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c @@ -128,9 +128,7 @@ void ubi_calculate_reserved(struct ubi_device *ubi) ubi->beb_rsvd_level = ubi->bad_peb_limit - ubi->bad_peb_count; if (ubi->beb_rsvd_level < 0) { ubi->beb_rsvd_level = 0; - ubi_warn("number of bad PEBs (%d) is above the expected limit " - "(%d), not reserving any PEBs for bad PEB handling, " - "will use available PEBs (if any)", + ubi_warn("number of bad PEBs (%d) is above the expected limit (%d), not reserving any PEBs for bad PEB handling, will use available PEBs (if any)", ubi->bad_peb_count, ubi->bad_peb_limit); } } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index f37f5dfd5ca3..b307b990a02a 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -270,8 +270,8 @@ static int vtbl_check(const struct ubi_device *ubi, if (len1 > 0 && len1 == len2 && !strncmp(vtbl[i].name, vtbl[n].name, len1)) { - ubi_err("volumes %d and %d have the same name" - " \"%s\"", i, n, vtbl[i].name); + ubi_err("volumes %d and %d have the same name \"%s\"", + i, n, vtbl[i].name); ubi_dump_vtbl_record(&vtbl[i], i); ubi_dump_vtbl_record(&vtbl[n], n); return -EINVAL; @@ -562,8 +562,8 @@ static int init_volumes(struct ubi_device *ubi, if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) { /* Auto re-size flag may be set only for one volume */ if (ubi->autoresize_vol_id != -1) { - ubi_err("more than one auto-resize volume (%d " - "and %d)", ubi->autoresize_vol_id, i); + ubi_err("more than one auto-resize volume (%d and %d)", + ubi->autoresize_vol_id, i); kfree(vol); return -EINVAL; } -- cgit v1.2.3 From 2a3e85f5963bcdc80e97d6d27dac7c22c43d5259 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 27 Aug 2012 15:13:05 +0300 Subject: UBI: use pr_ helper instead of printk Use 'pr_err()' instead of 'printk(KERN_ERR', etc. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 6 +- drivers/mtd/ubi/build.c | 23 ++++---- drivers/mtd/ubi/debug.c | 149 ++++++++++++++++++++++------------------------- drivers/mtd/ubi/debug.h | 8 +-- drivers/mtd/ubi/gluebi.c | 2 +- drivers/mtd/ubi/ubi.h | 8 +-- 6 files changed, 93 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index a5ad8e9de3e4..fc1bb56d5f1a 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1074,10 +1074,10 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) if (ai->corr_peb_count) { ubi_err("%d PEBs are corrupted and preserved", ai->corr_peb_count); - printk(KERN_ERR "Corrupted PEBs are:"); + pr_err("Corrupted PEBs are:"); list_for_each_entry(aeb, &ai->corr, u.list) - printk(KERN_CONT " %d", aeb->pnum); - printk(KERN_CONT "\n"); + pr_cont(" %d", aeb->pnum); + pr_cont("\n"); /* * If too many PEBs are corrupted, we refuse attaching, diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index ffc257f0c6c8..fe1c12340036 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1304,8 +1304,7 @@ static int __init bytes_str_to_int(const char *str) result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", - str); + ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1321,8 +1320,7 @@ static int __init bytes_str_to_int(const char *str) case '\0': break; default: - printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", - str); + ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1349,20 +1347,20 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - printk(KERN_ERR "UBI error: too many parameters, max. is %d\n", - UBI_MAX_DEVICES); + ubi_err("UBI error: too many parameters, max. is %d\n", + UBI_MAX_DEVICES); return -EINVAL; } len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - printk(KERN_ERR "UBI error: parameter \"%s\" is too long, max. is %d\n", - val, MTD_PARAM_LEN_MAX); + ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } if (len == 0) { - printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - ignored\n"); + pr_warn("UBI warning: empty 'mtd=' parameter - ignored\n"); return 0; } @@ -1376,8 +1374,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) tokens[i] = strsep(&pbuf, ","); if (pbuf) { - printk(KERN_ERR "UBI error: too many arguments at \"%s\"\n", - val); + ubi_err("UBI error: too many arguments at \"%s\"\n", val); return -EINVAL; } @@ -1394,8 +1391,8 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); if (err) { - printk(KERN_ERR "UBI error: bad value for max_beb_per1024 parameter: %s", - tokens[2]); + ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s", + tokens[2]); return -EINVAL; } } diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index f56c9b295da6..33a60a5bc859 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -62,21 +62,15 @@ out: */ void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { - printk(KERN_DEBUG "Erase counter header dump:\n"); - printk(KERN_DEBUG "\tmagic %#08x\n", - be32_to_cpu(ec_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)ec_hdr->version); - printk(KERN_DEBUG "\tec %llu\n", - (long long)be64_to_cpu(ec_hdr->ec)); - printk(KERN_DEBUG "\tvid_hdr_offset %d\n", - be32_to_cpu(ec_hdr->vid_hdr_offset)); - printk(KERN_DEBUG "\tdata_offset %d\n", - be32_to_cpu(ec_hdr->data_offset)); - printk(KERN_DEBUG "\timage_seq %d\n", - be32_to_cpu(ec_hdr->image_seq)); - printk(KERN_DEBUG "\thdr_crc %#08x\n", - be32_to_cpu(ec_hdr->hdr_crc)); - printk(KERN_DEBUG "erase counter header hexdump:\n"); + pr_err("Erase counter header dump:\n"); + pr_err("\tmagic %#08x\n", be32_to_cpu(ec_hdr->magic)); + pr_err("\tversion %d\n", (int)ec_hdr->version); + pr_err("\tec %llu\n", (long long)be64_to_cpu(ec_hdr->ec)); + pr_err("\tvid_hdr_offset %d\n", be32_to_cpu(ec_hdr->vid_hdr_offset)); + pr_err("\tdata_offset %d\n", be32_to_cpu(ec_hdr->data_offset)); + pr_err("\timage_seq %d\n", be32_to_cpu(ec_hdr->image_seq)); + pr_err("\thdr_crc %#08x\n", be32_to_cpu(ec_hdr->hdr_crc)); + pr_err("erase counter header hexdump:\n"); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ec_hdr, UBI_EC_HDR_SIZE, 1); } @@ -87,21 +81,21 @@ void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) */ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { - printk(KERN_DEBUG "Volume identifier header dump:\n"); - printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); - printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); - printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); - printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); - printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); - printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); - printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); - printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); - printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); - printk(KERN_DEBUG "\tsqnum %llu\n", + pr_err("Volume identifier header dump:\n"); + pr_err("\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); + pr_err("\tversion %d\n", (int)vid_hdr->version); + pr_err("\tvol_type %d\n", (int)vid_hdr->vol_type); + pr_err("\tcopy_flag %d\n", (int)vid_hdr->copy_flag); + pr_err("\tcompat %d\n", (int)vid_hdr->compat); + pr_err("\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); + pr_err("\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); + pr_err("\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); + pr_err("\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); + pr_err("\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); + pr_err("\tsqnum %llu\n", (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); - printk(KERN_DEBUG "\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); - printk(KERN_DEBUG "Volume identifier header hexdump:\n"); + pr_err("\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); + pr_err("Volume identifier header hexdump:\n"); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, vid_hdr, UBI_VID_HDR_SIZE, 1); } @@ -112,25 +106,25 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) */ void ubi_dump_vol_info(const struct ubi_volume *vol) { - printk(KERN_DEBUG "Volume information dump:\n"); - printk(KERN_DEBUG "\tvol_id %d\n", vol->vol_id); - printk(KERN_DEBUG "\treserved_pebs %d\n", vol->reserved_pebs); - printk(KERN_DEBUG "\talignment %d\n", vol->alignment); - printk(KERN_DEBUG "\tdata_pad %d\n", vol->data_pad); - printk(KERN_DEBUG "\tvol_type %d\n", vol->vol_type); - printk(KERN_DEBUG "\tname_len %d\n", vol->name_len); - printk(KERN_DEBUG "\tusable_leb_size %d\n", vol->usable_leb_size); - printk(KERN_DEBUG "\tused_ebs %d\n", vol->used_ebs); - printk(KERN_DEBUG "\tused_bytes %lld\n", vol->used_bytes); - printk(KERN_DEBUG "\tlast_eb_bytes %d\n", vol->last_eb_bytes); - printk(KERN_DEBUG "\tcorrupted %d\n", vol->corrupted); - printk(KERN_DEBUG "\tupd_marker %d\n", vol->upd_marker); + pr_err("Volume information dump:\n"); + pr_err("\tvol_id %d\n", vol->vol_id); + pr_err("\treserved_pebs %d\n", vol->reserved_pebs); + pr_err("\talignment %d\n", vol->alignment); + pr_err("\tdata_pad %d\n", vol->data_pad); + pr_err("\tvol_type %d\n", vol->vol_type); + pr_err("\tname_len %d\n", vol->name_len); + pr_err("\tusable_leb_size %d\n", vol->usable_leb_size); + pr_err("\tused_ebs %d\n", vol->used_ebs); + pr_err("\tused_bytes %lld\n", vol->used_bytes); + pr_err("\tlast_eb_bytes %d\n", vol->last_eb_bytes); + pr_err("\tcorrupted %d\n", vol->corrupted); + pr_err("\tupd_marker %d\n", vol->upd_marker); if (vol->name_len <= UBI_VOL_NAME_MAX && strnlen(vol->name, vol->name_len + 1) == vol->name_len) { - printk(KERN_DEBUG "\tname %s\n", vol->name); + pr_err("\tname %s\n", vol->name); } else { - printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n", + pr_err("\t1st 5 characters of name: %c%c%c%c%c\n", vol->name[0], vol->name[1], vol->name[2], vol->name[3], vol->name[4]); } @@ -145,29 +139,28 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { int name_len = be16_to_cpu(r->name_len); - printk(KERN_DEBUG "Volume table record %d dump:\n", idx); - printk(KERN_DEBUG "\treserved_pebs %d\n", - be32_to_cpu(r->reserved_pebs)); - printk(KERN_DEBUG "\talignment %d\n", be32_to_cpu(r->alignment)); - printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(r->data_pad)); - printk(KERN_DEBUG "\tvol_type %d\n", (int)r->vol_type); - printk(KERN_DEBUG "\tupd_marker %d\n", (int)r->upd_marker); - printk(KERN_DEBUG "\tname_len %d\n", name_len); + pr_err("Volume table record %d dump:\n", idx); + pr_err("\treserved_pebs %d\n", be32_to_cpu(r->reserved_pebs)); + pr_err("\talignment %d\n", be32_to_cpu(r->alignment)); + pr_err("\tdata_pad %d\n", be32_to_cpu(r->data_pad)); + pr_err("\tvol_type %d\n", (int)r->vol_type); + pr_err("\tupd_marker %d\n", (int)r->upd_marker); + pr_err("\tname_len %d\n", name_len); if (r->name[0] == '\0') { - printk(KERN_DEBUG "\tname NULL\n"); + pr_err("\tname NULL\n"); return; } if (name_len <= UBI_VOL_NAME_MAX && strnlen(&r->name[0], name_len + 1) == name_len) { - printk(KERN_DEBUG "\tname %s\n", &r->name[0]); + pr_err("\tname %s\n", &r->name[0]); } else { - printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n", + pr_err("\t1st 5 characters of name: %c%c%c%c%c\n", r->name[0], r->name[1], r->name[2], r->name[3], r->name[4]); } - printk(KERN_DEBUG "\tcrc %#08x\n", be32_to_cpu(r->crc)); + pr_err("\tcrc %#08x\n", be32_to_cpu(r->crc)); } /** @@ -176,15 +169,15 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) */ void ubi_dump_av(const struct ubi_ainf_volume *av) { - printk(KERN_DEBUG "Volume attaching information dump:\n"); - printk(KERN_DEBUG "\tvol_id %d\n", av->vol_id); - printk(KERN_DEBUG "\thighest_lnum %d\n", av->highest_lnum); - printk(KERN_DEBUG "\tleb_count %d\n", av->leb_count); - printk(KERN_DEBUG "\tcompat %d\n", av->compat); - printk(KERN_DEBUG "\tvol_type %d\n", av->vol_type); - printk(KERN_DEBUG "\tused_ebs %d\n", av->used_ebs); - printk(KERN_DEBUG "\tlast_data_size %d\n", av->last_data_size); - printk(KERN_DEBUG "\tdata_pad %d\n", av->data_pad); + pr_err("Volume attaching information dump:\n"); + pr_err("\tvol_id %d\n", av->vol_id); + pr_err("\thighest_lnum %d\n", av->highest_lnum); + pr_err("\tleb_count %d\n", av->leb_count); + pr_err("\tcompat %d\n", av->compat); + pr_err("\tvol_type %d\n", av->vol_type); + pr_err("\tused_ebs %d\n", av->used_ebs); + pr_err("\tlast_data_size %d\n", av->last_data_size); + pr_err("\tdata_pad %d\n", av->data_pad); } /** @@ -194,13 +187,13 @@ void ubi_dump_av(const struct ubi_ainf_volume *av) */ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type) { - printk(KERN_DEBUG "eraseblock attaching information dump:\n"); - printk(KERN_DEBUG "\tec %d\n", aeb->ec); - printk(KERN_DEBUG "\tpnum %d\n", aeb->pnum); + pr_err("eraseblock attaching information dump:\n"); + pr_err("\tec %d\n", aeb->ec); + pr_err("\tpnum %d\n", aeb->pnum); if (type == 0) { - printk(KERN_DEBUG "\tlnum %d\n", aeb->lnum); - printk(KERN_DEBUG "\tscrub %d\n", aeb->scrub); - printk(KERN_DEBUG "\tsqnum %llu\n", aeb->sqnum); + pr_err("\tlnum %d\n", aeb->lnum); + pr_err("\tscrub %d\n", aeb->scrub); + pr_err("\tsqnum %llu\n", aeb->sqnum); } } @@ -212,16 +205,16 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) { char nm[17]; - printk(KERN_DEBUG "Volume creation request dump:\n"); - printk(KERN_DEBUG "\tvol_id %d\n", req->vol_id); - printk(KERN_DEBUG "\talignment %d\n", req->alignment); - printk(KERN_DEBUG "\tbytes %lld\n", (long long)req->bytes); - printk(KERN_DEBUG "\tvol_type %d\n", req->vol_type); - printk(KERN_DEBUG "\tname_len %d\n", req->name_len); + pr_err("Volume creation request dump:\n"); + pr_err("\tvol_id %d\n", req->vol_id); + pr_err("\talignment %d\n", req->alignment); + pr_err("\tbytes %lld\n", (long long)req->bytes); + pr_err("\tvol_type %d\n", req->vol_type); + pr_err("\tname_len %d\n", req->name_len); memcpy(nm, req->name, 16); nm[16] = 0; - printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm); + pr_err("\t1st 16 characters of name: %s\n", nm); } /** diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index d9e89ec90983..ea4cb7ca3352 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -29,13 +29,13 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); #define ubi_assert(expr) do { \ if (unlikely(!(expr))) { \ - printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \ + pr_crit("UBI assert failed in %s at %u (pid %d)\n", \ __func__, __LINE__, current->pid); \ dump_stack(); \ } \ } while (0) -#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ +#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a) \ print_hex_dump(l, ps, pt, r, g, b, len, a) #define ubi_dbg_msg(type, fmt, ...) \ @@ -43,8 +43,8 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); ##__VA_ARGS__) /* Just a debugging messages not related to any specific UBI subsystem */ -#define dbg_msg(fmt, ...) \ - printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ +#define dbg_msg(fmt, ...) \ + pr_err("UBI DBG (pid %d): %s: " fmt "\n", \ current->pid, __func__, ##__VA_ARGS__) /* General debugging messages */ diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 388428291af1..dd8f6bdab7b4 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -41,7 +41,7 @@ #include "ubi-media.h" #define err_msg(fmt, ...) \ - printk(KERN_DEBUG "gluebi (pid %d): %s: " fmt "\n", \ + pr_err("gluebi (pid %d): %s: " fmt "\n", \ current->pid, __func__, ##__VA_ARGS__) /** diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 2a2475b9ec54..383ee43d2425 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -51,12 +51,12 @@ #define UBI_NAME_STR "ubi" /* Normal UBI messages */ -#define ubi_msg(fmt, ...) printk(KERN_NOTICE "UBI: " fmt "\n", ##__VA_ARGS__) +#define ubi_msg(fmt, ...) pr_notice("UBI: " fmt "\n", ##__VA_ARGS__) /* UBI warning messages */ -#define ubi_warn(fmt, ...) printk(KERN_WARNING "UBI warning: %s: " fmt "\n", \ - __func__, ##__VA_ARGS__) +#define ubi_warn(fmt, ...) pr_warn("UBI warning: %s: " fmt "\n", \ + __func__, ##__VA_ARGS__) /* UBI error messages */ -#define ubi_err(fmt, ...) printk(KERN_ERR "UBI error: %s: " fmt "\n", \ +#define ubi_err(fmt, ...) pr_err("UBI error: %s: " fmt "\n", \ __func__, ##__VA_ARGS__) /* Background thread name pattern */ -- cgit v1.2.3 From 1383b0d364e7abb6c3e7b0435d253c9740000817 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 27 Aug 2012 17:14:58 +0300 Subject: UBI: print less MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UBI currently prints a lot of information when it mounts a volume, which bothers some people. Make it less chatty - print only important information by default. Get rid of 'dbg_msg()' macro completely. Reported-by: Uwe Kleine-König Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 8 +++--- drivers/mtd/ubi/build.c | 73 +++++++++++++++++++++--------------------------- drivers/mtd/ubi/cdev.c | 6 ++-- drivers/mtd/ubi/debug.h | 5 ---- drivers/mtd/ubi/io.c | 2 +- drivers/mtd/ubi/vtbl.c | 2 +- drivers/mtd/ubi/wl.c | 2 +- 7 files changed, 42 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index fc1bb56d5f1a..b0539578b753 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -794,8 +794,8 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, pnum); ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); ubi_dump_vid_hdr(vid_hdr); - dbg_msg("hexdump of PEB %d offset %d, length %d", - pnum, ubi->leb_start, ubi->leb_size); + pr_err("hexdump of PEB %d offset %d, length %d", + pnum, ubi->leb_start, ubi->leb_size); ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->peb_buf, ubi->leb_size, 1); err = 1; @@ -1170,7 +1170,7 @@ static struct ubi_attach_info *scan_all(struct ubi_device *ubi) goto out_vidh; } - dbg_msg("scanning is finished"); + ubi_msg("scanning is finished"); /* Calculate mean erase counter */ if (ai->ec_count) @@ -1242,7 +1242,7 @@ int ubi_attach(struct ubi_device *ubi) ubi->corr_peb_count = ai->corr_peb_count; ubi->max_ec = ai->max_ec; ubi->mean_ec = ai->mean_ec; - ubi_msg("max. sequence number: %llu", ai->max_sqnum); + dbg_gen("max. sequence number: %llu", ai->max_sqnum); err = ubi_read_volume_table(ubi, ai); if (err) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index fe1c12340036..ffc067d63b81 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -619,6 +619,9 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) */ static int io_init(struct ubi_device *ubi, int max_beb_per1024) { + dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); + dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); + if (ubi->mtd->numeraseregions != 0) { /* * Some flashes have several erase regions. Different regions @@ -690,11 +693,11 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); - dbg_msg("min_io_size %d", ubi->min_io_size); - dbg_msg("max_write_size %d", ubi->max_write_size); - dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size); - dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize); - dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize); + dbg_gen("min_io_size %d", ubi->min_io_size); + dbg_gen("max_write_size %d", ubi->max_write_size); + dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size); + dbg_gen("ec_hdr_alsize %d", ubi->ec_hdr_alsize); + dbg_gen("vid_hdr_alsize %d", ubi->vid_hdr_alsize); if (ubi->vid_hdr_offset == 0) /* Default offset */ @@ -711,10 +714,10 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); - dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); - dbg_msg("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); - dbg_msg("vid_hdr_shift %d", ubi->vid_hdr_shift); - dbg_msg("leb_start %d", ubi->leb_start); + dbg_gen("vid_hdr_offset %d", ubi->vid_hdr_offset); + dbg_gen("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); + dbg_gen("vid_hdr_shift %d", ubi->vid_hdr_shift); + dbg_gen("leb_start %d", ubi->leb_start); /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { @@ -740,7 +743,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->max_erroneous = ubi->peb_count / 10; if (ubi->max_erroneous < 16) ubi->max_erroneous = 16; - dbg_msg("max_erroneous %d", ubi->max_erroneous); + dbg_gen("max_erroneous %d", ubi->max_erroneous); /* * It may happen that EC and VID headers are situated in one minimal @@ -760,17 +763,6 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->ro_mode = 1; } - ubi_msg("physical eraseblock size: %d bytes (%d KiB)", - ubi->peb_size, ubi->peb_size >> 10); - ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); - ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); - if (ubi->hdrs_min_io_size != ubi->min_io_size) - ubi_msg("sub-page size: %d", - ubi->hdrs_min_io_size); - ubi_msg("VID header offset: %d (aligned %d)", - ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); - ubi_msg("data offset: %d", ubi->leb_start); - /* * Note, ideally, we have to initialize @ubi->bad_peb_count here. But * unfortunately, MTD does not provide this information. We should loop @@ -932,8 +924,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, spin_lock_init(&ubi->volumes_lock); ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); - dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); - dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); err = io_init(ubi, max_beb_per1024); if (err) @@ -976,23 +966,24 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, goto out_debugfs; } - ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); - ubi_msg("MTD device name: \"%s\"", mtd->name); - ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); - ubi_msg("number of good PEBs: %d", ubi->good_peb_count); - ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); - ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count); - ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); - ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); - ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); - ubi_msg("number of user volumes: %d", - ubi->vol_count - UBI_INT_VOL_COUNT); - ubi_msg("available PEBs: %d", ubi->avail_pebs); - ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); - ubi_msg("number of PEBs reserved for bad PEB handling: %d", - ubi->beb_rsvd_pebs); - ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); - ubi_msg("image sequence number: %u", ubi->image_seq); + ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d", + mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num); + ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes", + ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size); + ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d", + ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size); + ubi_msg("VID header offset: %d (aligned %d), data offset: %d", + ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start); + ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", + ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count); + ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d", + ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, + ubi->vtbl_slots); + ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", + ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, + ubi->image_seq); + ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", + ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); /* * The below lock makes sure we do not race with 'ubi_thread()' which @@ -1069,7 +1060,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); - dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); /* * Before freeing anything, we have to stop the background thread to diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 540d2db492ee..dfcc65b33e99 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -754,7 +754,7 @@ static int rename_volumes(struct ubi_device *ubi, re->new_name_len = name_len; memcpy(re->new_name, name, name_len); list_add_tail(&re->list, &rename_list); - dbg_msg("will rename volume %d from \"%s\" to \"%s\"", + dbg_gen("will rename volume %d from \"%s\" to \"%s\"", vol_id, re->desc->vol->name, name); } @@ -812,7 +812,7 @@ static int rename_volumes(struct ubi_device *ubi, re1->remove = 1; re1->desc = desc; list_add(&re1->list, &rename_list); - dbg_msg("will remove volume %d, name \"%s\"", + dbg_gen("will remove volume %d, name \"%s\"", re1->desc->vol->vol_id, re1->desc->vol->name); } @@ -943,7 +943,7 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, { struct ubi_rnvol_req *req; - dbg_msg("re-name volumes"); + dbg_gen("re-name volumes"); req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL); if (!req) { err = -ENOMEM; diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index ea4cb7ca3352..3dbc877d9663 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -42,11 +42,6 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); pr_debug("UBI DBG " type " (pid %d): " fmt "\n", current->pid, \ ##__VA_ARGS__) -/* Just a debugging messages not related to any specific UBI subsystem */ -#define dbg_msg(fmt, ...) \ - pr_err("UBI DBG (pid %d): %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) - /* General debugging messages */ #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__) /* Messages from the eraseblock association sub-system */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 823b255ea742..3881b676c6cd 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -177,7 +177,7 @@ retry: * enabled. A corresponding message will be printed * later, when it is has been scrubbed. */ - dbg_msg("fixable bit-flip detected at PEB %d", pnum); + ubi_msg("fixable bit-flip detected at PEB %d", pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index b307b990a02a..b2d4e97238f9 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -304,7 +304,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_attach_info *ai, struct ubi_vid_hdr *vid_hdr; struct ubi_ainf_peb *new_aeb; - ubi_msg("create volume table (copy #%d)", copy + 1); + dbg_gen("create volume table (copy #%d)", copy + 1); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vid_hdr) diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index bd05276252fb..032fc57f1090 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1201,7 +1201,7 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) { struct ubi_wl_entry *e; - dbg_msg("schedule PEB %d for scrubbing", pnum); + ubi_msg("schedule PEB %d for scrubbing", pnum); retry: spin_lock(&ubi->wl_lock); -- cgit v1.2.3 From 5c19523ccd7ed924726341370c74c69be8b12cf2 Mon Sep 17 00:00:00 2001 From: Jiang Lu Date: Wed, 8 Aug 2012 10:31:01 +0800 Subject: UBI: load after mtd device drivers Use 'late_initcall()' in UBI to make sure it initializes after MTD drivers. Signed-off-by: Jiang Lu Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index ffc067d63b81..769f4810edb6 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1261,7 +1261,7 @@ out: ubi_err("UBI error: cannot initialize UBI, error %d", err); return err; } -module_init(ubi_init); +late_initcall(ubi_init); static void __exit ubi_exit(void) { -- cgit v1.2.3 From c1f1992e69791d7bfc59b097491f560c97015a08 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 31 Aug 2012 14:43:41 -0700 Subject: UBI: fix trivial typo 'it' => 'is' Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index b0539578b753..f236c4685c83 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -79,7 +79,7 @@ * NAND), it is probably a PEB which was being erased when power cut * happened, so this is corruption type 1. However, this is just a guess, * which might be wrong. - * o Otherwise this it corruption type 2. + * o Otherwise this is corruption type 2. */ #include -- cgit v1.2.3 From eea55a9fffc1e2b2e486ea8612236448b9883833 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:41 +0200 Subject: UBI: Add fastmap on-flash data structures Add the on-flash data structures neeed by fastmap to ubi-media.h Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi-media.h | 137 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 468ffbc0eabd..ac2b24d1783d 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h @@ -375,4 +375,141 @@ struct ubi_vtbl_record { __be32 crc; } __packed; +/* UBI fastmap on-flash data structures */ + +#define UBI_FM_SB_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 1) +#define UBI_FM_DATA_VOLUME_ID (UBI_LAYOUT_VOLUME_ID + 2) + +/* fastmap on-flash data structure format version */ +#define UBI_FM_FMT_VERSION 1 + +#define UBI_FM_SB_MAGIC 0x7B11D69F +#define UBI_FM_HDR_MAGIC 0xD4B82EF7 +#define UBI_FM_VHDR_MAGIC 0xFA370ED1 +#define UBI_FM_POOL_MAGIC 0x67AF4D08 +#define UBI_FM_EBA_MAGIC 0xf0c040a8 + +/* A fastmap supber block can be located between PEB 0 and + * UBI_FM_MAX_START */ +#define UBI_FM_MAX_START 64 + +/* A fastmap can use up to UBI_FM_MAX_BLOCKS PEBs */ +#define UBI_FM_MAX_BLOCKS 32 + +/* 5% of the total number of PEBs have to be scanned while attaching + * from a fastmap. + * But the size of this pool is limited to be between UBI_FM_MIN_POOL_SIZE and + * UBI_FM_MAX_POOL_SIZE */ +#define UBI_FM_MIN_POOL_SIZE 8 +#define UBI_FM_MAX_POOL_SIZE 256 + +#define UBI_FM_WL_POOL_SIZE 25 + +/** + * struct ubi_fm_sb - UBI fastmap super block + * @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC) + * @version: format version of this fastmap + * @data_crc: CRC over the fastmap data + * @used_blocks: number of PEBs used by this fastmap + * @block_loc: an array containing the location of all PEBs of the fastmap + * @block_ec: the erase counter of each used PEB + * @sqnum: highest sequence number value at the time while taking the fastmap + * + */ +struct ubi_fm_sb { + __be32 magic; + __u8 version; + __u8 padding1[3]; + __be32 data_crc; + __be32 used_blocks; + __be32 block_loc[UBI_FM_MAX_BLOCKS]; + __be32 block_ec[UBI_FM_MAX_BLOCKS]; + __be64 sqnum; + __u8 padding2[32]; +} __packed; + +/** + * struct ubi_fm_hdr - header of the fastmap data set + * @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC) + * @free_peb_count: number of free PEBs known by this fastmap + * @used_peb_count: number of used PEBs known by this fastmap + * @scrub_peb_count: number of to be scrubbed PEBs known by this fastmap + * @bad_peb_count: number of bad PEBs known by this fastmap + * @erase_peb_count: number of bad PEBs which have to be erased + * @vol_count: number of UBI volumes known by this fastmap + */ +struct ubi_fm_hdr { + __be32 magic; + __be32 free_peb_count; + __be32 used_peb_count; + __be32 scrub_peb_count; + __be32 bad_peb_count; + __be32 erase_peb_count; + __be32 vol_count; + __u8 padding[4]; +} __packed; + +/* struct ubi_fm_hdr is followed by two struct ubi_fm_scan_pool */ + +/** + * struct ubi_fm_scan_pool - Fastmap pool PEBs to be scanned while attaching + * @magic: pool magic numer (%UBI_FM_POOL_MAGIC) + * @size: current pool size + * @max_size: maximal pool size + * @pebs: an array containing the location of all PEBs in this pool + */ +struct ubi_fm_scan_pool { + __be32 magic; + __be16 size; + __be16 max_size; + __be32 pebs[UBI_FM_MAX_POOL_SIZE]; + __be32 padding[4]; +} __packed; + +/* ubi_fm_scan_pool is followed by nfree+nused struct ubi_fm_ec records */ + +/** + * struct ubi_fm_ec - stores the erase counter of a PEB + * @pnum: PEB number + * @ec: ec of this PEB + */ +struct ubi_fm_ec { + __be32 pnum; + __be32 ec; +} __packed; + +/** + * struct ubi_fm_volhdr - Fastmap volume header + * it identifies the start of an eba table + * @magic: Fastmap volume header magic number (%UBI_FM_VHDR_MAGIC) + * @vol_id: volume id of the fastmapped volume + * @vol_type: type of the fastmapped volume + * @data_pad: data_pad value of the fastmapped volume + * @used_ebs: number of used LEBs within this volume + * @last_eb_bytes: number of bytes used in the last LEB + */ +struct ubi_fm_volhdr { + __be32 magic; + __be32 vol_id; + __u8 vol_type; + __u8 padding1[3]; + __be32 data_pad; + __be32 used_ebs; + __be32 last_eb_bytes; + __u8 padding2[8]; +} __packed; + +/* struct ubi_fm_volhdr is followed by one struct ubi_fm_eba records */ + +/** + * struct ubi_fm_eba - denotes an association beween a PEB and LEB + * @magic: EBA table magic number + * @reserved_pebs: number of table entries + * @pnum: PEB number of LEB (LEB is the index) + */ +struct ubi_fm_eba { + __be32 magic; + __be32 reserved_pebs; + __be32 pnum[0]; +} __packed; #endif /* !__UBI_MEDIA_H__ */ -- cgit v1.2.3 From beae6d495646eb311e3623f123a67993a1dcad9b Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:42 +0200 Subject: UBI: Add fastmap stuff to ubi.h This patch adds fastmap specific data structures to ubi.h. It moves also struct ubi_work to ubi.h as it is now needed for more than one c file. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/ubi.h | 116 +++++++++++++++++++++++++++++++++++++++++++++++++- drivers/mtd/ubi/wl.c | 24 ----------- 2 files changed, 115 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 383ee43d2425..b0d3ba2a3dea 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -133,6 +133,17 @@ enum { MOVE_RETRY, }; +/* + * Return codes of the fastmap sub-system + * + * UBI_NO_FASTMAP: No fastmap super block was found + * UBI_BAD_FASTMAP: A fastmap was found but it's unusable + */ +enum { + UBI_NO_FASTMAP = 1, + UBI_BAD_FASTMAP, +}; + /** * struct ubi_wl_entry - wear-leveling entry. * @u.rb: link in the corresponding (free/used) RB-tree @@ -198,6 +209,41 @@ struct ubi_rename_entry { struct ubi_volume_desc; +/** + * struct ubi_fastmap_layout - in-memory fastmap data structure. + * @e: PEBs used by the current fastmap + * @to_be_tortured: if non-zero tortured this PEB + * @used_blocks: number of used PEBs + * @max_pool_size: maximal size of the user pool + * @max_wl_pool_size: maximal size of the pool used by the WL sub-system + */ +struct ubi_fastmap_layout { + struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS]; + int to_be_tortured[UBI_FM_MAX_BLOCKS]; + int used_blocks; + int max_pool_size; + int max_wl_pool_size; +}; + +/** + * struct ubi_fm_pool - in-memory fastmap pool + * @pebs: PEBs in this pool + * @used: number of used PEBs + * @size: total number of PEBs in this pool + * @max_size: maximal size of the pool + * + * A pool gets filled with up to max_size. + * If all PEBs within the pool are used a new fastmap will be written + * to the flash and the pool gets refilled with empty PEBs. + * + */ +struct ubi_fm_pool { + int pebs[UBI_FM_MAX_POOL_SIZE]; + int used; + int size; + int max_size; +}; + /** * struct ubi_volume - UBI volume description data structure. * @dev: device object to make use of the the Linux device model @@ -333,9 +379,21 @@ struct ubi_wl_entry; * @ltree: the lock tree * @alc_mutex: serializes "atomic LEB change" operations * + * @fm_disabled: non-zero if fastmap is disabled (default) + * @fm: in-memory data structure of the currently used fastmap + * @fm_pool: in-memory data structure of the fastmap pool + * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL + * sub-system + * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf + * @fm_buf: vmalloc()'d buffer which holds the raw fastmap + * @fm_size: fastmap size in bytes + * @fm_sem: allows ubi_update_fastmap() to block EBA table changes + * @fm_work: fastmap work queue + * * @used: RB-tree of used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks * @free: RB-tree of free physical eraseblocks + * @free_count: Contains the number of elements in @free * @scrub: RB-tree of physical eraseblocks which need scrubbing * @pq: protection queue (contain physical eraseblocks which are temporarily * protected from the wear-leveling worker) @@ -426,10 +484,22 @@ struct ubi_device { struct rb_root ltree; struct mutex alc_mutex; + /* Fastmap stuff */ + int fm_disabled; + struct ubi_fastmap_layout *fm; + struct ubi_fm_pool fm_pool; + struct ubi_fm_pool fm_wl_pool; + struct rw_semaphore fm_sem; + struct mutex fm_mutex; + void *fm_buf; + size_t fm_size; + struct work_struct fm_work; + /* Wear-leveling sub-system's stuff */ struct rb_root used; struct rb_root erroneous; struct rb_root free; + int free_count; struct rb_root scrub; struct list_head pq[UBI_PROT_QUEUE_LEN]; int pq_head; @@ -596,6 +666,32 @@ struct ubi_attach_info { struct kmem_cache *aeb_slab_cache; }; +/** + * struct ubi_work - UBI work description data structure. + * @list: a link in the list of pending works + * @func: worker function + * @e: physical eraseblock to erase + * @vol_id: the volume ID on which this erasure is being performed + * @lnum: the logical eraseblock number + * @torture: if the physical eraseblock has to be tortured + * @anchor: produce a anchor PEB to by used by fastmap + * + * The @func pointer points to the worker function. If the @cancel argument is + * not zero, the worker has to free the resources and exit immediately. The + * worker has to return zero in case of success and a negative error code in + * case of failure. + */ +struct ubi_work { + struct list_head list; + int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); + /* The below fields are only relevant to erasure works */ + struct ubi_wl_entry *e; + int vol_id; + int lnum; + int torture; + int anchor; +}; + #include "debug.h" extern struct kmem_cache *ubi_wl_entry_slab; @@ -606,7 +702,7 @@ extern struct class *ubi_class; extern struct mutex ubi_devices_mutex; extern struct blocking_notifier_head ubi_notifiers; -/* scan.c */ +/* attach.c */ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips); struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, @@ -664,6 +760,9 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, struct ubi_vid_hdr *vid_hdr); int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai); +unsigned long long ubi_next_sqnum(struct ubi_device *ubi); +int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, + struct ubi_attach_info *ai_scan); /* wl.c */ int ubi_wl_get_peb(struct ubi_device *ubi); @@ -674,6 +773,12 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai); void ubi_wl_close(struct ubi_device *ubi); int ubi_thread(void *u); +struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor); +int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e, + int lnum, int torture); +int ubi_is_erase_work(struct ubi_work *wrk); +void ubi_refill_pools(struct ubi_device *ubi); +int ubi_ensure_anchor_pebs(struct ubi_device *ubi); /* io.c */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, @@ -711,6 +816,15 @@ void ubi_free_internal_volumes(struct ubi_device *ubi); void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di); void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol, struct ubi_volume_info *vi); +/* scan.c */ +int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, + int pnum, const struct ubi_vid_hdr *vid_hdr); + +/* fastmap.c */ +size_t ubi_calc_fm_size(struct ubi_device *ubi); +int ubi_update_fastmap(struct ubi_device *ubi); +int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, + int fm_anchor); /* * ubi_rb_for_each_entry - walk an RB-tree. diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 032fc57f1090..f4d06dbdb2a9 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -135,30 +135,6 @@ */ #define WL_MAX_FAILURES 32 -/** - * struct ubi_work - UBI work description data structure. - * @list: a link in the list of pending works - * @func: worker function - * @e: physical eraseblock to erase - * @vol_id: the volume ID on which this erasure is being performed - * @lnum: the logical eraseblock number - * @torture: if the physical eraseblock has to be tortured - * - * The @func pointer points to the worker function. If the @cancel argument is - * not zero, the worker has to free the resources and exit immediately. The - * worker has to return zero in case of success and a negative error code in - * case of failure. - */ -struct ubi_work { - struct list_head list; - int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); - /* The below fields are only relevant to erasure works */ - struct ubi_wl_entry *e; - int vol_id; - int lnum; - int torture; -}; - static int self_check_ec(struct ubi_device *ubi, int pnum, int ec); static int self_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root); -- cgit v1.2.3 From f81aced8b4d830e253c2df62e236efec1196f162 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:43 +0200 Subject: UBI: Export next_sqnum() Fastmap needs next_sqnum(), rename it to ubi_next_sqnum() and make it non-static. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 6cbc9e7298a7..dccc6f5a12eb 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -57,7 +57,7 @@ * global sequence counter value. It also increases the global sequence * counter. */ -static unsigned long long next_sqnum(struct ubi_device *ubi) +unsigned long long ubi_next_sqnum(struct ubi_device *ubi) { unsigned long long sqnum; @@ -521,7 +521,7 @@ retry: goto out_put; } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); if (err) goto write_error; @@ -632,7 +632,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, } vid_hdr->vol_type = UBI_VID_DYNAMIC; - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); vid_hdr->lnum = cpu_to_be32(lnum); vid_hdr->compat = ubi_get_compat(ubi, vol_id); @@ -692,7 +692,7 @@ write_error: return err; } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); ubi_msg("try another PEB"); goto retry; } @@ -745,7 +745,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, return err; } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); vid_hdr->lnum = cpu_to_be32(lnum); vid_hdr->compat = ubi_get_compat(ubi, vol_id); @@ -810,7 +810,7 @@ write_error: return err; } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); ubi_msg("try another PEB"); goto retry; } @@ -862,7 +862,7 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, if (err) goto out_mutex; - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); vid_hdr->lnum = cpu_to_be32(lnum); vid_hdr->compat = ubi_get_compat(ubi, vol_id); @@ -930,7 +930,7 @@ write_error: goto out_leb_unlock; } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); ubi_msg("try another PEB"); goto retry; } @@ -1089,7 +1089,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, vid_hdr->data_size = cpu_to_be32(data_size); vid_hdr->data_crc = cpu_to_be32(crc); } - vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); if (err) { -- cgit v1.2.3 From d34fec154b4eb75de6732dbdb1e2ffa322d69e20 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:44 +0200 Subject: UBI: Add self_check_eba() self_check_eba() compares two ubi_attach_info objects. Fastmap uses this function for self checks. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index dccc6f5a12eb..a8ef263747da 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -1201,6 +1201,102 @@ static void print_rsvd_warning(struct ubi_device *ubi, ubi->corr_peb_count); } +/** + * self_check_eba - run a self check on the EBA table constructed by fastmap. + * @ubi: UBI device description object + * @ai_fastmap: UBI attach info object created by fastmap + * @ai_scan: UBI attach info object created by scanning + * + * Returns < 0 in case of an internal error, 0 otherwise. + * If a bad EBA table entry was found it will be printed out and + * ubi_assert() triggers. + */ +int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, + struct ubi_attach_info *ai_scan) +{ + int i, j, num_volumes, ret = 0; + int **scan_eba, **fm_eba; + struct ubi_ainf_volume *av; + struct ubi_volume *vol; + struct ubi_ainf_peb *aeb; + struct rb_node *rb; + + num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; + + scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL); + if (!scan_eba) + return -ENOMEM; + + fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL); + if (!fm_eba) { + kfree(scan_eba); + return -ENOMEM; + } + + for (i = 0; i < num_volumes; i++) { + vol = ubi->volumes[i]; + if (!vol) + continue; + + scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba), + GFP_KERNEL); + if (!scan_eba[i]) { + ret = -ENOMEM; + goto out_free; + } + + fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba), + GFP_KERNEL); + if (!fm_eba[i]) { + ret = -ENOMEM; + goto out_free; + } + + for (j = 0; j < vol->reserved_pebs; j++) + scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED; + + av = ubi_find_av(ai_scan, idx2vol_id(ubi, i)); + if (!av) + continue; + + ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) + scan_eba[i][aeb->lnum] = aeb->pnum; + + av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i)); + if (!av) + continue; + + ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb) + fm_eba[i][aeb->lnum] = aeb->pnum; + + for (j = 0; j < vol->reserved_pebs; j++) { + if (scan_eba[i][j] != fm_eba[i][j]) { + if (scan_eba[i][j] == UBI_LEB_UNMAPPED || + fm_eba[i][j] == UBI_LEB_UNMAPPED) + continue; + + ubi_err("LEB:%i:%i is PEB:%i instead of %i!", + vol->vol_id, i, fm_eba[i][j], + scan_eba[i][j]); + ubi_assert(0); + } + } + } + +out_free: + for (i = 0; i < num_volumes; i++) { + if (!ubi->volumes[i]) + continue; + + kfree(scan_eba[i]); + kfree(fm_eba[i]); + } + + kfree(scan_eba); + kfree(fm_eba); + return ret; +} + /** * ubi_eba_init - initialize the EBA sub-system using attaching information. * @ubi: UBI device description object -- cgit v1.2.3 From 5367747956f0aab5a56a232aa2e2f7121d7ffe79 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:45 +0200 Subject: UBI: Add fastmap bits to build.c Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 769f4810edb6..9d36595cef30 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -76,7 +76,10 @@ static int __initdata mtd_devs; /* MTD devices specification parameters */ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES]; - +#ifdef CONFIG_MTD_UBI_FASTMAP +/* UBI module parameter to enable fastmap automatically on non-fastmap images */ +static bool fm_autoconvert; +#endif /* Root UBI "class" object (corresponds to '//class/ubi/') */ struct class *ubi_class; @@ -153,6 +156,19 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) ubi_do_get_device_info(ubi, &nt.di); ubi_do_get_volume_info(ubi, vol, &nt.vi); + +#ifdef CONFIG_MTD_UBI_FASTMAP + switch (ntype) { + case UBI_VOLUME_ADDED: + case UBI_VOLUME_REMOVED: + case UBI_VOLUME_RESIZED: + case UBI_VOLUME_RENAMED: + if (ubi_update_fastmap(ubi)) { + ubi_err("Unable to update fastmap!"); + ubi_ro_mode(ubi); + } + } +#endif return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); } @@ -918,10 +934,40 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; +#ifdef CONFIG_MTD_UBI_FASTMAP + ubi->fm_pool.used = ubi->fm_pool.size = 0; + ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0; + + /* + * fm_pool.max_size is 5% of the total number of PEBs but it's also + * between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE. + */ + ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size, + ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE); + if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) + ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; + + ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; + ubi->fm_disabled = !fm_autoconvert; + + if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) + <= UBI_FM_MAX_START) { + ubi_err("More than %i PEBs are needed for fastmap, sorry.", + UBI_FM_MAX_START); + ubi->fm_disabled = 1; + } + + ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); +#else + ubi->fm_disabled = 1; +#endif mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->device_mutex); spin_lock_init(&ubi->volumes_lock); + mutex_init(&ubi->fm_mutex); + init_rwsem(&ubi->fm_sem); ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); @@ -934,6 +980,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi->peb_buf) goto out_free; +#ifdef CONFIG_MTD_UBI_FASTMAP + ubi->fm_size = ubi_calc_fm_size(ubi); + ubi->fm_buf = vzalloc(ubi->fm_size); + if (!ubi->fm_buf) + goto out_free; +#endif err = ubi_debugging_init_dev(ubi); if (err) goto out_free; @@ -1012,6 +1064,7 @@ out_debugging: ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf); + vfree(ubi->fm_buf); if (ref) put_device(&ubi->dev); else @@ -1061,7 +1114,11 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); - +#ifdef CONFIG_MTD_UBI_FASTMAP + /* If we don't write a new fastmap at detach time we lose all + * EC updates that have been made since the last written fastmap. */ + ubi_update_fastmap(ubi); +#endif /* * Before freeing anything, we have to stop the background thread to * prevent it from doing anything on this device while we are freeing. @@ -1077,12 +1134,14 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_debugfs_exit_dev(ubi); uif_close(ubi); + ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf); + vfree(ubi->fm_buf); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); put_device(&ubi->dev); return 0; @@ -1404,7 +1463,10 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd= Date: Wed, 26 Sep 2012 17:51:46 +0200 Subject: UBI: Wire-up ->fm_sem Fastmap uses ->fm_sem to stop EBA changes while writing a new fastmap. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/eba.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index a8ef263747da..9538380f6959 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -340,7 +340,9 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; + up_read(&ubi->fm_sem); err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0); out_unlock: @@ -548,7 +550,9 @@ retry: mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = new_pnum; + up_read(&ubi->fm_sem); ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); ubi_msg("data was successfully recovered"); @@ -665,7 +669,9 @@ retry: } } + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -783,7 +789,9 @@ retry: } ubi_assert(vol->eba_tbl[lnum] < 0); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); @@ -904,7 +912,9 @@ retry: goto out_leb_unlock; } + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = pnum; + up_read(&ubi->fm_sem); out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); @@ -1151,7 +1161,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } ubi_assert(vol->eba_tbl[lnum] == from); + down_read(&ubi->fm_sem); vol->eba_tbl[lnum] = to; + up_read(&ubi->fm_sem); out_unlock_buf: mutex_unlock(&ubi->buf_mutex); -- cgit v1.2.3 From 8076392de98803273ae354a8a61628af9c9dcbbd Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:47 +0200 Subject: UBI: Add fastmap stuff to attach.c - Export compare_lebs() as fastmap needs this function. - Implement fastmap scan logic. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 386 +++++++++++++++++++++++++++++++---------------- drivers/mtd/ubi/build.c | 2 +- drivers/mtd/ubi/ubi.h | 2 +- 3 files changed, 260 insertions(+), 130 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index f236c4685c83..f36a5139a40d 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -300,7 +300,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, } /** - * compare_lebs - find out which logical eraseblock is newer. + * ubi_compare_lebs - find out which logical eraseblock is newer. * @ubi: UBI device description object * @aeb: first logical eraseblock to compare * @pnum: physical eraseblock number of the second logical eraseblock to @@ -319,7 +319,7 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, * o bit 2 is cleared: the older LEB is not corrupted; * o bit 2 is set: the older LEB is corrupted. */ -static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, +int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, int pnum, const struct ubi_vid_hdr *vid_hdr) { void *buf; @@ -337,7 +337,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, * support these images anymore. Well, those images still work, * but only if no unclean reboots happened. */ - ubi_err("unsupported on-flash UBI format\n"); + ubi_err("unsupported on-flash UBI format"); return -EINVAL; } @@ -507,7 +507,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * sequence numbers. We still can attach these images, unless * there is a need to distinguish between old and new * eraseblocks, in which case we'll refuse the image in - * 'compare_lebs()'. In other words, we attach old clean + * 'ubi_compare_lebs()'. In other words, we attach old clean * images, but refuse attaching old images with duplicated * logical eraseblocks because there was an unclean reboot. */ @@ -523,7 +523,7 @@ int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, * Now we have to drop the older one and preserve the newer * one. */ - cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr); + cmp_res = ubi_compare_lebs(ubi, aeb, pnum, vid_hdr); if (cmp_res < 0) return cmp_res; @@ -748,7 +748,7 @@ struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, /** * check_corruption - check the data area of PEB. * @ubi: UBI device description object - * @vid_hrd: the (corrupted) VID header of this PEB + * @vid_hdr: the (corrupted) VID header of this PEB * @pnum: the physical eraseblock number to check * * This is a helper function which is used to distinguish between VID header @@ -810,6 +810,8 @@ out_unlock: * @ubi: UBI device description object * @ai: attaching information * @pnum: the physical eraseblock number + * @vid: The volume ID of the found volume will be stored in this pointer + * @sqnum: The sqnum of the found volume will be stored in this pointer * * This function reads UBI headers of PEB @pnum, checks them, and adds * information about this PEB to the corresponding list or RB-tree in the @@ -817,10 +819,10 @@ out_unlock: * successfully handled and a negative error code in case of failure. */ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, - int pnum) + int pnum, int *vid, unsigned long long *sqnum) { long long uninitialized_var(ec); - int err, bitflips = 0, vol_id, ec_err = 0; + int err, bitflips = 0, vol_id = -1, ec_err = 0; dbg_bld("scan PEB %d", pnum); @@ -991,14 +993,21 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, } vol_id = be32_to_cpu(vidh->vol_id); + if (vid) + *vid = vol_id; + if (sqnum) + *sqnum = be64_to_cpu(vidh->sqnum); if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { int lnum = be32_to_cpu(vidh->lnum); /* Unsupported internal volume */ switch (vidh->compat) { case UBI_COMPAT_DELETE: - ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", - vol_id, lnum); + if (vol_id != UBI_FM_SB_VOLUME_ID + && vol_id != UBI_FM_DATA_VOLUME_ID) { + ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", + vol_id, lnum); + } err = add_to_list(ai, pnum, vol_id, lnum, ec, 1, &ai->erase); if (err) @@ -1120,52 +1129,127 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) return 0; } +/** + * destroy_av - free volume attaching information. + * @av: volume attaching information + * @ai: attaching information + * + * This function destroys the volume attaching information. + */ +static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) +{ + struct ubi_ainf_peb *aeb; + struct rb_node *this = av->root.rb_node; + + while (this) { + if (this->rb_left) + this = this->rb_left; + else if (this->rb_right) + this = this->rb_right; + else { + aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &aeb->u.rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + } + kfree(av); +} + +/** + * destroy_ai - destroy attaching information. + * @ai: attaching information + */ +static void destroy_ai(struct ubi_attach_info *ai) +{ + struct ubi_ainf_peb *aeb, *aeb_tmp; + struct ubi_ainf_volume *av; + struct rb_node *rb; + + list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { + list_del(&aeb->u.list); + kmem_cache_free(ai->aeb_slab_cache, aeb); + } + + /* Destroy the volume RB-tree */ + rb = ai->volumes.rb_node; + while (rb) { + if (rb->rb_left) + rb = rb->rb_left; + else if (rb->rb_right) + rb = rb->rb_right; + else { + av = rb_entry(rb, struct ubi_ainf_volume, rb); + + rb = rb_parent(rb); + if (rb) { + if (rb->rb_left == &av->rb) + rb->rb_left = NULL; + else + rb->rb_right = NULL; + } + + destroy_av(ai, av); + } + } + + if (ai->aeb_slab_cache) + kmem_cache_destroy(ai->aeb_slab_cache); + + kfree(ai); +} + /** * scan_all - scan entire MTD device. * @ubi: UBI device description object + * @ai: attach info object + * @start: start scanning at this PEB * * This function does full scanning of an MTD device and returns complete * information about it in form of a "struct ubi_attach_info" object. In case * of failure, an error code is returned. */ -static struct ubi_attach_info *scan_all(struct ubi_device *ubi) +static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, + int start) { int err, pnum; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb; - struct ubi_attach_info *ai; - - ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); - if (!ai) - return ERR_PTR(-ENOMEM); - - INIT_LIST_HEAD(&ai->corr); - INIT_LIST_HEAD(&ai->free); - INIT_LIST_HEAD(&ai->erase); - INIT_LIST_HEAD(&ai->alien); - ai->volumes = RB_ROOT; err = -ENOMEM; - ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", - sizeof(struct ubi_ainf_peb), - 0, 0, NULL); - if (!ai->aeb_slab_cache) - goto out_ai; ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); if (!ech) - goto out_ai; + return err; vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); if (!vidh) goto out_ech; - for (pnum = 0; pnum < ubi->peb_count; pnum++) { + for (pnum = start; pnum < ubi->peb_count; pnum++) { cond_resched(); dbg_gen("process PEB %d", pnum); - err = scan_peb(ubi, ai, pnum); + err = scan_peb(ubi, ai, pnum, NULL, NULL); if (err < 0) goto out_vidh; } @@ -1210,32 +1294,144 @@ static struct ubi_attach_info *scan_all(struct ubi_device *ubi) ubi_free_vid_hdr(ubi, vidh); kfree(ech); - return ai; + return 0; out_vidh: ubi_free_vid_hdr(ubi, vidh); out_ech: kfree(ech); -out_ai: - ubi_destroy_ai(ai); - return ERR_PTR(err); + return err; +} + +#ifdef CONFIG_MTD_UBI_FASTMAP + +/** + * scan_fastmap - try to find a fastmap and attach from it. + * @ubi: UBI device description object + * @ai: attach info object + * + * Returns 0 on success, negative return values indicate an internal + * error. + * UBI_NO_FASTMAP denotes that no fastmap was found. + * UBI_BAD_FASTMAP denotes that the found fastmap was invalid. + */ +static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai) +{ + int err, pnum, fm_anchor = -1; + unsigned long long max_sqnum = 0; + + err = -ENOMEM; + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) + goto out; + + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vidh) + goto out_ech; + + for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) { + int vol_id = -1; + unsigned long long sqnum = -1; + cond_resched(); + + dbg_gen("process PEB %d", pnum); + err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum); + if (err < 0) + goto out_vidh; + + if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) { + max_sqnum = sqnum; + fm_anchor = pnum; + } + } + + ubi_free_vid_hdr(ubi, vidh); + kfree(ech); + + if (fm_anchor < 0) + return UBI_NO_FASTMAP; + + return ubi_scan_fastmap(ubi, ai, fm_anchor); + +out_vidh: + ubi_free_vid_hdr(ubi, vidh); +out_ech: + kfree(ech); +out: + return err; +} + +#endif + +static struct ubi_attach_info *alloc_ai(const char *slab_name) +{ + struct ubi_attach_info *ai; + + ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + if (!ai) + return ai; + + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; + ai->aeb_slab_cache = kmem_cache_create(slab_name, + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) { + kfree(ai); + ai = NULL; + } + + return ai; } /** * ubi_attach - attach an MTD device. * @ubi: UBI device descriptor + * @force_scan: if set to non-zero attach by scanning * * This function returns zero in case of success and a negative error code in * case of failure. */ -int ubi_attach(struct ubi_device *ubi) +int ubi_attach(struct ubi_device *ubi, int force_scan) { int err; struct ubi_attach_info *ai; - ai = scan_all(ubi); - if (IS_ERR(ai)) - return PTR_ERR(ai); + ai = alloc_ai("ubi_aeb_slab_cache"); + if (!ai) + return -ENOMEM; + +#ifdef CONFIG_MTD_UBI_FASTMAP + /* On small flash devices we disable fastmap in any case. */ + if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { + ubi->fm_disabled = 1; + force_scan = 1; + } + + if (force_scan) + err = scan_all(ubi, ai, 0); + else { + err = scan_fast(ubi, ai); + if (err > 0) { + if (err != UBI_NO_FASTMAP) { + destroy_ai(ai); + ai = alloc_ai("ubi_aeb_slab_cache2"); + if (!ai) + return -ENOMEM; + } + + err = scan_all(ubi, ai, UBI_FM_MAX_START); + } + } +#else + err = scan_all(ubi, ai, 0); +#endif + if (err) + goto out_ai; ubi->bad_peb_count = ai->bad_peb_count; ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; @@ -1256,7 +1452,29 @@ int ubi_attach(struct ubi_device *ubi) if (err) goto out_wl; - ubi_destroy_ai(ai); +#ifdef CONFIG_MTD_UBI_FASTMAP + if (ubi->fm && ubi->dbg->chk_gen) { + struct ubi_attach_info *scan_ai; + + scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); + if (!scan_ai) + goto out_wl; + + err = scan_all(ubi, scan_ai, 0); + if (err) { + destroy_ai(scan_ai); + goto out_wl; + } + + err = self_check_eba(ubi, ai, scan_ai); + destroy_ai(scan_ai); + + if (err) + goto out_wl; + } +#endif + + destroy_ai(ai); return 0; out_wl: @@ -1265,98 +1483,10 @@ out_vtbl: ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); out_ai: - ubi_destroy_ai(ai); + destroy_ai(ai); return err; } -/** - * destroy_av - free volume attaching information. - * @av: volume attaching information - * @ai: attaching information - * - * This function destroys the volume attaching information. - */ -static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) -{ - struct ubi_ainf_peb *aeb; - struct rb_node *this = av->root.rb_node; - - while (this) { - if (this->rb_left) - this = this->rb_left; - else if (this->rb_right) - this = this->rb_right; - else { - aeb = rb_entry(this, struct ubi_ainf_peb, u.rb); - this = rb_parent(this); - if (this) { - if (this->rb_left == &aeb->u.rb) - this->rb_left = NULL; - else - this->rb_right = NULL; - } - - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - } - kfree(av); -} - -/** - * ubi_destroy_ai - destroy attaching information. - * @ai: attaching information - */ -void ubi_destroy_ai(struct ubi_attach_info *ai) -{ - struct ubi_ainf_peb *aeb, *aeb_tmp; - struct ubi_ainf_volume *av; - struct rb_node *rb; - - list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { - list_del(&aeb->u.list); - kmem_cache_free(ai->aeb_slab_cache, aeb); - } - - /* Destroy the volume RB-tree */ - rb = ai->volumes.rb_node; - while (rb) { - if (rb->rb_left) - rb = rb->rb_left; - else if (rb->rb_right) - rb = rb->rb_right; - else { - av = rb_entry(rb, struct ubi_ainf_volume, rb); - - rb = rb_parent(rb); - if (rb) { - if (rb->rb_left == &av->rb) - rb->rb_left = NULL; - else - rb->rb_right = NULL; - } - - destroy_av(ai, av); - } - } - - if (ai->aeb_slab_cache) - kmem_cache_destroy(ai->aeb_slab_cache); - - kfree(ai); -} - /** * self_check_ai - check the attaching information. * @ubi: UBI device description object diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 9d36595cef30..990c93c61d07 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -990,7 +990,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (err) goto out_free; - err = ubi_attach(ubi); + err = ubi_attach(ubi, 0); if (err) { ubi_err("failed to attach mtd%d, error %d", mtd->index, err); goto out_debugging; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index b0d3ba2a3dea..7d57469723cf 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -710,7 +710,7 @@ struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av); struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi, struct ubi_attach_info *ai); -int ubi_attach(struct ubi_device *ubi); +int ubi_attach(struct ubi_device *ubi, int force_scan); void ubi_destroy_ai(struct ubi_attach_info *ai); /* vtbl.c */ -- cgit v1.2.3 From fbe93d5f5815df07db96f1e489211de4ff904e90 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:48 +0200 Subject: UBI: Add fastmap support to the WL sub-system To make fastmap possible the WL sub-system needs some changes. Mostly to support fastmaps pools. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 575 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 531 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index f4d06dbdb2a9..da7b44998b40 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -141,6 +141,42 @@ static int self_check_in_wl_tree(const struct ubi_device *ubi, static int self_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *e); +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * update_fastmap_work_fn - calls ubi_update_fastmap from a work queue + * @wrk: the work description object + */ +static void update_fastmap_work_fn(struct work_struct *wrk) +{ + struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work); + ubi_update_fastmap(ubi); +} + +/** + * ubi_ubi_is_fm_block - returns 1 if a PEB is currently used in a fastmap. + * @ubi: UBI device description object + * @pnum: the to be checked PEB + */ +static int ubi_is_fm_block(struct ubi_device *ubi, int pnum) +{ + int i; + + if (!ubi->fm) + return 0; + + for (i = 0; i < ubi->fm->used_blocks; i++) + if (ubi->fm->e[i]->pnum == pnum) + return 1; + + return 0; +} +#else +static int ubi_is_fm_block(struct ubi_device *ubi, int pnum) +{ + return 0; +} +#endif + /** * wl_tree_add - add a wear-leveling entry to a WL RB-tree. * @e: the wear-leveling entry to add @@ -237,18 +273,16 @@ static int produce_free_peb(struct ubi_device *ubi) { int err; - spin_lock(&ubi->wl_lock); while (!ubi->free.rb_node) { spin_unlock(&ubi->wl_lock); dbg_wl("do one work synchronously"); err = do_work(ubi); - if (err) - return err; spin_lock(&ubi->wl_lock); + if (err) + return err; } - spin_unlock(&ubi->wl_lock); return 0; } @@ -315,16 +349,18 @@ static void prot_queue_add(struct ubi_device *ubi, struct ubi_wl_entry *e) /** * find_wl_entry - find wear-leveling entry closest to certain erase counter. + * @ubi: UBI device description object * @root: the RB-tree where to look for * @diff: maximum possible difference from the smallest erase counter * * This function looks for a wear leveling entry with erase counter closest to * min + @diff, where min is the smallest erase counter. */ -static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) +static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi, + struct rb_root *root, int diff) { struct rb_node *p; - struct ubi_wl_entry *e; + struct ubi_wl_entry *e, *prev_e = NULL; int max; e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); @@ -339,35 +375,143 @@ static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff) p = p->rb_left; else { p = p->rb_right; + prev_e = e; e = e1; } } + /* If no fastmap has been written and this WL entry can be used + * as anchor PEB, hold it back and return the second best WL entry + * such that fastmap can use the anchor PEB later. */ + if (prev_e && !ubi->fm_disabled && + !ubi->fm && e->pnum < UBI_FM_MAX_START) + return prev_e; + return e; } /** - * ubi_wl_get_peb - get a physical eraseblock. + * find_mean_wl_entry - find wear-leveling entry with medium erase counter. + * @ubi: UBI device description object + * @root: the RB-tree where to look for + * + * This function looks for a wear leveling entry with medium erase counter, + * but not greater or equivalent than the lowest erase counter plus + * %WL_FREE_MAX_DIFF/2. + */ +static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi, + struct rb_root *root) +{ + struct ubi_wl_entry *e, *first, *last; + + first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); + last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb); + + if (last->ec - first->ec < WL_FREE_MAX_DIFF) { + e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb); + +#ifdef CONFIG_MTD_UBI_FASTMAP + /* If no fastmap has been written and this WL entry can be used + * as anchor PEB, hold it back and return the second best + * WL entry such that fastmap can use the anchor PEB later. */ + if (e && !ubi->fm_disabled && !ubi->fm && + e->pnum < UBI_FM_MAX_START) + e = rb_entry(rb_next(root->rb_node), + struct ubi_wl_entry, u.rb); +#endif + } else + e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2); + + return e; +} + +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB. + * @root: the RB-tree where to look for + */ +static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root) +{ + struct rb_node *p; + struct ubi_wl_entry *e, *victim = NULL; + int max_ec = UBI_MAX_ERASECOUNTER; + + ubi_rb_for_each_entry(p, e, root, u.rb) { + if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) { + victim = e; + max_ec = e->ec; + } + } + + return victim; +} + +static int anchor_pebs_avalible(struct rb_root *root) +{ + struct rb_node *p; + struct ubi_wl_entry *e; + + ubi_rb_for_each_entry(p, e, root, u.rb) + if (e->pnum < UBI_FM_MAX_START) + return 1; + + return 0; +} + +/** + * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number. + * @ubi: UBI device description object + * @anchor: This PEB will be used as anchor PEB by fastmap + * + * The function returns a physical erase block with a given maximal number + * and removes it from the wl subsystem. + * Must be called with wl_lock held! + */ +struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) +{ + struct ubi_wl_entry *e = NULL; + + if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1)) + goto out; + + if (anchor) + e = find_anchor_wl_entry(&ubi->free); + else + e = find_mean_wl_entry(ubi, &ubi->free); + + if (!e) + goto out; + + self_check_in_wl_tree(ubi, e, &ubi->free); + + /* remove it from the free list, + * the wl subsystem does no longer know this erase block */ + rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; +out: + return e; +} +#endif + +/** + * __wl_get_peb - get a physical eraseblock. * @ubi: UBI device description object * * This function returns a physical eraseblock in case of success and a * negative error code in case of failure. Might sleep. */ -int ubi_wl_get_peb(struct ubi_device *ubi) +static int __wl_get_peb(struct ubi_device *ubi) { int err; - struct ubi_wl_entry *e, *first, *last; + struct ubi_wl_entry *e; retry: - spin_lock(&ubi->wl_lock); if (!ubi->free.rb_node) { if (ubi->works_count == 0) { - ubi_assert(list_empty(&ubi->works)); ubi_err("no free eraseblocks"); - spin_unlock(&ubi->wl_lock); + ubi_assert(list_empty(&ubi->works)); return -ENOSPC; } - spin_unlock(&ubi->wl_lock); err = produce_free_peb(ubi); if (err < 0) @@ -375,13 +519,11 @@ retry: goto retry; } - first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb); - last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb); - - if (last->ec - first->ec < WL_FREE_MAX_DIFF) - e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb); - else - e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2); + e = find_mean_wl_entry(ubi, &ubi->free); + if (!e) { + ubi_err("no free eraseblocks"); + return -ENOSPC; + } self_check_in_wl_tree(ubi, e, &ubi->free); @@ -390,10 +532,14 @@ retry: * be protected from being moved for some time. */ rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; dbg_wl("PEB %d EC %d", e->pnum, e->ec); +#ifndef CONFIG_MTD_UBI_FASTMAP + /* We have to enqueue e only if fastmap is disabled, + * is fastmap enabled prot_queue_add() will be called by + * ubi_wl_get_peb() after removing e from the pool. */ prot_queue_add(ubi, e); - spin_unlock(&ubi->wl_lock); - +#endif err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, ubi->peb_size - ubi->vid_hdr_aloffset); if (err) { @@ -404,6 +550,150 @@ retry: return e->pnum; } +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * return_unused_pool_pebs - returns unused PEB to the free tree. + * @ubi: UBI device description object + * @pool: fastmap pool description object + */ +static void return_unused_pool_pebs(struct ubi_device *ubi, + struct ubi_fm_pool *pool) +{ + int i; + struct ubi_wl_entry *e; + + for (i = pool->used; i < pool->size; i++) { + e = ubi->lookuptbl[pool->pebs[i]]; + wl_tree_add(e, &ubi->free); + ubi->free_count++; + } +} + +/** + * refill_wl_pool - refills all the fastmap pool used by the + * WL sub-system. + * @ubi: UBI device description object + */ +static void refill_wl_pool(struct ubi_device *ubi) +{ + struct ubi_wl_entry *e; + struct ubi_fm_pool *pool = &ubi->fm_wl_pool; + + return_unused_pool_pebs(ubi, pool); + + for (pool->size = 0; pool->size < pool->max_size; pool->size++) { + if (!ubi->free.rb_node || + (ubi->free_count - ubi->beb_rsvd_pebs < 5)) + break; + + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + self_check_in_wl_tree(ubi, e, &ubi->free); + rb_erase(&e->u.rb, &ubi->free); + ubi->free_count--; + + pool->pebs[pool->size] = e->pnum; + } + pool->used = 0; +} + +/** + * refill_wl_user_pool - refills all the fastmap pool used by ubi_wl_get_peb. + * @ubi: UBI device description object + */ +static void refill_wl_user_pool(struct ubi_device *ubi) +{ + struct ubi_fm_pool *pool = &ubi->fm_pool; + + return_unused_pool_pebs(ubi, pool); + + for (pool->size = 0; pool->size < pool->max_size; pool->size++) { + if (!ubi->free.rb_node || + (ubi->free_count - ubi->beb_rsvd_pebs < 1)) + break; + + pool->pebs[pool->size] = __wl_get_peb(ubi); + if (pool->pebs[pool->size] < 0) + break; + } + pool->used = 0; +} + +/** + * ubi_refill_pools - refills all fastmap PEB pools. + * @ubi: UBI device description object + */ +void ubi_refill_pools(struct ubi_device *ubi) +{ + spin_lock(&ubi->wl_lock); + refill_wl_pool(ubi); + refill_wl_user_pool(ubi); + spin_unlock(&ubi->wl_lock); +} + +/* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of + * the fastmap pool. + */ +int ubi_wl_get_peb(struct ubi_device *ubi) +{ + int ret; + struct ubi_fm_pool *pool = &ubi->fm_pool; + struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; + + if (!pool->size || !wl_pool->size || pool->used == pool->size || + wl_pool->used == wl_pool->size) + ubi_update_fastmap(ubi); + + /* we got not a single free PEB */ + if (!pool->size) + ret = -ENOSPC; + else { + spin_lock(&ubi->wl_lock); + ret = pool->pebs[pool->used++]; + prot_queue_add(ubi, ubi->lookuptbl[ret]); + spin_unlock(&ubi->wl_lock); + } + + return ret; +} + +/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system. + * + * @ubi: UBI device description object + */ +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) +{ + struct ubi_fm_pool *pool = &ubi->fm_wl_pool; + int pnum; + + if (pool->used == pool->size || !pool->size) { + /* We cannot update the fastmap here because this + * function is called in atomic context. + * Let's fail here and refill/update it as soon as possible. */ + schedule_work(&ubi->fm_work); + return NULL; + } else { + pnum = pool->pebs[pool->used++]; + return ubi->lookuptbl[pnum]; + } +} +#else +static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) +{ + return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); +} + +int ubi_wl_get_peb(struct ubi_device *ubi) +{ + int peb; + + spin_lock(&ubi->wl_lock); + peb = __wl_get_peb(ubi); + spin_unlock(&ubi->wl_lock); + + return peb; +} +#endif + /** * prot_queue_del - remove a physical eraseblock from the protection queue. * @ubi: UBI device description object @@ -534,14 +824,14 @@ repeat: } /** - * schedule_ubi_work - schedule a work. + * __schedule_ubi_work - schedule a work. * @ubi: UBI device description object * @wrk: the work to schedule * * This function adds a work defined by @wrk to the tail of the pending works - * list. + * list. Can only be used of ubi->work_sem is already held in read mode! */ -static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) +static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) { spin_lock(&ubi->wl_lock); list_add_tail(&wrk->list, &ubi->works); @@ -552,9 +842,35 @@ static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) spin_unlock(&ubi->wl_lock); } +/** + * schedule_ubi_work - schedule a work. + * @ubi: UBI device description object + * @wrk: the work to schedule + * + * This function adds a work defined by @wrk to the tail of the pending works + * list. + */ +static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) +{ + down_read(&ubi->work_sem); + __schedule_ubi_work(ubi, wrk); + up_read(&ubi->work_sem); +} + static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, int cancel); +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * ubi_is_erase_work - checks whether a work is erase work. + * @wrk: The work object to be checked + */ +int ubi_is_erase_work(struct ubi_work *wrk) +{ + return wrk->func == erase_worker; +} +#endif + /** * schedule_erase - schedule an erase work. * @ubi: UBI device description object @@ -571,6 +887,9 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, { struct ubi_work *wl_wrk; + ubi_assert(e); + ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); + dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", e->pnum, e->ec, torture); @@ -588,6 +907,79 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, return 0; } +/** + * do_sync_erase - run the erase worker synchronously. + * @ubi: UBI device description object + * @e: the WL entry of the physical eraseblock to erase + * @vol_id: the volume ID that last used this PEB + * @lnum: the last used logical eraseblock number for the PEB + * @torture: if the physical eraseblock has to be tortured + * + */ +static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, + int vol_id, int lnum, int torture) +{ + struct ubi_work *wl_wrk; + + dbg_wl("sync erase of PEB %i", e->pnum); + + wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + if (!wl_wrk) + return -ENOMEM; + + wl_wrk->e = e; + wl_wrk->vol_id = vol_id; + wl_wrk->lnum = lnum; + wl_wrk->torture = torture; + + return erase_worker(ubi, wl_wrk, 0); +} + +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling + * sub-system. + * see: ubi_wl_put_peb() + * + * @ubi: UBI device description object + * @fm_e: physical eraseblock to return + * @lnum: the last used logical eraseblock number for the PEB + * @torture: if this physical eraseblock has to be tortured + */ +int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e, + int lnum, int torture) +{ + struct ubi_wl_entry *e; + int vol_id, pnum = fm_e->pnum; + + dbg_wl("PEB %d", pnum); + + ubi_assert(pnum >= 0); + ubi_assert(pnum < ubi->peb_count); + + spin_lock(&ubi->wl_lock); + e = ubi->lookuptbl[pnum]; + + /* This can happen if we recovered from a fastmap the very + * first time and writing now a new one. In this case the wl system + * has never seen any PEB used by the original fastmap. + */ + if (!e) { + e = fm_e; + ubi_assert(e->ec >= 0); + ubi->lookuptbl[pnum] = e; + } else { + e->ec = fm_e->ec; + kfree(fm_e); + } + + spin_unlock(&ubi->wl_lock); + + vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID; + return schedule_erase(ubi, e, vol_id, lnum, torture); +} +#endif + /** * wear_leveling_worker - wear-leveling worker function. * @ubi: UBI device description object @@ -603,6 +995,9 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, { int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; int vol_id = -1, uninitialized_var(lnum); +#ifdef CONFIG_MTD_UBI_FASTMAP + int anchor = wrk->anchor; +#endif struct ubi_wl_entry *e1, *e2; struct ubi_vid_hdr *vid_hdr; @@ -636,14 +1031,35 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, goto out_cancel; } +#ifdef CONFIG_MTD_UBI_FASTMAP + /* Check whether we need to produce an anchor PEB */ + if (!anchor) + anchor = !anchor_pebs_avalible(&ubi->free); + + if (anchor) { + e1 = find_anchor_wl_entry(&ubi->used); + if (!e1) + goto out_cancel; + e2 = get_peb_for_wl(ubi); + if (!e2) + goto out_cancel; + + self_check_in_wl_tree(ubi, e1, &ubi->used); + rb_erase(&e1->u.rb, &ubi->used); + dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum); + } else if (!ubi->scrub.rb_node) { +#else if (!ubi->scrub.rb_node) { +#endif /* * Now pick the least worn-out used physical eraseblock and a * highly worn-out free physical eraseblock. If the erase * counters differ much enough, start wear-leveling. */ e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + e2 = get_peb_for_wl(ubi); + if (!e2) + goto out_cancel; if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { dbg_wl("no WL needed: min used EC %d, max free EC %d", @@ -658,14 +1074,15 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, /* Perform scrubbing */ scrubbing = 1; e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb); - e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + e2 = get_peb_for_wl(ubi); + if (!e2) + goto out_cancel; + self_check_in_wl_tree(ubi, e1, &ubi->scrub); rb_erase(&e1->u.rb, &ubi->scrub); dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); } - self_check_in_wl_tree(ubi, e2, &ubi->free); - rb_erase(&e2->u.rb, &ubi->free); ubi->move_from = e1; ubi->move_to = e2; spin_unlock(&ubi->wl_lock); @@ -782,7 +1199,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, ubi->move_to_put = ubi->wl_scheduled = 0; spin_unlock(&ubi->wl_lock); - err = schedule_erase(ubi, e1, vol_id, lnum, 0); + err = do_sync_erase(ubi, e1, vol_id, lnum, 0); if (err) { kmem_cache_free(ubi_wl_entry_slab, e1); if (e2) @@ -797,7 +1214,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, */ dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase", e2->pnum, vol_id, lnum); - err = schedule_erase(ubi, e2, vol_id, lnum, 0); + err = do_sync_erase(ubi, e2, vol_id, lnum, 0); if (err) { kmem_cache_free(ubi_wl_entry_slab, e2); goto out_ro; @@ -836,7 +1253,7 @@ out_not_moved: spin_unlock(&ubi->wl_lock); ubi_free_vid_hdr(ubi, vid_hdr); - err = schedule_erase(ubi, e2, vol_id, lnum, torture); + err = do_sync_erase(ubi, e2, vol_id, lnum, torture); if (err) { kmem_cache_free(ubi_wl_entry_slab, e2); goto out_ro; @@ -877,12 +1294,13 @@ out_cancel: /** * ensure_wear_leveling - schedule wear-leveling if it is needed. * @ubi: UBI device description object + * @nested: set to non-zero if this function is called from UBI worker * * This function checks if it is time to start wear-leveling and schedules it * if yes. This function returns zero in case of success and a negative error * code in case of failure. */ -static int ensure_wear_leveling(struct ubi_device *ubi) +static int ensure_wear_leveling(struct ubi_device *ubi, int nested) { int err = 0; struct ubi_wl_entry *e1; @@ -910,7 +1328,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi) * %UBI_WL_THRESHOLD. */ e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); - e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) goto out_unlock; @@ -927,8 +1345,12 @@ static int ensure_wear_leveling(struct ubi_device *ubi) goto out_cancel; } + wrk->anchor = 0; wrk->func = &wear_leveling_worker; - schedule_ubi_work(ubi, wrk); + if (nested) + __schedule_ubi_work(ubi, wrk); + else + schedule_ubi_work(ubi, wrk); return err; out_cancel: @@ -939,6 +1361,38 @@ out_unlock: return err; } +#ifdef CONFIG_MTD_UBI_FASTMAP +/** + * ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB. + * @ubi: UBI device description object + */ +int ubi_ensure_anchor_pebs(struct ubi_device *ubi) +{ + struct ubi_work *wrk; + + spin_lock(&ubi->wl_lock); + if (ubi->wl_scheduled) { + spin_unlock(&ubi->wl_lock); + return 0; + } + ubi->wl_scheduled = 1; + spin_unlock(&ubi->wl_lock); + + wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + if (!wrk) { + spin_lock(&ubi->wl_lock); + ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + return -ENOMEM; + } + + wrk->anchor = 1; + wrk->func = &wear_leveling_worker; + schedule_ubi_work(ubi, wrk); + return 0; +} +#endif + /** * erase_worker - physical eraseblock erase worker function. * @ubi: UBI device description object @@ -969,6 +1423,8 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, dbg_wl("erase PEB %d EC %d LEB %d:%d", pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum); + ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); + err = sync_erase(ubi, e, wl_wrk->torture); if (!err) { /* Fine, we've erased it successfully */ @@ -976,6 +1432,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, spin_lock(&ubi->wl_lock); wl_tree_add(e, &ubi->free); + ubi->free_count++; spin_unlock(&ubi->wl_lock); /* @@ -985,7 +1442,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, serve_prot_queue(ubi); /* And take care about wear-leveling */ - err = ensure_wear_leveling(ubi); + err = ensure_wear_leveling(ubi, 1); return err; } @@ -1223,7 +1680,7 @@ retry: * Technically scrubbing is the same as wear-leveling, so it is done * by the WL worker. */ - return ensure_wear_leveling(ubi); + return ensure_wear_leveling(ubi, 0); } /** @@ -1404,7 +1861,7 @@ static void cancel_pending(struct ubi_device *ubi) */ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) { - int err, i; + int err, i, reserved_pebs, found_pebs = 0; struct rb_node *rb1, *rb2; struct ubi_ainf_volume *av; struct ubi_ainf_peb *aeb, *tmp; @@ -1416,6 +1873,9 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) init_rwsem(&ubi->work_sem); ubi->max_ec = ai->max_ec; INIT_LIST_HEAD(&ubi->works); +#ifdef CONFIG_MTD_UBI_FASTMAP + INIT_WORK(&ubi->fm_work, update_fastmap_work_fn); +#endif sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); @@ -1437,13 +1897,17 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; + ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); ubi->lookuptbl[e->pnum] = e; if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) { kmem_cache_free(ubi_wl_entry_slab, e); goto out_free; } + + found_pebs++; } + ubi->free_count = 0; list_for_each_entry(aeb, &ai->free, u.list) { cond_resched(); @@ -1454,8 +1918,14 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; ubi_assert(e->ec >= 0); + ubi_assert(!ubi_is_fm_block(ubi, e->pnum)); + wl_tree_add(e, &ubi->free); + ubi->free_count++; + ubi->lookuptbl[e->pnum] = e; + + found_pebs++; } ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { @@ -1469,6 +1939,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum = aeb->pnum; e->ec = aeb->ec; ubi->lookuptbl[e->pnum] = e; + if (!aeb->scrub) { dbg_wl("add PEB %d EC %d to the used tree", e->pnum, e->ec); @@ -1478,22 +1949,38 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) e->pnum, e->ec); wl_tree_add(e, &ubi->scrub); } + + found_pebs++; } } - if (ubi->avail_pebs < WL_RESERVED_PEBS) { + dbg_wl("found %i PEBs", found_pebs); + + if (ubi->fm) + ubi_assert(ubi->good_peb_count == \ + found_pebs + ubi->fm->used_blocks); + else + ubi_assert(ubi->good_peb_count == found_pebs); + + reserved_pebs = WL_RESERVED_PEBS; +#ifdef CONFIG_MTD_UBI_FASTMAP + /* Reserve enough LEBs to store two fastmaps. */ + reserved_pebs += (ubi->fm_size / ubi->leb_size) * 2; +#endif + + if (ubi->avail_pebs < reserved_pebs) { ubi_err("no enough physical eraseblocks (%d, need %d)", - ubi->avail_pebs, WL_RESERVED_PEBS); + ubi->avail_pebs, reserved_pebs); if (ubi->corr_peb_count) ubi_err("%d PEBs are corrupted and not used", ubi->corr_peb_count); goto out_free; } - ubi->avail_pebs -= WL_RESERVED_PEBS; - ubi->rsvd_pebs += WL_RESERVED_PEBS; + ubi->avail_pebs -= reserved_pebs; + ubi->rsvd_pebs += reserved_pebs; /* Schedule wear-leveling if needed */ - err = ensure_wear_leveling(ubi); + err = ensure_wear_leveling(ubi, 0); if (err) goto out_free; @@ -1572,7 +2059,7 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) } read_ec = be64_to_cpu(ec_hdr->ec); - if (ec != read_ec) { + if (ec != read_ec && read_ec - ec > 1) { ubi_err("self-check failed for PEB %d", pnum); ubi_err("read EC is %lld, should be %d", read_ec, ec); dump_stack(); -- cgit v1.2.3 From bdacb13da4adb91f2b732def5bac15804b92ea3c Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:49 +0200 Subject: UBI: Add fastmap core Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 1537 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1537 insertions(+) create mode 100644 drivers/mtd/ubi/fastmap.c (limited to 'drivers') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c new file mode 100644 index 000000000000..1a5f53c090d4 --- /dev/null +++ b/drivers/mtd/ubi/fastmap.c @@ -0,0 +1,1537 @@ +/* + * Copyright (c) 2012 Linutronix GmbH + * Author: Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + */ + +#include +#include "ubi.h" + +/** + * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device. + * @ubi: UBI device description object + */ +size_t ubi_calc_fm_size(struct ubi_device *ubi) +{ + size_t size; + + size = sizeof(struct ubi_fm_hdr) + \ + sizeof(struct ubi_fm_scan_pool) + \ + sizeof(struct ubi_fm_scan_pool) + \ + (ubi->peb_count * sizeof(struct ubi_fm_ec)) + \ + (sizeof(struct ubi_fm_eba) + \ + (ubi->peb_count * sizeof(__be32))) + \ + sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES; + return roundup(size, ubi->leb_size); +} + + +/** + * new_fm_vhdr - allocate a new volume header for fastmap usage. + * @ubi: UBI device description object + * @vol_id: the VID of the new header + * + * Returns a new struct ubi_vid_hdr on success. + * NULL indicates out of memory. + */ +static struct ubi_vid_hdr *new_fm_vhdr(struct ubi_device *ubi, int vol_id) +{ + struct ubi_vid_hdr *new; + + new = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!new) + goto out; + + new->vol_type = UBI_VID_DYNAMIC; + new->vol_id = cpu_to_be32(vol_id); + + /* UBI implementations without fastmap support have to delete the + * fastmap. + */ + new->compat = UBI_COMPAT_DELETE; + +out: + return new; +} + +/** + * add_aeb - create and add a attach erase block to a given list. + * @ai: UBI attach info object + * @list: the target list + * @pnum: PEB number of the new attach erase block + * @ec: erease counter of the new LEB + * @scrub: scrub this PEB after attaching + * + * Returns 0 on success, < 0 indicates an internal error. + */ +static int add_aeb(struct ubi_attach_info *ai, struct list_head *list, + int pnum, int ec, int scrub) +{ + struct ubi_ainf_peb *aeb; + + aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL); + if (!aeb) + return -ENOMEM; + + aeb->pnum = pnum; + aeb->ec = ec; + aeb->lnum = -1; + aeb->scrub = scrub; + aeb->copy_flag = aeb->sqnum = 0; + + ai->ec_sum += aeb->ec; + ai->ec_count++; + + if (ai->max_ec < aeb->ec) + ai->max_ec = aeb->ec; + + if (ai->min_ec > aeb->ec) + ai->min_ec = aeb->ec; + + list_add_tail(&aeb->u.list, list); + + return 0; +} + +/** + * add_vol - create and add a new volume to ubi_attach_info. + * @ai: ubi_attach_info object + * @vol_id: VID of the new volume + * @used_ebs: number of used EBS + * @data_pad: data padding value of the new volume + * @vol_type: volume type + * @last_eb_bytes: number of bytes in the last LEB + * + * Returns the new struct ubi_ainf_volume on success. + * NULL indicates an error. + */ +static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id, + int used_ebs, int data_pad, u8 vol_type, + int last_eb_bytes) +{ + struct ubi_ainf_volume *av; + struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; + + while (*p) { + parent = *p; + av = rb_entry(parent, struct ubi_ainf_volume, rb); + + if (vol_id > av->vol_id) + p = &(*p)->rb_left; + else if (vol_id > av->vol_id) + p = &(*p)->rb_right; + } + + av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL); + if (!av) + goto out; + + av->highest_lnum = av->leb_count = 0; + av->vol_id = vol_id; + av->used_ebs = used_ebs; + av->data_pad = data_pad; + av->last_data_size = last_eb_bytes; + av->compat = 0; + av->vol_type = vol_type; + av->root = RB_ROOT; + + dbg_bld("found volume (ID %i)", vol_id); + + rb_link_node(&av->rb, parent, p); + rb_insert_color(&av->rb, &ai->volumes); + +out: + return av; +} + +/** + * assign_aeb_to_av - assigns a SEB to a given ainf_volume and removes it + * from it's original list. + * @ai: ubi_attach_info object + * @aeb: the to be assigned SEB + * @av: target scan volume + */ +static void assign_aeb_to_av(struct ubi_attach_info *ai, + struct ubi_ainf_peb *aeb, + struct ubi_ainf_volume *av) +{ + struct ubi_ainf_peb *tmp_aeb; + struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; + + p = &av->root.rb_node; + while (*p) { + parent = *p; + + tmp_aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); + if (aeb->lnum != tmp_aeb->lnum) { + if (aeb->lnum < tmp_aeb->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + + continue; + } else + break; + } + + list_del(&aeb->u.list); + av->leb_count++; + + rb_link_node(&aeb->u.rb, parent, p); + rb_insert_color(&aeb->u.rb, &av->root); +} + +/** + * update_vol - inserts or updates a LEB which was found a pool. + * @ubi: the UBI device object + * @ai: attach info object + * @av: the volume this LEB belongs to + * @new_vh: the volume header derived from new_aeb + * @new_aeb: the AEB to be examined + * + * Returns 0 on success, < 0 indicates an internal error. + */ +static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai, + struct ubi_ainf_volume *av, struct ubi_vid_hdr *new_vh, + struct ubi_ainf_peb *new_aeb) +{ + struct rb_node **p = &av->root.rb_node, *parent = NULL; + struct ubi_ainf_peb *aeb, *victim; + int cmp_res; + + while (*p) { + parent = *p; + aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb); + + if (be32_to_cpu(new_vh->lnum) != aeb->lnum) { + if (be32_to_cpu(new_vh->lnum) < aeb->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + + continue; + } + + /* This case can happen if the fastmap gets written + * because of a volume change (creation, deletion, ..). + * Then a PEB can be within the persistent EBA and the pool. + */ + if (aeb->pnum == new_aeb->pnum) { + ubi_assert(aeb->lnum == new_aeb->lnum); + kmem_cache_free(ai->aeb_slab_cache, new_aeb); + + return 0; + } + + cmp_res = ubi_compare_lebs(ubi, aeb, new_aeb->pnum, new_vh); + if (cmp_res < 0) + return cmp_res; + + /* new_aeb is newer */ + if (cmp_res & 1) { + victim = kmem_cache_alloc(ai->aeb_slab_cache, + GFP_KERNEL); + if (!victim) + return -ENOMEM; + + victim->ec = aeb->ec; + victim->pnum = aeb->pnum; + list_add_tail(&victim->u.list, &ai->erase); + + if (av->highest_lnum == be32_to_cpu(new_vh->lnum)) + av->last_data_size = \ + be32_to_cpu(new_vh->data_size); + + dbg_bld("vol %i: AEB %i's PEB %i is the newer", + av->vol_id, aeb->lnum, new_aeb->pnum); + + aeb->ec = new_aeb->ec; + aeb->pnum = new_aeb->pnum; + aeb->copy_flag = new_vh->copy_flag; + aeb->scrub = new_aeb->scrub; + kmem_cache_free(ai->aeb_slab_cache, new_aeb); + + /* new_aeb is older */ + } else { + dbg_bld("vol %i: AEB %i's PEB %i is old, dropping it", + av->vol_id, aeb->lnum, new_aeb->pnum); + list_add_tail(&new_aeb->u.list, &ai->erase); + } + + return 0; + } + /* This LEB is new, let's add it to the volume */ + + if (av->highest_lnum <= be32_to_cpu(new_vh->lnum)) { + av->highest_lnum = be32_to_cpu(new_vh->lnum); + av->last_data_size = be32_to_cpu(new_vh->data_size); + } + + if (av->vol_type == UBI_STATIC_VOLUME) + av->used_ebs = be32_to_cpu(new_vh->used_ebs); + + av->leb_count++; + + rb_link_node(&new_aeb->u.rb, parent, p); + rb_insert_color(&new_aeb->u.rb, &av->root); + + return 0; +} + +/** + * process_pool_aeb - we found a non-empty PEB in a pool. + * @ubi: UBI device object + * @ai: attach info object + * @new_vh: the volume header derived from new_aeb + * @new_aeb: the AEB to be examined + * + * Returns 0 on success, < 0 indicates an internal error. + */ +static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai, + struct ubi_vid_hdr *new_vh, + struct ubi_ainf_peb *new_aeb) +{ + struct ubi_ainf_volume *av, *tmp_av = NULL; + struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; + int found = 0; + + if (be32_to_cpu(new_vh->vol_id) == UBI_FM_SB_VOLUME_ID || + be32_to_cpu(new_vh->vol_id) == UBI_FM_DATA_VOLUME_ID) { + kmem_cache_free(ai->aeb_slab_cache, new_aeb); + + return 0; + } + + /* Find the volume this SEB belongs to */ + while (*p) { + parent = *p; + tmp_av = rb_entry(parent, struct ubi_ainf_volume, rb); + + if (be32_to_cpu(new_vh->vol_id) > tmp_av->vol_id) + p = &(*p)->rb_left; + else if (be32_to_cpu(new_vh->vol_id) < tmp_av->vol_id) + p = &(*p)->rb_right; + else { + found = 1; + break; + } + } + + if (found) + av = tmp_av; + else { + ubi_err("orphaned volume in fastmap pool!"); + return UBI_BAD_FASTMAP; + } + + ubi_assert(be32_to_cpu(new_vh->vol_id) == av->vol_id); + + return update_vol(ubi, ai, av, new_vh, new_aeb); +} + +/** + * unmap_peb - unmap a PEB. + * If fastmap detects a free PEB in the pool it has to check whether + * this PEB has been unmapped after writing the fastmap. + * + * @ai: UBI attach info object + * @pnum: The PEB to be unmapped + */ +static void unmap_peb(struct ubi_attach_info *ai, int pnum) +{ + struct ubi_ainf_volume *av; + struct rb_node *node, *node2; + struct ubi_ainf_peb *aeb; + + for (node = rb_first(&ai->volumes); node; node = rb_next(node)) { + av = rb_entry(node, struct ubi_ainf_volume, rb); + + for (node2 = rb_first(&av->root); node2; + node2 = rb_next(node2)) { + aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb); + if (aeb->pnum == pnum) { + rb_erase(&aeb->u.rb, &av->root); + kmem_cache_free(ai->aeb_slab_cache, aeb); + return; + } + } + } +} + +/** + * scan_pool - scans a pool for changed (no longer empty PEBs). + * @ubi: UBI device object + * @ai: attach info object + * @pebs: an array of all PEB numbers in the to be scanned pool + * @pool_size: size of the pool (number of entries in @pebs) + * @max_sqnum: pointer to the maximal sequence number + * @eba_orphans: list of PEBs which need to be scanned + * @free: list of PEBs which are most likely free (and go into @ai->free) + * + * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned. + * < 0 indicates an internal error. + */ +static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, + int *pebs, int pool_size, unsigned long long *max_sqnum, + struct list_head *eba_orphans, struct list_head *free) +{ + struct ubi_vid_hdr *vh; + struct ubi_ec_hdr *ech; + struct ubi_ainf_peb *new_aeb, *tmp_aeb; + int i, pnum, err, found_orphan, ret = 0; + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) + return -ENOMEM; + + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) { + kfree(ech); + return -ENOMEM; + } + + dbg_bld("scanning fastmap pool: size = %i", pool_size); + + /* + * Now scan all PEBs in the pool to find changes which have been made + * after the creation of the fastmap + */ + for (i = 0; i < pool_size; i++) { + int scrub = 0; + + pnum = be32_to_cpu(pebs[i]); + + if (ubi_io_is_bad(ubi, pnum)) { + ubi_err("bad PEB in fastmap pool!"); + ret = UBI_BAD_FASTMAP; + goto out; + } + + err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); + if (err && err != UBI_IO_BITFLIPS) { + ubi_err("unable to read EC header! PEB:%i err:%i", + pnum, err); + ret = err > 0 ? UBI_BAD_FASTMAP : err; + goto out; + } else if (ret == UBI_IO_BITFLIPS) + scrub = 1; + + if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + ubi_err("bad image seq: 0x%x, expected: 0x%x", + be32_to_cpu(ech->image_seq), ubi->image_seq); + err = UBI_BAD_FASTMAP; + goto out; + } + + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); + if (err == UBI_IO_FF || err == UBI_IO_FF_BITFLIPS) { + unsigned long long ec = be64_to_cpu(ech->ec); + unmap_peb(ai, pnum); + dbg_bld("Adding PEB to free: %i", pnum); + if (err == UBI_IO_FF_BITFLIPS) + add_aeb(ai, free, pnum, ec, 1); + else + add_aeb(ai, free, pnum, ec, 0); + continue; + } else if (err == 0 || err == UBI_IO_BITFLIPS) { + dbg_bld("Found non empty PEB:%i in pool", pnum); + + if (err == UBI_IO_BITFLIPS) + scrub = 1; + + found_orphan = 0; + list_for_each_entry(tmp_aeb, eba_orphans, u.list) { + if (tmp_aeb->pnum == pnum) { + found_orphan = 1; + break; + } + } + if (found_orphan) { + kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); + list_del(&tmp_aeb->u.list); + } + + new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, + GFP_KERNEL); + if (!new_aeb) { + ret = -ENOMEM; + goto out; + } + + new_aeb->ec = be64_to_cpu(ech->ec); + new_aeb->pnum = pnum; + new_aeb->lnum = be32_to_cpu(vh->lnum); + new_aeb->sqnum = be64_to_cpu(vh->sqnum); + new_aeb->copy_flag = vh->copy_flag; + new_aeb->scrub = scrub; + + if (*max_sqnum < new_aeb->sqnum) + *max_sqnum = new_aeb->sqnum; + + err = process_pool_aeb(ubi, ai, vh, new_aeb); + if (err) { + ret = err > 0 ? UBI_BAD_FASTMAP : err; + goto out; + } + } else { + /* We are paranoid and fall back to scanning mode */ + ubi_err("fastmap pool PEBs contains damaged PEBs!"); + ret = err > 0 ? UBI_BAD_FASTMAP : err; + goto out; + } + + } + +out: + ubi_free_vid_hdr(ubi, vh); + kfree(ech); + return ret; +} + +/** + * count_fastmap_pebs - Counts the PEBs found by fastmap. + * @ai: The UBI attach info object + */ +static int count_fastmap_pebs(struct ubi_attach_info *ai) +{ + struct ubi_ainf_peb *aeb; + struct ubi_ainf_volume *av; + struct rb_node *rb1, *rb2; + int n = 0; + + list_for_each_entry(aeb, &ai->erase, u.list) + n++; + + list_for_each_entry(aeb, &ai->free, u.list) + n++; + + ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) + ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb) + n++; + + return n; +} + +/** + * ubi_attach_fastmap - creates ubi_attach_info from a fastmap. + * @ubi: UBI device object + * @ai: UBI attach info object + * @fm: the fastmap to be attached + * + * Returns 0 on success, UBI_BAD_FASTMAP if the found fastmap was unusable. + * < 0 indicates an internal error. + */ +static int ubi_attach_fastmap(struct ubi_device *ubi, + struct ubi_attach_info *ai, + struct ubi_fastmap_layout *fm) +{ + struct list_head used, eba_orphans, free; + struct ubi_ainf_volume *av; + struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb; + struct ubi_ec_hdr *ech; + struct ubi_fm_sb *fmsb; + struct ubi_fm_hdr *fmhdr; + struct ubi_fm_scan_pool *fmpl1, *fmpl2; + struct ubi_fm_ec *fmec; + struct ubi_fm_volhdr *fmvhdr; + struct ubi_fm_eba *fm_eba; + int ret, i, j, pool_size, wl_pool_size; + size_t fm_pos = 0, fm_size = ubi->fm_size; + unsigned long long max_sqnum = 0; + void *fm_raw = ubi->fm_buf; + + INIT_LIST_HEAD(&used); + INIT_LIST_HEAD(&free); + INIT_LIST_HEAD(&eba_orphans); + INIT_LIST_HEAD(&ai->corr); + INIT_LIST_HEAD(&ai->free); + INIT_LIST_HEAD(&ai->erase); + INIT_LIST_HEAD(&ai->alien); + ai->volumes = RB_ROOT; + ai->min_ec = UBI_MAX_ERASECOUNTER; + + ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab", + sizeof(struct ubi_ainf_peb), + 0, 0, NULL); + if (!ai->aeb_slab_cache) { + ret = -ENOMEM; + goto fail; + } + + fmsb = (struct ubi_fm_sb *)(fm_raw); + ai->max_sqnum = fmsb->sqnum; + fm_pos += sizeof(struct ubi_fm_sb); + if (fm_pos >= fm_size) + goto fail_bad; + + fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmhdr); + if (fm_pos >= fm_size) + goto fail_bad; + + if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) { + ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC); + goto fail_bad; + } + + fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl1); + if (fm_pos >= fm_size) + goto fail_bad; + if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) { + ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC); + goto fail_bad; + } + + fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl2); + if (fm_pos >= fm_size) + goto fail_bad; + if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) { + ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC); + goto fail_bad; + } + + pool_size = be16_to_cpu(fmpl1->size); + wl_pool_size = be16_to_cpu(fmpl2->size); + fm->max_pool_size = be16_to_cpu(fmpl1->max_size); + fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size); + + if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) { + ubi_err("bad pool size: %i", pool_size); + goto fail_bad; + } + + if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) { + ubi_err("bad WL pool size: %i", wl_pool_size); + goto fail_bad; + } + + + if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE || + fm->max_pool_size < 0) { + ubi_err("bad maximal pool size: %i", fm->max_pool_size); + goto fail_bad; + } + + if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE || + fm->max_wl_pool_size < 0) { + ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size); + goto fail_bad; + } + + /* read EC values from free list */ + for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) { + fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmec); + if (fm_pos >= fm_size) + goto fail_bad; + + add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 0); + } + + /* read EC values from used list */ + for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) { + fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmec); + if (fm_pos >= fm_size) + goto fail_bad; + + add_aeb(ai, &used, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 0); + } + + /* read EC values from scrub list */ + for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) { + fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmec); + if (fm_pos >= fm_size) + goto fail_bad; + + add_aeb(ai, &used, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 1); + } + + /* read EC values from erase list */ + for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) { + fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmec); + if (fm_pos >= fm_size) + goto fail_bad; + + add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 1); + } + + ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); + ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count); + + /* Iterate over all volumes and read their EBA table */ + for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) { + fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmvhdr); + if (fm_pos >= fm_size) + goto fail_bad; + + if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) { + ubi_err("bad fastmap vol header magic: 0x%x, " \ + "expected: 0x%x", + be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC); + goto fail_bad; + } + + av = add_vol(ai, be32_to_cpu(fmvhdr->vol_id), + be32_to_cpu(fmvhdr->used_ebs), + be32_to_cpu(fmvhdr->data_pad), + fmvhdr->vol_type, + be32_to_cpu(fmvhdr->last_eb_bytes)); + + if (!av) + goto fail_bad; + + ai->vols_found++; + if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id)) + ai->highest_vol_id = be32_to_cpu(fmvhdr->vol_id); + + fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos); + fm_pos += sizeof(*fm_eba); + fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs)); + if (fm_pos >= fm_size) + goto fail_bad; + + if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) { + ubi_err("bad fastmap EBA header magic: 0x%x, " \ + "expected: 0x%x", + be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC); + goto fail_bad; + } + + for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) { + int pnum = be32_to_cpu(fm_eba->pnum[j]); + + if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0) + continue; + + aeb = NULL; + list_for_each_entry(tmp_aeb, &used, u.list) { + if (tmp_aeb->pnum == pnum) + aeb = tmp_aeb; + } + + /* This can happen if a PEB is already in an EBA known + * by this fastmap but the PEB itself is not in the used + * list. + * In this case the PEB can be within the fastmap pool + * or while writing the fastmap it was in the protection + * queue. + */ + if (!aeb) { + aeb = kmem_cache_alloc(ai->aeb_slab_cache, + GFP_KERNEL); + if (!aeb) { + ret = -ENOMEM; + + goto fail; + } + + aeb->lnum = j; + aeb->pnum = be32_to_cpu(fm_eba->pnum[j]); + aeb->ec = -1; + aeb->scrub = aeb->copy_flag = aeb->sqnum = 0; + list_add_tail(&aeb->u.list, &eba_orphans); + continue; + } + + aeb->lnum = j; + + if (av->highest_lnum <= aeb->lnum) + av->highest_lnum = aeb->lnum; + + assign_aeb_to_av(ai, aeb, av); + + dbg_bld("inserting PEB:%i (LEB %i) to vol %i", + aeb->pnum, aeb->lnum, av->vol_id); + } + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) { + ret = -ENOMEM; + goto fail; + } + + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, + u.list) { + int err; + + if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) { + ubi_err("bad PEB in fastmap EBA orphan list"); + ret = UBI_BAD_FASTMAP; + kfree(ech); + goto fail; + } + + err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0); + if (err && err != UBI_IO_BITFLIPS) { + ubi_err("unable to read EC header! PEB:%i " \ + "err:%i", tmp_aeb->pnum, err); + ret = err > 0 ? UBI_BAD_FASTMAP : err; + kfree(ech); + + goto fail; + } else if (err == UBI_IO_BITFLIPS) + tmp_aeb->scrub = 1; + + tmp_aeb->ec = be64_to_cpu(ech->ec); + assign_aeb_to_av(ai, tmp_aeb, av); + } + + kfree(ech); + } + + ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum, + &eba_orphans, &free); + if (ret) + goto fail; + + ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum, + &eba_orphans, &free); + if (ret) + goto fail; + + if (max_sqnum > ai->max_sqnum) + ai->max_sqnum = max_sqnum; + + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { + list_del(&tmp_aeb->u.list); + list_add_tail(&tmp_aeb->u.list, &ai->free); + } + + /* + * If fastmap is leaking PEBs (must not happen), raise a + * fat warning and fall back to scanning mode. + * We do this here because in ubi_wl_init() it's too late + * and we cannot fall back to scanning. + */ + if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count - + ai->bad_peb_count - fm->used_blocks)) + goto fail_bad; + + return 0; + +fail_bad: + ret = UBI_BAD_FASTMAP; +fail: + return ret; +} + +/** + * ubi_scan_fastmap - scan the fastmap. + * @ubi: UBI device object + * @ai: UBI attach info to be filled + * @fm_anchor: The fastmap starts at this PEB + * + * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found, + * UBI_BAD_FASTMAP if one was found but is not usable. + * < 0 indicates an internal error. + */ +int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, + int fm_anchor) +{ + struct ubi_fm_sb *fmsb, *fmsb2; + struct ubi_vid_hdr *vh; + struct ubi_ec_hdr *ech; + struct ubi_fastmap_layout *fm; + int i, used_blocks, pnum, ret = 0; + size_t fm_size; + __be32 crc, tmp_crc; + unsigned long long sqnum = 0; + + mutex_lock(&ubi->fm_mutex); + memset(ubi->fm_buf, 0, ubi->fm_size); + + fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); + if (!fmsb) { + ret = -ENOMEM; + goto out; + } + + fm = kzalloc(sizeof(*fm), GFP_KERNEL); + if (!fm) { + ret = -ENOMEM; + kfree(fmsb); + goto out; + } + + ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb)); + if (ret && ret != UBI_IO_BITFLIPS) + goto free_fm_sb; + else if (ret == UBI_IO_BITFLIPS) + fm->to_be_tortured[0] = 1; + + if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { + ubi_err("bad super block magic: 0x%x, expected: 0x%x", + be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); + ret = UBI_BAD_FASTMAP; + goto free_fm_sb; + } + + if (fmsb->version != UBI_FM_FMT_VERSION) { + ubi_err("bad fastmap version: %i, expected: %i", + fmsb->version, UBI_FM_FMT_VERSION); + ret = UBI_BAD_FASTMAP; + goto free_fm_sb; + } + + used_blocks = be32_to_cpu(fmsb->used_blocks); + if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { + ubi_err("number of fastmap blocks is invalid: %i", used_blocks); + ret = UBI_BAD_FASTMAP; + goto free_fm_sb; + } + + fm_size = ubi->leb_size * used_blocks; + if (fm_size != ubi->fm_size) { + ubi_err("bad fastmap size: %zi, expected: %zi", fm_size, + ubi->fm_size); + ret = UBI_BAD_FASTMAP; + goto free_fm_sb; + } + + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) { + ret = -ENOMEM; + goto free_fm_sb; + } + + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) { + ret = -ENOMEM; + goto free_hdr; + } + + for (i = 0; i < used_blocks; i++) { + pnum = be32_to_cpu(fmsb->block_loc[i]); + + if (ubi_io_is_bad(ubi, pnum)) { + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + + ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); + if (ret && ret != UBI_IO_BITFLIPS) { + ubi_err("unable to read fastmap block# %i EC (PEB: %i)", + i, pnum); + if (ret > 0) + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } else if (ret == UBI_IO_BITFLIPS) + fm->to_be_tortured[i] = 1; + + if (!ubi->image_seq) + ubi->image_seq = be32_to_cpu(ech->image_seq); + + if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + + ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); + if (ret && ret != UBI_IO_BITFLIPS) { + ubi_err("unable to read fastmap block# %i (PEB: %i)", + i, pnum); + goto free_hdr; + } + + if (i == 0) { + if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { + ubi_err("bad fastmap anchor vol_id: 0x%x," \ + " expected: 0x%x", + be32_to_cpu(vh->vol_id), + UBI_FM_SB_VOLUME_ID); + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + } else { + if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { + ubi_err("bad fastmap data vol_id: 0x%x," \ + " expected: 0x%x", + be32_to_cpu(vh->vol_id), + UBI_FM_DATA_VOLUME_ID); + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + } + + if (sqnum < be64_to_cpu(vh->sqnum)) + sqnum = be64_to_cpu(vh->sqnum); + + ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, + ubi->leb_start, ubi->leb_size); + if (ret && ret != UBI_IO_BITFLIPS) { + ubi_err("unable to read fastmap block# %i (PEB: %i, " \ + "err: %i)", i, pnum, ret); + goto free_hdr; + } + } + + kfree(fmsb); + fmsb = NULL; + + fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf); + tmp_crc = be32_to_cpu(fmsb2->data_crc); + fmsb2->data_crc = 0; + crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); + if (crc != tmp_crc) { + ubi_err("fastmap data CRC is invalid"); + ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc); + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + + fmsb2->sqnum = sqnum; + + fm->used_blocks = used_blocks; + + ret = ubi_attach_fastmap(ubi, ai, fm); + if (ret) { + if (ret > 0) + ret = UBI_BAD_FASTMAP; + goto free_hdr; + } + + for (i = 0; i < used_blocks; i++) { + struct ubi_wl_entry *e; + + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!e) { + while (i--) + kfree(fm->e[i]); + + ret = -ENOMEM; + goto free_hdr; + } + + e->pnum = be32_to_cpu(fmsb2->block_loc[i]); + e->ec = be32_to_cpu(fmsb2->block_ec[i]); + fm->e[i] = e; + } + + ubi->fm = fm; + ubi->fm_pool.max_size = ubi->fm->max_pool_size; + ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; + ubi_msg("attached by fastmap"); + ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi->fm_disabled = 0; + + ubi_free_vid_hdr(ubi, vh); + kfree(ech); +out: + mutex_unlock(&ubi->fm_mutex); + if (ret == UBI_BAD_FASTMAP) + ubi_err("Attach by fastmap failed, doing a full scan!"); + return ret; + +free_hdr: + ubi_free_vid_hdr(ubi, vh); + kfree(ech); +free_fm_sb: + kfree(fmsb); + kfree(fm); + goto out; +} + +/** + * ubi_write_fastmap - writes a fastmap. + * @ubi: UBI device object + * @new_fm: the to be written fastmap + * + * Returns 0 on success, < 0 indicates an internal error. + */ +static int ubi_write_fastmap(struct ubi_device *ubi, + struct ubi_fastmap_layout *new_fm) +{ + size_t fm_pos = 0; + void *fm_raw; + struct ubi_fm_sb *fmsb; + struct ubi_fm_hdr *fmh; + struct ubi_fm_scan_pool *fmpl1, *fmpl2; + struct ubi_fm_ec *fec; + struct ubi_fm_volhdr *fvh; + struct ubi_fm_eba *feba; + struct rb_node *node; + struct ubi_wl_entry *wl_e; + struct ubi_volume *vol; + struct ubi_vid_hdr *avhdr, *dvhdr; + struct ubi_work *ubi_wrk; + int ret, i, j, free_peb_count, used_peb_count, vol_count; + int scrub_peb_count, erase_peb_count; + + fm_raw = ubi->fm_buf; + memset(ubi->fm_buf, 0, ubi->fm_size); + + avhdr = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID); + if (!avhdr) { + ret = -ENOMEM; + goto out; + } + + dvhdr = new_fm_vhdr(ubi, UBI_FM_DATA_VOLUME_ID); + if (!dvhdr) { + ret = -ENOMEM; + goto out_kfree; + } + + spin_lock(&ubi->volumes_lock); + spin_lock(&ubi->wl_lock); + + fmsb = (struct ubi_fm_sb *)fm_raw; + fm_pos += sizeof(*fmsb); + ubi_assert(fm_pos <= ubi->fm_size); + + fmh = (struct ubi_fm_hdr *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmh); + ubi_assert(fm_pos <= ubi->fm_size); + + fmsb->magic = cpu_to_be32(UBI_FM_SB_MAGIC); + fmsb->version = UBI_FM_FMT_VERSION; + fmsb->used_blocks = cpu_to_be32(new_fm->used_blocks); + /* the max sqnum will be filled in while *reading* the fastmap */ + fmsb->sqnum = 0; + + fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC); + free_peb_count = 0; + used_peb_count = 0; + scrub_peb_count = 0; + erase_peb_count = 0; + vol_count = 0; + + fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl1); + fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); + fmpl1->size = cpu_to_be16(ubi->fm_pool.size); + fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size); + + for (i = 0; i < ubi->fm_pool.size; i++) + fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]); + + fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos); + fm_pos += sizeof(*fmpl2); + fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC); + fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size); + fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size); + + for (i = 0; i < ubi->fm_wl_pool.size; i++) + fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]); + + for (node = rb_first(&ubi->free); node; node = rb_next(node)) { + wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + + fec->pnum = cpu_to_be32(wl_e->pnum); + fec->ec = cpu_to_be32(wl_e->ec); + + free_peb_count++; + fm_pos += sizeof(*fec); + ubi_assert(fm_pos <= ubi->fm_size); + } + fmh->free_peb_count = cpu_to_be32(free_peb_count); + + for (node = rb_first(&ubi->used); node; node = rb_next(node)) { + wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + + fec->pnum = cpu_to_be32(wl_e->pnum); + fec->ec = cpu_to_be32(wl_e->ec); + + used_peb_count++; + fm_pos += sizeof(*fec); + ubi_assert(fm_pos <= ubi->fm_size); + } + fmh->used_peb_count = cpu_to_be32(used_peb_count); + + for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) { + wl_e = rb_entry(node, struct ubi_wl_entry, u.rb); + fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + + fec->pnum = cpu_to_be32(wl_e->pnum); + fec->ec = cpu_to_be32(wl_e->ec); + + scrub_peb_count++; + fm_pos += sizeof(*fec); + ubi_assert(fm_pos <= ubi->fm_size); + } + fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count); + + + list_for_each_entry(ubi_wrk, &ubi->works, list) { + if (ubi_is_erase_work(ubi_wrk)) { + wl_e = ubi_wrk->e; + ubi_assert(wl_e); + + fec = (struct ubi_fm_ec *)(fm_raw + fm_pos); + + fec->pnum = cpu_to_be32(wl_e->pnum); + fec->ec = cpu_to_be32(wl_e->ec); + + erase_peb_count++; + fm_pos += sizeof(*fec); + ubi_assert(fm_pos <= ubi->fm_size); + } + } + fmh->erase_peb_count = cpu_to_be32(erase_peb_count); + + for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) { + vol = ubi->volumes[i]; + + if (!vol) + continue; + + vol_count++; + + fvh = (struct ubi_fm_volhdr *)(fm_raw + fm_pos); + fm_pos += sizeof(*fvh); + ubi_assert(fm_pos <= ubi->fm_size); + + fvh->magic = cpu_to_be32(UBI_FM_VHDR_MAGIC); + fvh->vol_id = cpu_to_be32(vol->vol_id); + fvh->vol_type = vol->vol_type; + fvh->used_ebs = cpu_to_be32(vol->used_ebs); + fvh->data_pad = cpu_to_be32(vol->data_pad); + fvh->last_eb_bytes = cpu_to_be32(vol->last_eb_bytes); + + ubi_assert(vol->vol_type == UBI_DYNAMIC_VOLUME || + vol->vol_type == UBI_STATIC_VOLUME); + + feba = (struct ubi_fm_eba *)(fm_raw + fm_pos); + fm_pos += sizeof(*feba) + (sizeof(__be32) * vol->reserved_pebs); + ubi_assert(fm_pos <= ubi->fm_size); + + for (j = 0; j < vol->reserved_pebs; j++) + feba->pnum[j] = cpu_to_be32(vol->eba_tbl[j]); + + feba->reserved_pebs = cpu_to_be32(j); + feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC); + } + fmh->vol_count = cpu_to_be32(vol_count); + fmh->bad_peb_count = cpu_to_be32(ubi->bad_peb_count); + + avhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); + avhdr->lnum = 0; + + spin_unlock(&ubi->wl_lock); + spin_unlock(&ubi->volumes_lock); + + dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum); + ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr); + if (ret) { + ubi_err("unable to write vid_hdr to fastmap SB!"); + goto out_kfree; + } + + for (i = 0; i < new_fm->used_blocks; i++) { + fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum); + fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec); + } + + fmsb->data_crc = 0; + fmsb->data_crc = cpu_to_be32(crc32(UBI_CRC32_INIT, fm_raw, + ubi->fm_size)); + + for (i = 1; i < new_fm->used_blocks; i++) { + dvhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); + dvhdr->lnum = cpu_to_be32(i); + dbg_bld("writing fastmap data to PEB %i sqnum %llu", + new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum)); + ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr); + if (ret) { + ubi_err("unable to write vid_hdr to PEB %i!", + new_fm->e[i]->pnum); + goto out_kfree; + } + } + + for (i = 0; i < new_fm->used_blocks; i++) { + ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size), + new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size); + if (ret) { + ubi_err("unable to write fastmap to PEB %i!", + new_fm->e[i]->pnum); + goto out_kfree; + } + } + + ubi_assert(new_fm); + ubi->fm = new_fm; + + dbg_bld("fastmap written!"); + +out_kfree: + ubi_free_vid_hdr(ubi, avhdr); + ubi_free_vid_hdr(ubi, dvhdr); +out: + return ret; +} + +/** + * erase_block - Manually erase a PEB. + * @ubi: UBI device object + * @pnum: PEB to be erased + * + * Returns the new EC value on success, < 0 indicates an internal error. + */ +static int erase_block(struct ubi_device *ubi, int pnum) +{ + int ret; + struct ubi_ec_hdr *ec_hdr; + long long ec; + + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ec_hdr) + return -ENOMEM; + + ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0); + if (ret < 0) + goto out; + else if (ret && ret != UBI_IO_BITFLIPS) { + ret = -EINVAL; + goto out; + } + + ret = ubi_io_sync_erase(ubi, pnum, 0); + if (ret < 0) + goto out; + + ec = be64_to_cpu(ec_hdr->ec); + ec += ret; + if (ec > UBI_MAX_ERASECOUNTER) { + ret = -EINVAL; + goto out; + } + + ec_hdr->ec = cpu_to_be64(ec); + ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); + if (ret < 0) + goto out; + + ret = ec; +out: + kfree(ec_hdr); + return ret; +} + +/** + * invalidate_fastmap - destroys a fastmap. + * @ubi: UBI device object + * @fm: the fastmap to be destroyed + * + * Returns 0 on success, < 0 indicates an internal error. + */ +static int invalidate_fastmap(struct ubi_device *ubi, + struct ubi_fastmap_layout *fm) +{ + int ret, i; + struct ubi_vid_hdr *vh; + + ret = erase_block(ubi, fm->e[0]->pnum); + if (ret < 0) + return ret; + + vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID); + if (!vh) + return -ENOMEM; + + /* deleting the current fastmap SB is not enough, an old SB may exist, + * so create a (corrupted) SB such that fastmap will find it and fall + * back to scanning mode in any case */ + vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi)); + ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh); + + for (i = 0; i < fm->used_blocks; i++) + ubi_wl_put_fm_peb(ubi, fm->e[i], i, fm->to_be_tortured[i]); + + return ret; +} + +/** + * ubi_update_fastmap - will be called by UBI if a volume changes or + * a fastmap pool becomes full. + * @ubi: UBI device object + * + * Returns 0 on success, < 0 indicates an internal error. + */ +int ubi_update_fastmap(struct ubi_device *ubi) +{ + int ret, i; + struct ubi_fastmap_layout *new_fm, *old_fm; + struct ubi_wl_entry *tmp_e; + + mutex_lock(&ubi->fm_mutex); + + ubi_refill_pools(ubi); + + if (ubi->ro_mode || ubi->fm_disabled) { + mutex_unlock(&ubi->fm_mutex); + return 0; + } + + ret = ubi_ensure_anchor_pebs(ubi); + if (ret) { + mutex_unlock(&ubi->fm_mutex); + return ret; + } + + new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); + if (!new_fm) { + mutex_unlock(&ubi->fm_mutex); + return -ENOMEM; + } + + new_fm->used_blocks = ubi->fm_size / ubi->leb_size; + + for (i = 0; i < new_fm->used_blocks; i++) { + new_fm->e[i] = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!new_fm->e[i]) { + while (i--) + kfree(new_fm->e[i]); + + kfree(new_fm); + mutex_unlock(&ubi->fm_mutex); + return -ENOMEM; + } + } + + old_fm = ubi->fm; + ubi->fm = NULL; + + if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) { + ubi_err("fastmap too large"); + ret = -ENOSPC; + goto err; + } + + for (i = 1; i < new_fm->used_blocks; i++) { + spin_lock(&ubi->wl_lock); + tmp_e = ubi_wl_get_fm_peb(ubi, 0); + spin_unlock(&ubi->wl_lock); + + if (!tmp_e && !old_fm) { + int j; + ubi_err("could not get any free erase block"); + + for (j = 1; j < i; j++) + ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0); + + ret = -ENOSPC; + goto err; + } else if (!tmp_e && old_fm) { + ret = erase_block(ubi, old_fm->e[i]->pnum); + if (ret < 0) { + int j; + + for (j = 1; j < i; j++) + ubi_wl_put_fm_peb(ubi, new_fm->e[j], + j, 0); + + ubi_err("could not erase old fastmap PEB"); + goto err; + } + + new_fm->e[i]->pnum = old_fm->e[i]->pnum; + new_fm->e[i]->ec = old_fm->e[i]->ec; + } else { + new_fm->e[i]->pnum = tmp_e->pnum; + new_fm->e[i]->ec = tmp_e->ec; + + if (old_fm) + ubi_wl_put_fm_peb(ubi, old_fm->e[i], i, + old_fm->to_be_tortured[i]); + } + } + + spin_lock(&ubi->wl_lock); + tmp_e = ubi_wl_get_fm_peb(ubi, 1); + spin_unlock(&ubi->wl_lock); + + if (old_fm) { + /* no fresh anchor PEB was found, reuse the old one */ + if (!tmp_e) { + ret = erase_block(ubi, old_fm->e[0]->pnum); + if (ret < 0) { + int i; + ubi_err("could not erase old anchor PEB"); + + for (i = 1; i < new_fm->used_blocks; i++) + ubi_wl_put_fm_peb(ubi, new_fm->e[i], + i, 0); + goto err; + } + + new_fm->e[0]->pnum = old_fm->e[0]->pnum; + new_fm->e[0]->ec = ret; + } else { + /* we've got a new anchor PEB, return the old one */ + ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0, + old_fm->to_be_tortured[0]); + + new_fm->e[0]->pnum = tmp_e->pnum; + new_fm->e[0]->ec = tmp_e->ec; + } + } else { + if (!tmp_e) { + int i; + ubi_err("could not find any anchor PEB"); + + for (i = 1; i < new_fm->used_blocks; i++) + ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0); + + ret = -ENOSPC; + goto err; + } + + new_fm->e[0]->pnum = tmp_e->pnum; + new_fm->e[0]->ec = tmp_e->ec; + } + + down_write(&ubi->work_sem); + down_write(&ubi->fm_sem); + ret = ubi_write_fastmap(ubi, new_fm); + up_write(&ubi->fm_sem); + up_write(&ubi->work_sem); + + if (ret) + goto err; + +out_unlock: + mutex_unlock(&ubi->fm_mutex); + kfree(old_fm); + return ret; + +err: + kfree(new_fm); + + ubi_warn("Unable to write new fastmap, err=%i", ret); + + ret = 0; + if (old_fm) { + ret = invalidate_fastmap(ubi, old_fm); + if (ret < 0) + ubi_err("Unable to invalidiate current fastmap!"); + else if (ret) + ret = 0; + } + goto out_unlock; +} -- cgit v1.2.3 From 128140fa8ec1ab5178594cc7a3a82f2addc2af54 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 26 Sep 2012 17:51:50 +0200 Subject: UBI: Wire-up fastmap Make fastmap known to Kconfig, UBI Makefile and MAINTAINERS. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/Kconfig | 21 +++++++++++++++++++++ drivers/mtd/ubi/Makefile | 1 + 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index 271a842f8c39..36663af56d89 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -56,6 +56,27 @@ config MTD_UBI_BEB_LIMIT Leave the default value if unsure. +config MTD_UBI_FASTMAP + bool "UBI Fastmap (Experimental feature)" + default n + help + Important: this feature is experimental so far and the on-flash + format for fastmap may change in the next kernel versions + + Fastmap is a mechanism which allows attaching an UBI device + in nearly constant time. Instead of scanning the whole MTD device it + only has to locate a checkpoint (called fastmap) on the device. + The on-flash fastmap contains all information needed to attach + the device. Using fastmap makes only sense on large devices where + attaching by scanning takes long. UBI will not automatically install + a fastmap on old images, but you can set the UBI module parameter + fm_autoconvert to 1 if you want so. Please note that fastmap-enabled + images are still usable with UBI implementations without + fastmap support. On typical flash devices the whole fastmap fits + into one PEB. UBI will reserve PEBs to hold two fastmaps. + + If in doubt, say "N". + config MTD_UBI_GLUEBI tristate "MTD devices emulation driver (gluebi)" help diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile index a0803ac74712..b46b0c978581 100644 --- a/drivers/mtd/ubi/Makefile +++ b/drivers/mtd/ubi/Makefile @@ -2,5 +2,6 @@ obj-$(CONFIG_MTD_UBI) += ubi.o ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o ubi-y += misc.o debug.o +ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o -- cgit v1.2.3 From 956751d73e93d411908df5965700cf6946d38df8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 9 Oct 2012 14:14:21 +0800 Subject: UBI: use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 1a5f53c090d4..0648c6996d43 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -814,10 +814,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, if (max_sqnum > ai->max_sqnum) ai->max_sqnum = max_sqnum; - list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { - list_del(&tmp_aeb->u.list); - list_add_tail(&tmp_aeb->u.list, &ai->free); - } + list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) + list_move_tail(&tmp_aeb->u.list, &ai->free); /* * If fastmap is leaking PEBs (must not happen), raise a -- cgit v1.2.3 From c156252e6b0d16ee5b8a46c98b1b38b80ed061c1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 26 Oct 2012 16:11:26 +0300 Subject: UBI: do not allocate the memory unnecessarily UBI reserves an LEB sized buffer for various needs. We can use this buffer while scanning, instead of allocating another one. This patch was originally created by Jan Luebbe , but then he dropped it and I picked up and tweaked a little bit. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index f36a5139a40d..8f0e9e882a03 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -322,7 +322,6 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, int pnum, const struct ubi_vid_hdr *vid_hdr) { - void *buf; int len, err, second_is_newer, bitflips = 0, corrupted = 0; uint32_t data_crc, crc; struct ubi_vid_hdr *vh = NULL; @@ -393,18 +392,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, /* Read the data of the copy and check the CRC */ len = be32_to_cpu(vid_hdr->data_size); - buf = vmalloc(len); - if (!buf) { - err = -ENOMEM; - goto out_free_vidh; - } - err = ubi_io_read_data(ubi, buf, pnum, 0, len); + mutex_lock(&ubi->buf_mutex); + err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len); if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) - goto out_free_buf; + goto out_unlock; data_crc = be32_to_cpu(vid_hdr->data_crc); - crc = crc32(UBI_CRC32_INIT, buf, len); + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len); if (crc != data_crc) { dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", pnum, crc, data_crc); @@ -415,8 +410,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, dbg_bld("PEB %d CRC is OK", pnum); bitflips = !!err; } + mutex_unlock(&ubi->buf_mutex); - vfree(buf); ubi_free_vid_hdr(ubi, vh); if (second_is_newer) @@ -426,8 +421,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, return second_is_newer | (bitflips << 1) | (corrupted << 2); -out_free_buf: - vfree(buf); +out_unlock: + mutex_unlock(&ubi->buf_mutex); out_free_vidh: ubi_free_vid_hdr(ubi, vh); return err; -- cgit v1.2.3 From eb5031376777a6d777c65da4877c18ce51541fcb Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 19 Nov 2012 20:35:20 -0300 Subject: UBI: gluebi: rename misleading variables Both names 'total_read' and 'total_written' are actually used as the number of bytes left to read and write. Fix this confusion by renaming both to 'bytes_left'. Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/gluebi.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index dd8f6bdab7b4..782f12d7756b 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -171,7 +171,7 @@ static void gluebi_put_device(struct mtd_info *mtd) static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, unsigned char *buf) { - int err = 0, lnum, offs, total_read; + int err = 0, lnum, offs, bytes_left; struct gluebi_device *gluebi; if (len < 0 || from < 0 || from + len > mtd->size) @@ -180,12 +180,12 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, gluebi = container_of(mtd, struct gluebi_device, mtd); lnum = div_u64_rem(from, mtd->erasesize, &offs); - total_read = len; - while (total_read) { + bytes_left = len; + while (bytes_left) { size_t to_read = mtd->erasesize - offs; - if (to_read > total_read) - to_read = total_read; + if (to_read > bytes_left) + to_read = bytes_left; err = ubi_read(gluebi->desc, lnum, buf, offs, to_read); if (err) @@ -193,11 +193,11 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, lnum += 1; offs = 0; - total_read -= to_read; + bytes_left -= to_read; buf += to_read; } - *retlen = len - total_read; + *retlen = len - bytes_left; return err; } @@ -215,7 +215,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - int err = 0, lnum, offs, total_written; + int err = 0, lnum, offs, bytes_left; struct gluebi_device *gluebi; if (len < 0 || to < 0 || len + to > mtd->size) @@ -231,12 +231,12 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, if (len % mtd->writesize || offs % mtd->writesize) return -EINVAL; - total_written = len; - while (total_written) { + bytes_left = len; + while (bytes_left) { size_t to_write = mtd->erasesize - offs; - if (to_write > total_written) - to_write = total_written; + if (to_write > bytes_left) + to_write = bytes_left; err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write); if (err) @@ -244,11 +244,11 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, lnum += 1; offs = 0; - total_written -= to_write; + bytes_left -= to_write; buf += to_write; } - *retlen = len - total_written; + *retlen = len - bytes_left; return err; } -- cgit v1.2.3 From a4dbb6061a4db270b3807b0b402112d6ad20c4e6 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 21 Nov 2012 12:46:12 -0300 Subject: UBI: remove spurious comment This line of comment looks completely bogus. It was introduced in: commit d99383b00eba9c6ac3dea462d718b2849012ee03 Author: Artem Bityutskiy Date: Wed May 18 14:47:34 2011 +0300 UBI: change the interface of a debugging check function Remove it. Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index da7b44998b40..ae955174f6ef 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1,5 +1,4 @@ /* - * @ubi: UBI device description object * Copyright (c) International Business Machines Corp., 2006 * * This program is free software; you can redistribute it and/or modify -- cgit v1.2.3 From 2f85492ddb51d6dc595ebb9401c4b56ea4e6a2bb Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 23 Nov 2012 08:58:05 -0300 Subject: UBI: replace memcpy with struct assignment This kind of memcpy() is error-prone. Its replacement with a struct assignment is prefered because it's type-safe and much easier to read. Found by coccinelle. Hand patched and reviewed. Tested by compilation only. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier struct_name; struct struct_name to; struct struct_name from; expression E; @@ -memcpy(&(to), &(from), E); +to = from; // Signed-off-by: Peter Senna Tschudin Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 3 +-- drivers/mtd/ubi/upd.c | 6 ++---- drivers/mtd/ubi/vmt.c | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 990c93c61d07..bf1ebb1ed60e 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -825,8 +825,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * No available PEBs to re-size the volume, clear the flag on * flash and exit. */ - memcpy(&vtbl_rec, &ubi->vtbl[vol_id], - sizeof(struct ubi_vtbl_record)); + vtbl_rec = ubi->vtbl[vol_id]; err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) ubi_err("cannot clean auto-resize flag for volume %d", diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 9f2ebd8750e7..ec2c2dc1c1ca 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -64,8 +64,7 @@ static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol) return 0; } - memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], - sizeof(struct ubi_vtbl_record)); + vtbl_rec = ubi->vtbl[vol->vol_id]; vtbl_rec.upd_marker = 1; mutex_lock(&ubi->device_mutex); @@ -93,8 +92,7 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, dbg_gen("clear update marker for volume %d", vol->vol_id); - memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], - sizeof(struct ubi_vtbl_record)); + vtbl_rec = ubi->vtbl[vol->vol_id]; ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); vtbl_rec.upd_marker = 0; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 04ba8bc7f1ca..87a78d307ea0 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -534,7 +534,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) } /* Change volume table record */ - memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); + vtbl_rec = ubi->vtbl[vol_id]; vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) -- cgit v1.2.3 From faf1e8678ee3068298d2598ad424701380a1f747 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 3 Dec 2012 20:57:46 +0100 Subject: UBI: remove PEB from free tree in get_peb_for_wl() If UBI is built without fastmap, get_peb_for_wl() has to remove the PEB manially from the free tree. Otherwise the requested PEB lives in two trees. Reported-by: Zach Sadecki Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index ae955174f6ef..773e6c8f42f4 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -678,7 +678,13 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) #else static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) { - return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + struct ubi_wl_entry *e; + + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); + self_check_in_wl_tree(ubi, e, &ubi->free); + rb_erase(&e->u.rb, &ubi->free); + + return e; } int ubi_wl_get_peb(struct ubi_device *ubi) -- cgit v1.2.3 From 15ea159a31e5956a4d6ef3b7c01411d40ecbc2a6 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 3 Dec 2012 20:57:47 +0100 Subject: UBI: dont call ubi_self_check_all_ff() in __wl_get_peb() As ubi_self_check_all_ff() might sleep we are not allowed to call it from atomic context. For now we call it only from ubi_wl_get_peb(). There are some code paths where it would also make sense, but these paths are currently atomic and only enabled when fastmap is used. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 773e6c8f42f4..1fbdcaec808c 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -497,7 +497,7 @@ out: * @ubi: UBI device description object * * This function returns a physical eraseblock in case of success and a - * negative error code in case of failure. Might sleep. + * negative error code in case of failure. */ static int __wl_get_peb(struct ubi_device *ubi) { @@ -539,13 +539,6 @@ retry: * ubi_wl_get_peb() after removing e from the pool. */ prot_queue_add(ubi, e); #endif - err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, - ubi->peb_size - ubi->vid_hdr_aloffset); - if (err) { - ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); - return err; - } - return e->pnum; } @@ -689,12 +682,19 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) int ubi_wl_get_peb(struct ubi_device *ubi) { - int peb; + int peb, err; spin_lock(&ubi->wl_lock); peb = __wl_get_peb(ubi); spin_unlock(&ubi->wl_lock); + err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, + ubi->peb_size - ubi->vid_hdr_aloffset); + if (err) { + ubi_err("new PEB %d does not contain all 0xFF bytes", peb); + return err; + } + return peb; } #endif -- cgit v1.2.3 From 8e9e752a8e981f35b14d53a779f9bea15703bf73 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 28 Nov 2012 09:18:29 -0300 Subject: UBI: introduce helpers dbg_chk_{io, gen} With this patch code is a bit more readable and there's no generated code or functionality impact. Furthermore, this abstracts implementation details and will allow to change ubi_debug_info in a less invasive way. Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/attach.c | 4 ++-- drivers/mtd/ubi/debug.h | 9 +++++++++ drivers/mtd/ubi/io.c | 14 +++++++------- drivers/mtd/ubi/vmt.c | 2 +- drivers/mtd/ubi/vtbl.c | 2 +- drivers/mtd/ubi/wl.c | 6 +++--- 6 files changed, 23 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 8f0e9e882a03..5da50606affd 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1448,7 +1448,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) goto out_wl; #ifdef CONFIG_MTD_UBI_FASTMAP - if (ubi->fm && ubi->dbg->chk_gen) { + if (ubi->fm && ubi_dbg_chk_gen(ubi)) { struct ubi_attach_info *scan_ai; scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); @@ -1498,7 +1498,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) struct ubi_ainf_peb *aeb, *last_aeb; uint8_t *buf; - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return 0; /* diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 3dbc877d9663..0add8d8a1672 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -158,4 +158,13 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) return 0; } +static inline int ubi_dbg_chk_io(const struct ubi_device *ubi) +{ + return ubi->dbg->chk_io; +} + +static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi) +{ + return ubi->dbg->chk_gen; +} #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 3881b676c6cd..545483018cde 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -1133,7 +1133,7 @@ static int self_check_not_bad(const struct ubi_device *ubi, int pnum) { int err; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; err = ubi_io_is_bad(ubi, pnum); @@ -1160,7 +1160,7 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, int err; uint32_t magic; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; magic = be32_to_cpu(ec_hdr->magic); @@ -1198,7 +1198,7 @@ static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) uint32_t crc, hdr_crc; struct ubi_ec_hdr *ec_hdr; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); @@ -1242,7 +1242,7 @@ static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, int err; uint32_t magic; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; magic = be32_to_cpu(vid_hdr->magic); @@ -1283,7 +1283,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) struct ubi_vid_hdr *vid_hdr; void *p; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); @@ -1335,7 +1335,7 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, void *buf1; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); @@ -1399,7 +1399,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; - if (!ubi->dbg->chk_io) + if (!ubi_dbg_chk_io(ubi)) return 0; buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 87a78d307ea0..e4c677a4c969 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -846,7 +846,7 @@ static int self_check_volumes(struct ubi_device *ubi) { int i, err = 0; - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return 0; for (i = 0; i < ubi->vtbl_slots; i++) { diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index b2d4e97238f9..30f84eff6385 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -858,7 +858,7 @@ out_free: */ static void self_vtbl_check(const struct ubi_device *ubi) { - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return; if (vtbl_check(ubi, ubi->vtbl)) { diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 1fbdcaec808c..5df49d3cb5c7 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -2049,7 +2049,7 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) long long read_ec; struct ubi_ec_hdr *ec_hdr; - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return 0; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); @@ -2089,7 +2089,7 @@ out_free: static int self_check_in_wl_tree(const struct ubi_device *ubi, struct ubi_wl_entry *e, struct rb_root *root) { - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return 0; if (in_wl_tree(e, root)) @@ -2115,7 +2115,7 @@ static int self_check_in_pq(const struct ubi_device *ubi, struct ubi_wl_entry *p; int i; - if (!ubi->dbg->chk_gen) + if (!ubi_dbg_chk_gen(ubi)) return 0; for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) -- cgit v1.2.3 From 739c363d5c8d45914a509446a2f2ce084e90053a Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 28 Nov 2012 09:18:30 -0300 Subject: UBI: embed ubi_debug_info field in ubi_device struct ubi_debug_info struct was dynamically allocated which is always suboptimal, for it tends to fragment memory and make the code error-prone. Fix this by embedding it in ubi_device struct. Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 9 +-------- drivers/mtd/ubi/debug.c | 34 ++++---------------------------- drivers/mtd/ubi/debug.h | 52 ++++++------------------------------------------- drivers/mtd/ubi/ubi.h | 40 ++++++++++++++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index bf1ebb1ed60e..85664c9bcead 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -985,14 +985,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi->fm_buf) goto out_free; #endif - err = ubi_debugging_init_dev(ubi); - if (err) - goto out_free; - err = ubi_attach(ubi, 0); if (err) { ubi_err("failed to attach mtd%d, error %d", mtd->index, err); - goto out_debugging; + goto out_free; } if (ubi->autoresize_vol_id != -1) { @@ -1059,8 +1055,6 @@ out_detach: ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); -out_debugging: - ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf); vfree(ubi->fm_buf); @@ -1138,7 +1132,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); - ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf); vfree(ubi->fm_buf); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 33a60a5bc859..790bca4f9283 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -217,32 +217,6 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) pr_err("\t1st 16 characters of name: %s\n", nm); } -/** - * ubi_debugging_init_dev - initialize debugging for an UBI device. - * @ubi: UBI device description object - * - * This function initializes debugging-related data for UBI device @ubi. - * Returns zero in case of success and a negative error code in case of - * failure. - */ -int ubi_debugging_init_dev(struct ubi_device *ubi) -{ - ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL); - if (!ubi->dbg) - return -ENOMEM; - - return 0; -} - -/** - * ubi_debugging_exit_dev - free debugging data for an UBI device. - * @ubi: UBI device description object - */ -void ubi_debugging_exit_dev(struct ubi_device *ubi) -{ - kfree(ubi->dbg); -} - /* * Root directory for UBI stuff in debugfs. Contains sub-directories which * contain the stuff specific to particular UBI devices. @@ -295,7 +269,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, ubi = ubi_get_device(ubi_num); if (!ubi) return -ENODEV; - d = ubi->dbg; + d = &ubi->dbg; if (dent == d->dfs_chk_gen) val = d->chk_gen; @@ -341,7 +315,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ubi = ubi_get_device(ubi_num); if (!ubi) return -ENODEV; - d = ubi->dbg; + d = &ubi->dbg; buf_size = min_t(size_t, count, (sizeof(buf) - 1)); if (copy_from_user(buf, user_buf, buf_size)) { @@ -406,7 +380,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) unsigned long ubi_num = ubi->ubi_num; const char *fname; struct dentry *dent; - struct ubi_debug_info *d = ubi->dbg; + struct ubi_debug_info *d = &ubi->dbg; if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; @@ -479,5 +453,5 @@ out: void ubi_debugfs_exit_dev(struct ubi_device *ubi) { if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(ubi->dbg->dfs_dir); + debugfs_remove_recursive(ubi->dbg.dfs_dir); } diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 0add8d8a1672..33f8f3b2c9b2 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h @@ -60,51 +60,11 @@ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type); void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); -int ubi_debugging_init_dev(struct ubi_device *ubi); -void ubi_debugging_exit_dev(struct ubi_device *ubi); int ubi_debugfs_init(void); void ubi_debugfs_exit(void); int ubi_debugfs_init_dev(struct ubi_device *ubi); void ubi_debugfs_exit_dev(struct ubi_device *ubi); -/* - * The UBI debugfs directory name pattern and maximum name length (3 for "ubi" - * + 2 for the number plus 1 for the trailing zero byte. - */ -#define UBI_DFS_DIR_NAME "ubi%d" -#define UBI_DFS_DIR_LEN (3 + 2 + 1) - -/** - * struct ubi_debug_info - debugging information for an UBI device. - * - * @chk_gen: if UBI general extra checks are enabled - * @chk_io: if UBI I/O extra checks are enabled - * @disable_bgt: disable the background task for testing purposes - * @emulate_bitflips: emulate bit-flips for testing purposes - * @emulate_io_failures: emulate write/erase failures for testing purposes - * @dfs_dir_name: name of debugfs directory containing files of this UBI device - * @dfs_dir: direntry object of the UBI device debugfs directory - * @dfs_chk_gen: debugfs knob to enable UBI general extra checks - * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks - * @dfs_disable_bgt: debugfs knob to disable the background task - * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips - * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures - */ -struct ubi_debug_info { - unsigned int chk_gen:1; - unsigned int chk_io:1; - unsigned int disable_bgt:1; - unsigned int emulate_bitflips:1; - unsigned int emulate_io_failures:1; - char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; - struct dentry *dfs_dir; - struct dentry *dfs_chk_gen; - struct dentry *dfs_chk_io; - struct dentry *dfs_disable_bgt; - struct dentry *dfs_emulate_bitflips; - struct dentry *dfs_emulate_io_failures; -}; - /** * ubi_dbg_is_bgt_disabled - if the background thread is disabled. * @ubi: UBI device description object @@ -114,7 +74,7 @@ struct ubi_debug_info { */ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) { - return ubi->dbg->disable_bgt; + return ubi->dbg.disable_bgt; } /** @@ -125,7 +85,7 @@ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) */ static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) { - if (ubi->dbg->emulate_bitflips) + if (ubi->dbg.emulate_bitflips) return !(random32() % 200); return 0; } @@ -139,7 +99,7 @@ static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) */ static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) { - if (ubi->dbg->emulate_io_failures) + if (ubi->dbg.emulate_io_failures) return !(random32() % 500); return 0; } @@ -153,18 +113,18 @@ static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) */ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) { - if (ubi->dbg->emulate_io_failures) + if (ubi->dbg.emulate_io_failures) return !(random32() % 400); return 0; } static inline int ubi_dbg_chk_io(const struct ubi_device *ubi) { - return ubi->dbg->chk_io; + return ubi->dbg.chk_io; } static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi) { - return ubi->dbg->chk_gen; + return ubi->dbg.chk_gen; } #endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 7d57469723cf..8ea6297a208f 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -84,6 +84,13 @@ /* The volume ID/LEB number/erase counter is unknown */ #define UBI_UNKNOWN -1 +/* + * The UBI debugfs directory name pattern and maximum name length (3 for "ubi" + * + 2 for the number plus 1 for the trailing zero byte. + */ +#define UBI_DFS_DIR_NAME "ubi%d" +#define UBI_DFS_DIR_LEN (3 + 2 + 1) + /* * Error codes returned by the I/O sub-system. * @@ -341,6 +348,37 @@ struct ubi_volume_desc { struct ubi_wl_entry; +/** + * struct ubi_debug_info - debugging information for an UBI device. + * + * @chk_gen: if UBI general extra checks are enabled + * @chk_io: if UBI I/O extra checks are enabled + * @disable_bgt: disable the background task for testing purposes + * @emulate_bitflips: emulate bit-flips for testing purposes + * @emulate_io_failures: emulate write/erase failures for testing purposes + * @dfs_dir_name: name of debugfs directory containing files of this UBI device + * @dfs_dir: direntry object of the UBI device debugfs directory + * @dfs_chk_gen: debugfs knob to enable UBI general extra checks + * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks + * @dfs_disable_bgt: debugfs knob to disable the background task + * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips + * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures + */ +struct ubi_debug_info { + unsigned int chk_gen:1; + unsigned int chk_io:1; + unsigned int disable_bgt:1; + unsigned int emulate_bitflips:1; + unsigned int emulate_io_failures:1; + char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; + struct dentry *dfs_dir; + struct dentry *dfs_chk_gen; + struct dentry *dfs_chk_io; + struct dentry *dfs_disable_bgt; + struct dentry *dfs_emulate_bitflips; + struct dentry *dfs_emulate_io_failures; +}; + /** * struct ubi_device - UBI device description structure * @dev: UBI device object to use the the Linux device model @@ -545,7 +583,7 @@ struct ubi_device { struct mutex buf_mutex; struct mutex ckvol_mutex; - struct ubi_debug_info *dbg; + struct ubi_debug_info dbg; }; /** -- cgit v1.2.3 From 7f7b3145889da64644f04f026101f33e1702357f Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 17 Dec 2012 16:04:23 -0800 Subject: random32: rename random32 to prandom This renames all random32 functions to have 'prandom_' prefix as follows: void prandom_seed(u32 seed); /* rename from srandom32() */ u32 prandom_u32(void); /* rename from random32() */ void prandom_seed_state(struct rnd_state *state, u64 seed); /* rename from prandom32_seed() */ u32 prandom_u32_state(struct rnd_state *state); /* rename from prandom32() */ The purpose of this renaming is to prevent some kernel developers from assuming that prandom32() and random32() might imply that only prandom32() was the one using a pseudo-random number generator by prandom32's "p", and the result may be a very embarassing security exposure. This concern was expressed by Theodore Ts'o. And furthermore, I'm going to introduce new functions for getting the requested number of pseudo-random bytes. If I continue to use both prandom32 and random32 prefixes for these functions, the confusion is getting worse. As a result of this renaming, "prandom_" is the common prefix for pseudo-random number library. Currently, srandom32() and random32() are preserved because it is difficult to rename too many users at once. Signed-off-by: Akinobu Mita Cc: "Theodore Ts'o" Cc: Robert Love Cc: Michel Lespinasse Cc: Valdis Kletnieks Cc: David Laight Cc: Adrian Hunter Cc: Artem Bityutskiy Cc: David Woodhouse Cc: Eilon Greenstein Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/fcoe/fcoe_ctlr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index c74c4b8e71ef..812c5b935363 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2026,7 +2026,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip) */ port_id = fip->port_id; if (fip->probe_tries) - port_id = prandom32(&fip->rnd_state) & 0xffff; + port_id = prandom_u32_state(&fip->rnd_state) & 0xffff; else if (!port_id) port_id = fip->lp->wwpn & 0xffff; if (!port_id || port_id == 0xffff) @@ -2051,7 +2051,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip) static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) { fip->probe_tries = 0; - prandom32_seed(&fip->rnd_state, fip->lp->wwpn); + prandom_seed_state(&fip->rnd_state, fip->lp->wwpn); fcoe_ctlr_vn_restart(fip); } -- cgit v1.2.3 From 141b74db72a4f04dcee8cd59275f191a4e1cefd2 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 17 Dec 2012 16:04:32 -0800 Subject: mtd: nandsim: use prandom_bytes This also removes unnecessary memset call which is immediately overwritten with random bytes. Signed-off-by: Akinobu Mita Cc: Artem Bityutskiy Cc: David Woodhouse Cc: "Theodore Ts'o" Cc: Adrian Hunter Cc: David Laight Cc: Eilon Greenstein Cc: Michel Lespinasse Cc: Robert Love Cc: Valdis Kletnieks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/nand/nandsim.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 357e8c5252a8..84ee1a36eb2c 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -1408,10 +1408,7 @@ int do_read_error(struct nandsim *ns, int num) unsigned int page_no = ns->regs.row; if (read_error(page_no)) { - int i; - memset(ns->buf.byte, 0xFF, num); - for (i = 0; i < num; ++i) - ns->buf.byte[i] = random32(); + prandom_bytes(ns->buf.byte, num); NS_WARN("simulating read error in page %u\n", page_no); return 1; } -- cgit v1.2.3 From b16cdf1b8d60c4c64605bca6e63fe3d1d57c6edb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 3 May 2013 14:54:34 -0400 Subject: UBI: drop redundant "UBI error" string The ubi_err() macro automatically prefixes "UBI error" before the message. By also using it here, we get a log like so: UBI error: ubi_init: UBI error: cannot initialize UBI, error -19 Signed-off-by: Mike Frysinger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 85664c9bcead..77d70f7502bd 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1309,7 +1309,7 @@ out_version: out_class: class_destroy(ubi_class); out: - ubi_err("UBI error: cannot initialize UBI, error %d", err); + ubi_err("cannot initialize UBI, error %d", err); return err; } late_initcall(ubi_init); @@ -1346,7 +1346,7 @@ static int __init bytes_str_to_int(const char *str) result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); + ubi_err("incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1362,7 +1362,7 @@ static int __init bytes_str_to_int(const char *str) case '\0': break; default: - ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); + ubi_err("incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1389,14 +1389,14 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - ubi_err("UBI error: too many parameters, max. is %d\n", + ubi_err("too many parameters, max. is %d\n", UBI_MAX_DEVICES); return -EINVAL; } len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + ubi_err("parameter \"%s\" is too long, max. is %d\n", val, MTD_PARAM_LEN_MAX); return -EINVAL; } @@ -1416,7 +1416,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) tokens[i] = strsep(&pbuf, ","); if (pbuf) { - ubi_err("UBI error: too many arguments at \"%s\"\n", val); + ubi_err("too many arguments at \"%s\"\n", val); return -EINVAL; } @@ -1433,7 +1433,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); if (err) { - ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s", + ubi_err("bad value for max_beb_per1024 parameter: %s", tokens[2]); return -EINVAL; } -- cgit v1.2.3 From f08cdd4be3bf5ae2620716ed7779c56900ba30eb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 22 Apr 2013 21:40:16 -0400 Subject: UBI: do not abort init when ubi.mtd devices cannot be found The current ubi.mtd parsing logic will warn & continue on when attaching the specified mtd device fails (for any reason). It doesn't however skip things when the specified mtd device can't be opened. This scenario can be hit in a couple of different ways such as: - build NAND controller driver as a module - build UBI into the kernel - include ubi.mtd on the kernel command line - boot the system - MTD devices don't exist, so UBI init fails This is problematic because failing init means the entire UBI layer is unavailable until you reboot and modify the kernel command line. If we just warn and continue on, /dev/ubi_ctrl is available for userland to add UBI volumes on the fly once it loads the NAND driver. Signed-off-by: Mike Frysinger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 77d70f7502bd..52f3ff5570e0 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1261,7 +1261,11 @@ static int __init ubi_init(void) mtd = open_mtd_device(p->name); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - goto out_detach; + ubi_err("cannot open mtd %s, error %d", p->name, err); + /* See comment below re-ubi_is_module(). */ + if (ubi_is_module()) + goto out_detach; + continue; } mutex_lock(&ubi_devices_mutex); -- cgit v1.2.3 From 7e07518e542e653b67852a1c1d4f90fa914a0453 Mon Sep 17 00:00:00 2001 From: Brian Pomerantz Date: Wed, 1 May 2013 17:10:44 -0700 Subject: UBI: fastmap break out of used PEB search While searching for PEB matches for each volume in the used PEB list, the search fails to stop when the PEB is found. This patch adds a break in the inner loop to stop the search when it is matched. Signed-off-by: Brian Pomerantz Acked-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/fastmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 0648c6996d43..154275182b4b 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -727,8 +727,10 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, aeb = NULL; list_for_each_entry(tmp_aeb, &used, u.list) { - if (tmp_aeb->pnum == pnum) + if (tmp_aeb->pnum == pnum) { aeb = tmp_aeb; + break; + } } /* This can happen if a PEB is already in an EBA known -- cgit v1.2.3 From f1a60a56b7ac367b5285694cd02574e4edbe4c47 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 3 May 2013 14:55:23 -0400 Subject: UBI: support ubi_num on mtd.ubi command line I want to be able to add UBI volumes with specific numbers, but the command line API doesn't have that atm. Add an additional token to support it. Artem: amended the patch a little bit. Signed-off-by: Mike Frysinger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 52f3ff5570e0..939018c27cb7 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -47,7 +47,7 @@ #define MTD_PARAM_LEN_MAX 64 /* Maximum number of comma-separated items in the 'mtd=' parameter */ -#define MTD_PARAM_MAX_COUNT 3 +#define MTD_PARAM_MAX_COUNT 4 /* Maximum value for the number of bad PEBs per 1024 PEBs */ #define MAX_MTD_UBI_BEB_LIMIT 768 @@ -67,6 +67,7 @@ */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; + int ubi_num; int vid_hdr_offs; int max_beb_per1024; }; @@ -1269,7 +1270,7 @@ static int __init ubi_init(void) } mutex_lock(&ubi_devices_mutex); - err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, + err = ubi_attach_mtd_dev(mtd, p->ubi_num, p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { @@ -1387,7 +1388,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; - char *tokens[MTD_PARAM_MAX_COUNT]; + char *tokens[MTD_PARAM_MAX_COUNT], *token; if (!val) return -EINVAL; @@ -1427,37 +1428,53 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) p = &mtd_dev_param[mtd_devs]; strcpy(&p->name[0], tokens[0]); - if (tokens[1]) - p->vid_hdr_offs = bytes_str_to_int(tokens[1]); + token = tokens[1]; + if (token) { + p->vid_hdr_offs = bytes_str_to_int(token); - if (p->vid_hdr_offs < 0) - return p->vid_hdr_offs; + if (p->vid_hdr_offs < 0) + return p->vid_hdr_offs; + } - if (tokens[2]) { - int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); + token = tokens[2]; + if (token) { + int err = kstrtoint(token, 10, &p->max_beb_per1024); if (err) { ubi_err("bad value for max_beb_per1024 parameter: %s", - tokens[2]); + token); return -EINVAL; } } + token = tokens[3]; + if (token) { + int err = kstrtoint(token, 10, &p->ubi_num); + + if (err) { + ubi_err("bad value for ubi_num parameter: %s", token); + return -EINVAL; + } + } else + p->ubi_num = UBI_DEV_NUM_AUTO; + mtd_devs += 1; return 0; } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=[,[,max_beb_per1024]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=[,[,max_beb_per1024[,ubi_num]]].\n" "Multiple \"mtd\" parameters may be specified.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" "Optional \"max_beb_per1024\" parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value (" __stringify(CONFIG_MTD_UBI_BEB_LIMIT) ") if 0)\n" + "Optional \"ubi_num\" parameter specifies UBI device number which have to be assigned to the newly created UBI device (assigned automatically by default)\n" "\n" "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" + "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); -- cgit v1.2.3