Commit 060e8e3b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'upstream-3.14-rc1' of git://git.infradead.org/linux-ubifs

Pull ubifs updates from Artem Bityutskiy:

 - Improve the NOR erasure quirk - now it tries to do as little writes
   as possible, because the eraseblock may be in an "unstable" state and
   write operation sometimes causes NOR chip lock-ups.

 - Both UBI and UBIFS changes are now maintainer in one single tree,
   because the amount of changes dropped significantly.

* tag 'upstream-3.14-rc1' of git://git.infradead.org/linux-ubifs:
  UBI: avoid program operation on NOR flash after erasure interrupted
  MAINTAINERS: keep UBI and UBIFS stuff in the same tree
  UBI: fix error return code
parents 271bf66d 2c7ca5cc
...@@ -8960,7 +8960,7 @@ UNSORTED BLOCK IMAGES (UBI) ...@@ -8960,7 +8960,7 @@ UNSORTED BLOCK IMAGES (UBI)
M: Artem Bityutskiy <dedekind1@gmail.com> M: Artem Bityutskiy <dedekind1@gmail.com>
W: http://www.linux-mtd.infradead.org/ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubi-2.6.git T: git git://git.infradead.org/ubifs-2.6.git
S: Maintained S: Maintained
F: drivers/mtd/ubi/ F: drivers/mtd/ubi/
F: include/linux/mtd/ubi.h F: include/linux/mtd/ubi.h
......
...@@ -1453,8 +1453,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) ...@@ -1453,8 +1453,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
struct ubi_attach_info *scan_ai; struct ubi_attach_info *scan_ai;
scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
if (!scan_ai) if (!scan_ai) {
err = -ENOMEM;
goto out_wl; goto out_wl;
}
err = scan_all(ubi, scan_ai, 0); err = scan_all(ubi, scan_ai, 0);
if (err) { if (err) {
......
...@@ -1245,8 +1245,10 @@ static int __init ubi_init(void) ...@@ -1245,8 +1245,10 @@ static int __init ubi_init(void)
ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
sizeof(struct ubi_wl_entry), sizeof(struct ubi_wl_entry),
0, 0, NULL); 0, 0, NULL);
if (!ubi_wl_entry_slab) if (!ubi_wl_entry_slab) {
err = -ENOMEM;
goto out_dev_unreg; goto out_dev_unreg;
}
err = ubi_debugfs_init(); err = ubi_debugfs_init();
if (err) if (err)
......
...@@ -495,10 +495,12 @@ static int torture_peb(struct ubi_device *ubi, int pnum) ...@@ -495,10 +495,12 @@ static int torture_peb(struct ubi_device *ubi, int pnum)
*/ */
static int nor_erase_prepare(struct ubi_device *ubi, int pnum) static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
{ {
int err, err1; int err;
size_t written; size_t written;
loff_t addr; loff_t addr;
uint32_t data = 0; uint32_t data = 0;
struct ubi_ec_hdr ec_hdr;
/* /*
* Note, we cannot generally define VID header buffers on stack, * Note, we cannot generally define VID header buffers on stack,
* because of the way we deal with these buffers (see the header * because of the way we deal with these buffers (see the header
...@@ -509,50 +511,38 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) ...@@ -509,50 +511,38 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
struct ubi_vid_hdr vid_hdr; struct ubi_vid_hdr vid_hdr;
/* /*
* If VID or EC is valid, we have to corrupt them before erasing.
* It is important to first invalidate the EC header, and then the VID * 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 * header. Otherwise a power cut may lead to valid EC header and
* invalid VID header, in which case UBI will treat this PEB as * invalid VID header, in which case UBI will treat this PEB as
* corrupted and will try to preserve it, and print scary warnings. * corrupted and will try to preserve it, and print scary warnings.
*/ */
addr = (loff_t)pnum * ubi->peb_size; addr = (loff_t)pnum * ubi->peb_size;
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
if (!err) { if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
addr += ubi->vid_hdr_aloffset; err != UBI_IO_FF){
err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
if (!err) if(err)
return 0; goto error;
} }
/* err = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
* We failed to write to the media. This was observed with Spansion if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
* S29GL512N NOR flash. Most probably the previously eraseblock erasure err != UBI_IO_FF){
* was interrupted at a very inappropriate moment, so it became addr += ubi->vid_hdr_aloffset;
* unwritable. In this case we probably anyway have garbage in this err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
* PEB. if (err)
*/ goto error;
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
err1 == UBI_IO_FF) {
struct ubi_ec_hdr ec_hdr;
err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
err1 == UBI_IO_FF)
/*
* Both VID and EC headers are corrupted, so we can
* safely erase this PEB and not afraid that it will be
* treated as a valid PEB in case of an unclean reboot.
*/
return 0;
} }
return 0;
error:
/* /*
* The PEB contains a valid VID header, but we cannot invalidate it. * The PEB contains a valid VID or EC header, but we cannot invalidate
* Supposedly the flash media or the driver is screwed up, so return an * it. Supposedly the flash media or the driver is screwed up, so
* error. * return an error.
*/ */
ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err);
pnum, err, err1);
ubi_dump_flash(ubi, pnum, 0, ubi->peb_size); ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
return -EIO; return -EIO;
} }
......
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