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

Commit e3d18658 authored by David Woodhouse's avatar David Woodhouse
Browse files
parents a2e1b833 cc5f4f28
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
	if (err)
		goto out_free;

	mutex_init(&ubi->buf_mutex);
	ubi->peb_buf1 = vmalloc(ubi->peb_size);
	if (!ubi->peb_buf1)
		goto out_free;

	ubi->peb_buf2 = vmalloc(ubi->peb_size);
	if (!ubi->peb_buf2)
		 goto out_free;

#ifdef CONFIG_MTD_UBI_DEBUG
	mutex_init(&ubi->dbg_buf_mutex);
	ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
	if (!ubi->dbg_peb_buf)
		 goto out_free;
#endif

	err = attach_by_scanning(ubi);
	if (err) {
		dbg_err("failed to attach by scanning, error %d", err);
@@ -630,6 +646,11 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset,
	ubi_wl_close(ubi);
	vfree(ubi->vtbl);
out_free:
	vfree(ubi->peb_buf1);
	vfree(ubi->peb_buf2);
#ifdef CONFIG_MTD_UBI_DEBUG
	vfree(ubi->dbg_peb_buf);
#endif
	kfree(ubi);
out_mtd:
	put_mtd_device(mtd);
@@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi)
	ubi_wl_close(ubi);
	vfree(ubi->vtbl);
	put_mtd_device(ubi->mtd);
	vfree(ubi->peb_buf1);
	vfree(ubi->peb_buf2);
#ifdef CONFIG_MTD_UBI_DEBUG
	vfree(ubi->dbg_peb_buf);
#endif
	kfree(ubi_devices[ubi_num]);
	ubi_devices[ubi_num] = NULL;
	ubi_devices_cnt -= 1;
+2 −35
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)
	dbg_msg("data_offset    %d",    be32_to_cpu(ec_hdr->data_offset));
	dbg_msg("hdr_crc        %#08x", be32_to_cpu(ec_hdr->hdr_crc));
	dbg_msg("erase counter header hexdump:");
	ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
		       ec_hdr, UBI_EC_HDR_SIZE, 1);
}

/**
@@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
	dbg_msg("the 1st 16 characters of the name: %s", nm);
}

#define BYTES_PER_LINE 32

/**
 * ubi_dbg_hexdump - dump a buffer.
 * @ptr: the buffer to dump
 * @size: buffer size which must be multiple of 4 bytes
 */
void ubi_dbg_hexdump(const void *ptr, int size)
{
	int i, k = 0, rows, columns;
	const uint8_t *p = ptr;

	size = ALIGN(size, 4);
	rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE;
	for (i = 0; i < rows; i++) {
		int j;

		cond_resched();
		columns = min(size - k, BYTES_PER_LINE) / 4;
		if (columns == 0)
			break;
		printk(KERN_DEBUG "%5d:  ", i * BYTES_PER_LINE);
		for (j = 0; j < columns; j++) {
			int n, N;

			N = size - k > 4 ? 4 : size - k;
			for (n = 0; n < N; n++)
				printk("%02x", p[k++]);
			printk(" ");
		}
		printk("\n");
	}
}

#endif /* CONFIG_MTD_UBI_DEBUG_MSG */
+0 −2
Original line number Diff line number Diff line
@@ -59,7 +59,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_hexdump(const void *buf, int size);

#else

@@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size);
#define ubi_dbg_dump_sv(sv)              ({})
#define ubi_dbg_dump_seb(seb, type)      ({})
#define ubi_dbg_dump_mkvol_req(req)      ({})
#define ubi_dbg_hexdump(buf, size)       ({})

#endif /* CONFIG_MTD_UBI_DEBUG_MSG */

+60 −71
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@
#include <linux/err.h>
#include "ubi.h"

/* Number of physical eraseblocks reserved for atomic LEB change operation */
#define EBA_RESERVED_PEBS 1

/**
 * struct ltree_entry - an entry in the lock tree.
 * @rb: links RB-tree nodes
@@ -157,7 +160,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id,
{
	struct ltree_entry *le, *le1, *le_free;

	le = kmem_cache_alloc(ltree_slab, GFP_KERNEL);
	le = kmem_cache_alloc(ltree_slab, GFP_NOFS);
	if (!le)
		return ERR_PTR(-ENOMEM);

@@ -397,7 +400,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf,

retry:
	if (check) {
		vid_hdr = ubi_zalloc_vid_hdr(ubi);
		vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
		if (!vid_hdr) {
			err = -ENOMEM;
			goto out_unlock;
@@ -495,16 +498,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
	int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
	struct ubi_volume *vol = ubi->volumes[idx];
	struct ubi_vid_hdr *vid_hdr;
	unsigned char *new_buf;

	vid_hdr = ubi_zalloc_vid_hdr(ubi);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr) {
		return -ENOMEM;
	}

	mutex_lock(&ubi->buf_mutex);

retry:
	new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN);
	if (new_pnum < 0) {
		mutex_unlock(&ubi->buf_mutex);
		ubi_free_vid_hdr(ubi, vid_hdr);
		return new_pnum;
	}
@@ -524,31 +529,22 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
		goto write_error;

	data_size = offset + len;
	new_buf = vmalloc(data_size);
	if (!new_buf) {
		err = -ENOMEM;
		goto out_put;
	}
	memset(new_buf + offset, 0xFF, len);
	memset(ubi->peb_buf1 + offset, 0xFF, len);

	/* Read everything before the area where the write failure happened */
	if (offset > 0) {
		err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset);
		if (err && err != UBI_IO_BITFLIPS) {
			vfree(new_buf);
		err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset);
		if (err && err != UBI_IO_BITFLIPS)
			goto out_put;
	}
	}

	memcpy(new_buf + offset, buf, len);
	memcpy(ubi->peb_buf1 + offset, buf, len);

	err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size);
	if (err) {
		vfree(new_buf);
	err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size);
	if (err)
		goto write_error;
	}

	vfree(new_buf);
	mutex_unlock(&ubi->buf_mutex);
	ubi_free_vid_hdr(ubi, vid_hdr);

	vol->eba_tbl[lnum] = new_pnum;
@@ -558,6 +554,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
	return 0;

out_put:
	mutex_unlock(&ubi->buf_mutex);
	ubi_wl_put_peb(ubi, new_pnum, 1);
	ubi_free_vid_hdr(ubi, vid_hdr);
	return err;
@@ -570,6 +567,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
	ubi_warn("failed to write to PEB %d", new_pnum);
	ubi_wl_put_peb(ubi, new_pnum, 1);
	if (++tries > UBI_IO_RETRIES) {
		mutex_unlock(&ubi->buf_mutex);
		ubi_free_vid_hdr(ubi, vid_hdr);
		return err;
	}
@@ -627,7 +625,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum,
	 * The logical eraseblock is not mapped. We have to get a free physical
	 * eraseblock and write the volume identifier header there first.
	 */
	vid_hdr = ubi_zalloc_vid_hdr(ubi);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr) {
		leb_write_unlock(ubi, vol_id, lnum);
		return -ENOMEM;
@@ -738,7 +736,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
	else
		ubi_assert(len % ubi->min_io_size == 0);

	vid_hdr = ubi_zalloc_vid_hdr(ubi);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr)
		return -ENOMEM;

@@ -832,6 +830,9 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum,
 * data, which has to be aligned. This function guarantees that in case of an
 * unclean reboot the old contents is preserved. Returns zero in case of
 * success and a negative error code in case of failure.
 *
 * UBI reserves one LEB for the "atomic LEB change" operation, so only one
 * 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, int vol_id, int lnum,
			      const void *buf, int len, int dtype)
@@ -844,15 +845,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
	if (ubi->ro_mode)
		return -EROFS;

	vid_hdr = ubi_zalloc_vid_hdr(ubi);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr)
		return -ENOMEM;

	mutex_lock(&ubi->alc_mutex);
	err = leb_write_lock(ubi, vol_id, lnum);
	if (err) {
		ubi_free_vid_hdr(ubi, vid_hdr);
		return err;
	}
	if (err)
		goto out_mutex;

	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
	vid_hdr->vol_id = cpu_to_be32(vol_id);
@@ -869,9 +869,8 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
retry:
	pnum = ubi_wl_get_peb(ubi, dtype);
	if (pnum < 0) {
		ubi_free_vid_hdr(ubi, vid_hdr);
		leb_write_unlock(ubi, vol_id, lnum);
		return pnum;
		err = pnum;
		goto out_leb_unlock;
	}

	dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d",
@@ -893,17 +892,18 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,

	if (vol->eba_tbl[lnum] >= 0) {
		err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1);
		if (err) {
			ubi_free_vid_hdr(ubi, vid_hdr);
			leb_write_unlock(ubi, vol_id, lnum);
			return err;
		}
		if (err)
			goto out_leb_unlock;
	}

	vol->eba_tbl[lnum] = pnum;

out_leb_unlock:
	leb_write_unlock(ubi, vol_id, lnum);
out_mutex:
	mutex_unlock(&ubi->alc_mutex);
	ubi_free_vid_hdr(ubi, vid_hdr);
	return 0;
	return err;

write_error:
	if (err != -EIO || !ubi->bad_allowed) {
@@ -913,17 +913,13 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum,
		 * mode just in case.
		 */
		ubi_ro_mode(ubi);
		leb_write_unlock(ubi, vol_id, lnum);
		ubi_free_vid_hdr(ubi, vid_hdr);
		return err;
		goto out_leb_unlock;
	}

	err = ubi_wl_put_peb(ubi, pnum, 1);
	if (err || ++tries > UBI_IO_RETRIES) {
		ubi_ro_mode(ubi);
		leb_write_unlock(ubi, vol_id, lnum);
		ubi_free_vid_hdr(ubi, vid_hdr);
		return err;
		goto out_leb_unlock;
	}

	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
@@ -965,7 +961,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
	int err, vol_id, lnum, data_size, aldata_size, pnum, idx;
	struct ubi_volume *vol;
	uint32_t crc;
	void *buf, *buf1 = NULL;

	vol_id = be32_to_cpu(vid_hdr->vol_id);
	lnum = be32_to_cpu(vid_hdr->lnum);
@@ -979,19 +974,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
		data_size = aldata_size =
			    ubi->leb_size - be32_to_cpu(vid_hdr->data_pad);

	buf = vmalloc(aldata_size);
	if (!buf)
		return -ENOMEM;

	/*
	 * We do not want anybody to write to this logical eraseblock while we
	 * are moving it, so we lock it.
	 */
	err = leb_write_lock(ubi, vol_id, lnum);
	if (err) {
		vfree(buf);
	if (err)
		return err;
	}

	mutex_lock(&ubi->buf_mutex);

	/*
	 * But the logical eraseblock might have been put by this time.
@@ -1023,7 +1014,7 @@ 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 */

	dbg_eba("read %d bytes of data", aldata_size);
	err = ubi_io_read_data(ubi, buf, from, 0, aldata_size);
	err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size);
	if (err && err != UBI_IO_BITFLIPS) {
		ubi_warn("error %d while reading data from PEB %d",
			 err, from);
@@ -1042,10 +1033,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, buf, data_size);
			ubi_calc_data_len(ubi, ubi->peb_buf1, data_size);

	cond_resched();
	crc = crc32(UBI_CRC32_INIT, buf, data_size);
	crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size);
	cond_resched();

	/*
@@ -1076,23 +1067,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
	}

	if (data_size > 0) {
		err = ubi_io_write_data(ubi, buf, to, 0, aldata_size);
		err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size);
		if (err)
			goto out_unlock;

		cond_resched();

		/*
		 * We've written the data and are going to read it back to make
		 * sure it was written correctly.
		 */
		buf1 = vmalloc(aldata_size);
		if (!buf1) {
			err = -ENOMEM;
			goto out_unlock;
		}

		cond_resched();

		err = ubi_io_read_data(ubi, buf1, to, 0, aldata_size);
		err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size);
		if (err) {
			if (err != UBI_IO_BITFLIPS)
				ubi_warn("cannot read data back from PEB %d",
@@ -1102,7 +1088,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,

		cond_resched();

		if (memcmp(buf, buf1, aldata_size)) {
		if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) {
			ubi_warn("read data back from PEB %d - it is different",
				 to);
			goto out_unlock;
@@ -1112,16 +1098,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
	ubi_assert(vol->eba_tbl[lnum] == from);
	vol->eba_tbl[lnum] = to;

	leb_write_unlock(ubi, vol_id, lnum);
	vfree(buf);
	vfree(buf1);

	return 0;

out_unlock:
	mutex_unlock(&ubi->buf_mutex);
	leb_write_unlock(ubi, vol_id, lnum);
	vfree(buf);
	vfree(buf1);
	return err;
}

@@ -1144,6 +1123,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
	dbg_eba("initialize EBA unit");

	spin_lock_init(&ubi->ltree_lock);
	mutex_init(&ubi->alc_mutex);
	ubi->ltree = RB_ROOT;

	if (ubi_devices_cnt == 0) {
@@ -1205,6 +1185,15 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
		ubi->rsvd_pebs  += ubi->beb_rsvd_pebs;
	}

	if (ubi->avail_pebs < EBA_RESERVED_PEBS) {
		ubi_err("no enough physical eraseblocks (%d, need %d)",
			ubi->avail_pebs, EBA_RESERVED_PEBS);
		err = -ENOSPC;
		goto out_free;
	}
	ubi->avail_pebs -= EBA_RESERVED_PEBS;
	ubi->rsvd_pebs += EBA_RESERVED_PEBS;

	dbg_eba("EBA unit is initialized");
	return 0;

+35 −40
Original line number Diff line number Diff line
@@ -98,8 +98,8 @@ 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);
static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
				 int offset, int len);
static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
				 int len);
#else
#define paranoid_check_not_bad(ubi, pnum) 0
#define paranoid_check_peb_ec_hdr(ubi, pnum)  0
@@ -202,8 +202,8 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
 * Note, in case of an error, it is possible that something was still written
 * to the flash media, but may be some garbage.
 */
int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum,
		 int offset, int len)
int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
		 int len)
{
	int err;
	size_t written;
@@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei)
 * zero in case of success and a negative error code in case of failure. If
 * %-EIO is returned, the physical eraseblock most probably went bad.
 */
static int do_sync_erase(const struct ubi_device *ubi, int pnum)
static int do_sync_erase(struct ubi_device *ubi, int pnum)
{
	int err, retries = 0;
	struct erase_info ei;
@@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
 * test, a positive number of erase operations done if the test was
 * successfully passed, and other negative error codes in case of other errors.
 */
static int torture_peb(const struct ubi_device *ubi, int pnum)
static int torture_peb(struct ubi_device *ubi, int pnum)
{
	void *buf;
	int err, i, patt_count;

	buf = vmalloc(ubi->peb_size);
	if (!buf)
		return -ENOMEM;

	patt_count = ARRAY_SIZE(patterns);
	ubi_assert(patt_count > 0);

	mutex_lock(&ubi->buf_mutex);
	for (i = 0; i < patt_count; i++) {
		err = do_sync_erase(ubi, pnum);
		if (err)
			goto out;

		/* Make sure the PEB contains only 0xFF bytes */
		err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size);
		err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
		if (err)
			goto out;

		err = check_pattern(buf, 0xFF, ubi->peb_size);
		err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
		if (err == 0) {
			ubi_err("erased PEB %d, but a non-0xFF byte found",
				pnum);
@@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
		}

		/* Write a pattern and check it */
		memset(buf, patterns[i], ubi->peb_size);
		err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size);
		memset(ubi->peb_buf1, patterns[i], ubi->peb_size);
		err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
		if (err)
			goto out;

		memset(buf, ~patterns[i], ubi->peb_size);
		err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size);
		memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size);
		err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
		if (err)
			goto out;

		err = check_pattern(buf, patterns[i], ubi->peb_size);
		err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size);
		if (err == 0) {
			ubi_err("pattern %x checking failed for PEB %d",
				patterns[i], pnum);
@@ -430,14 +426,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
	err = patt_count;

out:
	if (err == UBI_IO_BITFLIPS || err == -EBADMSG)
	mutex_unlock(&ubi->buf_mutex);
	if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
		/*
		 * If a bit-flip or data integrity error was detected, the test
		 * has not passed because it happened on a freshly erased
		 * physical eraseblock which means something is wrong with it.
		 */
		ubi_err("read problems on freshly erased PEB %d, must be bad",
			pnum);
		err = -EIO;
	vfree(buf);
	}
	return err;
}

@@ -457,7 +456,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
 * codes in case of other errors. Note, %-EIO means that the physical
 * eraseblock is bad.
 */
int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture)
int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
{
	int err, ret = 0;

@@ -614,7 +613,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi,
 * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty;
 * o a negative error code in case of failure.
 */
int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
		       struct ubi_ec_hdr *ec_hdr, int verbose)
{
	int err, read_err = 0;
@@ -720,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
 * case of failure. If %-EIO is returned, the physical eraseblock most probably
 * went bad.
 */
int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum,
int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
			struct ubi_ec_hdr *ec_hdr)
{
	int err;
@@ -886,7 +885,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi,
 *   header there);
 * o a negative error code in case of failure.
 */
int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
			struct ubi_vid_hdr *vid_hdr, int verbose)
{
	int err, read_err = 0;
@@ -993,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
 * case of failure. If %-EIO is returned, the physical eraseblock probably went
 * bad.
 */
int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum,
int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
			 struct ubi_vid_hdr *vid_hdr)
{
	int err;
@@ -1096,7 +1095,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
	uint32_t crc, hdr_crc;
	struct ubi_ec_hdr *ec_hdr;

	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
	if (!ec_hdr)
		return -ENOMEM;

@@ -1176,7 +1175,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
	struct ubi_vid_hdr *vid_hdr;
	void *p;

	vid_hdr = ubi_zalloc_vid_hdr(ubi);
	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
	if (!vid_hdr)
		return -ENOMEM;

@@ -1216,44 +1215,40 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
 * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
 * code if an error occurred.
 */
static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
				 int offset, int len)
static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
				 int len)
{
	size_t read;
	int err;
	void *buf;
	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;

	buf = vmalloc(len);
	if (!buf)
		return -ENOMEM;
	memset(buf, 0, len);

	err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
	mutex_lock(&ubi->dbg_buf_mutex);
	err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_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 error;
	}

	err = check_pattern(buf, 0xFF, len);
	err = check_pattern(ubi->dbg_peb_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);
		goto fail;
	}
	mutex_unlock(&ubi->dbg_buf_mutex);

	vfree(buf);
	return 0;

fail:
	ubi_err("paranoid check failed for PEB %d", pnum);
	dbg_msg("hex dump of the %d-%d region", offset, offset + len);
	ubi_dbg_hexdump(buf, len);
	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
		       ubi->dbg_peb_buf, len, 1);
	err = 1;
error:
	ubi_dbg_dump_stack();
	vfree(buf);
	mutex_unlock(&ubi->dbg_buf_mutex);
	return err;
}

Loading