summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-21 11:10:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-21 11:10:16 -0700
commit104c0d6bc43e10ba84931c45b67e2c76c9c67f68 (patch)
treeea80d62d9e5cc112b89928435be6be94673c0f39 /drivers/mtd
parent9dca3432ee063b70a4cfb3f0857d0aeef7b84fa8 (diff)
parent6a379f67454a3c740671ed6c7793b76ffecef50b (diff)
Merge tag 'upstream-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI, UBIFS and JFFS2 updates from Richard Weinberger: "UBI: - Be less stupid when placing a fastmap anchor - Try harder to get an empty PEB in case of contention - Make ubiblock to warn if image is not a multiple of 512 UBIFS: - Various fixes in error paths JFFS2: - Various fixes in error paths" * tag 'upstream-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: jffs2: Fix memory leak in jffs2_scan_eraseblock() error path jffs2: Remove jffs2_gc_fetch_page and jffs2_gc_release_page jffs2: Fix possible null-pointer dereferences in jffs2_add_frag_to_fragtree() ubi: block: Warn if volume size is not multiple of 512 ubifs: Fix memory leak bug in alloc_ubifs_info() error path ubifs: Fix memory leak in __ubifs_node_verify_hmac error path ubifs: Fix memory leak in read_znode() error path ubi: ubi_wl_get_peb: Increase the number of attempts while getting PEB ubi: Don't do anchor move within fastmap area ubifs: Remove redundant assignment to pointer fname
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/block.c43
-rw-r--r--drivers/mtd/ubi/fastmap-wl.c6
-rw-r--r--drivers/mtd/ubi/wl.c6
3 files changed, 44 insertions, 11 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 6025398955a2..e1a2ae21dfd3 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -345,15 +345,36 @@ static const struct blk_mq_ops ubiblock_mq_ops = {
.init_request = ubiblock_init_request,
};
+static int calc_disk_capacity(struct ubi_volume_info *vi, u64 *disk_capacity)
+{
+ u64 size = vi->used_bytes >> 9;
+
+ if (vi->used_bytes % 512) {
+ pr_warn("UBI: block: volume size is not a multiple of 512, "
+ "last %llu bytes are ignored!\n",
+ vi->used_bytes - (size << 9));
+ }
+
+ if ((sector_t)size != size)
+ return -EFBIG;
+
+ *disk_capacity = size;
+
+ return 0;
+}
+
int ubiblock_create(struct ubi_volume_info *vi)
{
struct ubiblock *dev;
struct gendisk *gd;
- u64 disk_capacity = vi->used_bytes >> 9;
+ u64 disk_capacity;
int ret;
- if ((sector_t)disk_capacity != disk_capacity)
- return -EFBIG;
+ ret = calc_disk_capacity(vi, &disk_capacity);
+ if (ret) {
+ return ret;
+ }
+
/* Check that the volume isn't already handled */
mutex_lock(&devices_mutex);
if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
@@ -507,7 +528,8 @@ out_unlock:
static int ubiblock_resize(struct ubi_volume_info *vi)
{
struct ubiblock *dev;
- u64 disk_capacity = vi->used_bytes >> 9;
+ u64 disk_capacity;
+ int ret;
/*
* Need to lock the device list until we stop using the device,
@@ -520,11 +542,16 @@ static int ubiblock_resize(struct ubi_volume_info *vi)
mutex_unlock(&devices_mutex);
return -ENODEV;
}
- if ((sector_t)disk_capacity != disk_capacity) {
+
+ ret = calc_disk_capacity(vi, &disk_capacity);
+ if (ret) {
mutex_unlock(&devices_mutex);
- dev_warn(disk_to_dev(dev->gd), "the volume is too big (%d LEBs), cannot resize",
- vi->size);
- return -EFBIG;
+ if (ret == -EFBIG) {
+ dev_warn(disk_to_dev(dev->gd),
+ "the volume is too big (%d LEBs), cannot resize",
+ vi->size);
+ }
+ return ret;
}
mutex_lock(&dev->dev_mutex);
diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c
index d9e2e3a6e105..c44c8470247e 100644
--- a/drivers/mtd/ubi/fastmap-wl.c
+++ b/drivers/mtd/ubi/fastmap-wl.c
@@ -196,7 +196,7 @@ static int produce_free_peb(struct ubi_device *ubi)
*/
int ubi_wl_get_peb(struct ubi_device *ubi)
{
- int ret, retried = 0;
+ int ret, attempts = 0;
struct ubi_fm_pool *pool = &ubi->fm_pool;
struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
@@ -221,12 +221,12 @@ again:
if (pool->used == pool->size) {
spin_unlock(&ubi->wl_lock);
- if (retried) {
+ attempts++;
+ if (attempts == 10) {
ubi_err(ubi, "Unable to get a free PEB from user WL pool");
ret = -ENOSPC;
goto out;
}
- retried = 1;
up_read(&ubi->fm_eba_sem);
ret = produce_free_peb(ubi);
if (ret < 0) {
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 949700a9bb4b..3fcdefe2714d 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -710,6 +710,12 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
if (!e2)
goto out_cancel;
+ /*
+ * Anchor move within the anchor area is useless.
+ */
+ if (e2->pnum < UBI_FM_MAX_START)
+ goto out_cancel;
+
self_check_in_wl_tree(ubi, e1, &ubi->used);
rb_erase(&e1->u.rb, &ubi->used);
dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);