Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8960,7 +8960,7 @@ UNSORTED BLOCK IMAGES (UBI)
M:	Artem Bityutskiy <dedekind1@gmail.com>
W:	http://www.linux-mtd.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
F:	drivers/mtd/ubi/
F:	include/linux/mtd/ubi.h
+3 −1
Original line number Diff line number Diff line
@@ -1453,8 +1453,10 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
		struct ubi_attach_info *scan_ai;

		scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
		if (!scan_ai)
		if (!scan_ai) {
			err = -ENOMEM;
			goto out_wl;
		}

		err = scan_all(ubi, scan_ai, 0);
		if (err) {
+3 −1
Original line number Diff line number Diff line
@@ -1245,8 +1245,10 @@ static int __init ubi_init(void)
	ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
					      sizeof(struct ubi_wl_entry),
					      0, 0, NULL);
	if (!ubi_wl_entry_slab)
	if (!ubi_wl_entry_slab) {
		err = -ENOMEM;
		goto out_dev_unreg;
	}

	err = ubi_debugfs_init();
	if (err)
+22 −32
Original line number Diff line number Diff line
@@ -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)
{
	int err, err1;
	int err;
	size_t written;
	loff_t addr;
	uint32_t data = 0;
	struct ubi_ec_hdr ec_hdr;

	/*
	 * Note, we cannot generally define VID header buffers on stack,
	 * 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)
	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
	 * 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.
	 */
	addr = (loff_t)pnum * ubi->peb_size;
	err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
	if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
	    err != UBI_IO_FF){
		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
	if (!err) {
		if(err)
			goto error;
	}

	err = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
	if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
	    err != UBI_IO_FF){
		addr += ubi->vid_hdr_aloffset;
		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
		if (!err)
			return 0;
		if (err)
			goto error;
	}

	/*
	 * We failed to write to the media. This was observed with Spansion
	 * S29GL512N NOR flash. Most probably the previously eraseblock erasure
	 * was interrupted at a very inappropriate moment, so it became
	 * unwritable. In this case we probably anyway have garbage in this
	 * PEB.
	 */
	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;
	}

error:
	/*
	 * The PEB contains a valid VID header, but we cannot invalidate it.
	 * Supposedly the flash media or the driver is screwed up, so return an
	 * error.
	 * The PEB contains a valid VID or EC header, but we cannot invalidate
	 * it. Supposedly the flash media or the driver is screwed up, so
	 * return an error.
	 */
	ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
		pnum, err, err1);
	ubi_err("cannot invalidate PEB %d, write returned %d", pnum, err);
	ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
	return -EIO;
}