diff options
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/build.c | 26 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 19 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 4 |
3 files changed, 33 insertions, 16 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 0904eb40c95f..8b91a55ec0d2 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -95,7 +95,7 @@ static DEFINE_SPINLOCK(ubi_devices_lock); /* "Show" method for files in '/<sysfs>/class/ubi/' */ /* UBI version attribute ('/<sysfs>/class/ubi/version') */ -static ssize_t version_show(struct class *class, struct class_attribute *attr, +static ssize_t version_show(const struct class *class, const struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", UBI_VERSION); @@ -111,7 +111,6 @@ ATTRIBUTE_GROUPS(ubi_class); /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ struct class ubi_class = { .name = UBI_NAME_STR, - .owner = THIS_MODULE, .class_groups = ubi_class_groups, }; @@ -666,12 +665,6 @@ 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); - if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) > - ubi->vid_hdr_alsize)) { - ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset); - return -EINVAL; - } - 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); @@ -689,6 +682,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024) ubi->vid_hdr_aloffset; } + /* + * Memory allocation for VID header is ubi->vid_hdr_alsize + * which is described in comments in io.c. + * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds + * ubi->vid_hdr_alsize, so that all vid header operations + * won't access memory out of bounds. + */ + if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) { + ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)" + " + VID header size(%zu) > VID header aligned size(%d).", + ubi->vid_hdr_offset, ubi->vid_hdr_shift, + UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize); + return -EINVAL; + } + /* Similar for the data offset */ ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); @@ -1258,7 +1266,7 @@ static int __init ubi_init(void) mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, p->ubi_num, p->vid_hdr_offs, p->max_beb_per1024, - p->enable_fm == 0 ? true : false); + p->enable_fm == 0); mutex_unlock(&ubi_devices_mutex); if (err < 0) { pr_err("UBI error: cannot attach mtd%d\n", diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 403b79d6efd5..655ff41863e2 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -946,7 +946,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum, int offset, int len) { struct ubi_device *ubi = vol->ubi; - int pnum, opnum, err, vol_id = vol->vol_id; + int pnum, opnum, err, err2, vol_id = vol->vol_id; pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { @@ -981,10 +981,19 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum, out_put: up_read(&ubi->fm_eba_sem); - if (err && pnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - else if (!err && opnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err && pnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + pnum, err2); + } + } else if (!err && opnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + opnum, err2); + } + } return err; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 40f39e5d6dfc..26a214f016c1 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -575,7 +575,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, * @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 - * @nested: denotes whether the work_sem is already held in read mode + * @nested: denotes whether the work_sem is already held * * This function returns zero in case of success and a %-ENOMEM in case of * failure. @@ -1131,7 +1131,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, vol_id, lnum, 0, false); + err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true); if (err1) { spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e); |