Commit 65b99c74 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'upstream-3.7-rc1' of git://git.infradead.org/linux-ubi

Pull UBI changes from Artem Bityutskiy:
 "The main change is the way we reserve eraseblocks for bad blocks
  handling.  We used to reserve 2% of the partition, but now we are more
  aggressive and we reserve 2% of the entire chip, which is what
  actually manufacturers specify in data sheets.  We introduced an
  option to users to override the default, though.

  There are a couple of fixes as well, and a number of cleanups."

* tag 'upstream-3.7-rc1' of git://git.infradead.org/linux-ubi: (24 commits)
  UBI: fix trivial typo 'it' => 'is'
  UBI: load after mtd device drivers
  UBI: print less
  UBI: use pr_ helper instead of printk
  UBI: comply with coding style
  UBI: erase free PEB with bitflip in EC header
  UBI: fix autoresize handling in R/O mode
  UBI: add max_beb_per1024 to attach ioctl
  UBI: allow specifying bad PEBs limit using module parameter
  UBI: check max_beb_per1024 value in ubi_attach_mtd_dev
  UBI: prepare for max_beb_per1024 module parameter addition
  UBI: introduce MTD_PARAM_MAX_COUNT
  UBI: separate bad_peb_limit in a function
  arm: sam9_l9260_defconfig: correct CONFIG_MTD_UBI_BEB_LIMIT
  UBI: use the whole MTD device size to get bad_peb_limit
  mtd: mtdparts: introduce mtd_get_device_size
  mtd: mark mtd_is_partition argument as constant
  arm: sam9_l9260_defconfig: remove non-existing config option
  UBI: kill CONFIG_MTD_UBI_BEB_RESERVE
  UBI: limit amount of reserved eraseblocks for bad PEB handling
  ...
parents 782c3fb2 55393ba1
......@@ -39,7 +39,7 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ATMEL=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_RESERVE=3
CONFIG_MTD_UBI_BEB_LIMIT=25
CONFIG_MTD_UBI_GLUEBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
......
......@@ -744,7 +744,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
return ret;
}
int mtd_is_partition(struct mtd_info *mtd)
int mtd_is_partition(const struct mtd_info *mtd)
{
struct mtd_part *part;
int ispart = 0;
......@@ -760,3 +760,13 @@ int mtd_is_partition(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);
......@@ -27,20 +27,34 @@ 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
config MTD_UBI_BEB_LIMIT
int "Maximum expected bad eraseblock count per 1024 eraseblocks"
default 20
range 0 768
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.
This option specifies the maximum bad physical eraseblocks UBI
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.
This option can be overridden by the "mtd=" UBI module parameter or
by the "attach" ioctl.
Leave the default value if unsure.
config MTD_UBI_GLUEBI
tristate "MTD devices emulation driver (gluebi)"
......
......@@ -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 <linux/err.h>
......@@ -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,12 +790,12 @@ 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);
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;
......@@ -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;
}
......@@ -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
......@@ -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)
......@@ -1075,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,
......@@ -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;
}
......@@ -1172,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)
......@@ -1244,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)
......
This diff is collapsed.
......@@ -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;
......@@ -753,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);
}
......@@ -811,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);
}
......@@ -942,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;
......@@ -1010,7 +1011,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,
req.max_beb_per1024);
mutex_unlock(&ubi_devices_mutex);
if (err < 0)
put_mtd_device(mtd);
......
This diff is collapsed.
......@@ -29,22 +29,18 @@ 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, ...) \
pr_debug("UBI DBG " type ": " fmt "\n", ##__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", \
current->pid, __func__, ##__VA_ARGS__)
pr_debug("UBI DBG " type " (pid %d): " fmt "\n", current->pid, \
##__VA_ARGS__)
/* General debugging messages */
#define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__)
......
......@@ -420,9 +420,8 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
*/
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 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
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);
}
/**
......
......@@ -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__)
/**
......@@ -341,9 +341,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)) {
......@@ -376,8 +375,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;
......@@ -390,9 +389,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);
......@@ -422,8 +420,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;
}
......@@ -449,8 +447,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;
......@@ -507,9 +505,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);
}
......
......@@ -177,21 +177,20 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
* 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;
}
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 = 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
......@@ -685,8 +684,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;
}
......@@ -777,10 +775,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
......@@ -792,12 +790,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;
}
......@@ -806,12 +804,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;
......@@ -1032,10 +1030,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
......@@ -1043,12 +1041,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;
}
......@@ -1057,12 +1055,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
......@@ -1300,8 +1298,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();
......@@ -1411,15 +1409,15 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
err = mtd_read(ubi->mtd, addr, len, &read, buf);
if (err && !mtd_is_bitflip(err)) {
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;
}
......
......@@ -121,10 +121,16 @@ 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);
}
}
/**
......
......@@ -51,17 +51,14 @@
#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__)
/* 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"
......@@ -363,6 +360,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 +408,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;
......@@ -694,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);
......
......@@ -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;
......@@ -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)
......@@ -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;
}
......
......@@ -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;
}
......@@ -1189,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);
......
......@@ -79,9 +79,10 @@ struct mtd_part_parser {
extern int register_mtd_parser(struct mtd_part_parser *parser);
extern int deregister_mtd_parser(struct mtd_part_parser *parser);
int mtd_is_partition(struct mtd_info *mtd);
int mtd_is_partition(const struct mtd_info *mtd);
int mtd_add_partition(struct mtd_info *master, char *name,
long long offset, long long length);
int mtd_del_partition(struct mtd_info *master, int partno);
uint64_t mtd_get_device_size(const struct mtd_info *mtd);
#endif
......@@ -222,6 +222,7 @@ enum {
* @ubi_num: UBI device number to create
* @mtd_num: MTD device number to attach
* @vid_hdr_offset: VID header offset (use defaults if %0)
* @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
* @padding: reserved for future, not used, has to be zeroed
*
* This data structure is used to specify MTD device UBI has to attach and the
......@@ -245,12 +246,25 @@ enum {
* be 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes
* aligned, which is OK, as UBI is clever enough to realize this is 4th
* sub-page of the first page and add needed padding.
*
* The @max_beb_per1024 is the maximum amount of bad PEBs UBI expects on the
* UBI device per 1024 eraseblocks. This value is often given in an other form
* in the NAND datasheet (min NVB i.e. minimal number of valid blocks). The
* maximum expected bad eraseblocks per 1024 is then:
* 1024 * (1 - MinNVB / MaxNVB)
* Which gives 20 for most NAND devices. This limit is used in order to derive
* amount of eraseblock UBI reserves for handling new bad blocks. If the device
* has more bad eraseblocks than this limit, UBI does not reserve any physical
* eraseblocks for new bad eraseblocks, but attempts to use available
* eraseblocks (if any). The accepted range is 0-768. If 0 is given, the
* default kernel value of %CONFIG_MTD_UBI_BEB_LIMIT will be used.
*/
struct ubi_attach_req {
__s32 ubi_num;
__s32 mtd_num;
__s32 vid_hdr_offset;
__s8 padding[12];
__s16 max_beb_per1024;
__s8 padding[10];
};
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment