diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 11:10:16 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 11:10:16 -0700 |
commit | 104c0d6bc43e10ba84931c45b67e2c76c9c67f68 (patch) | |
tree | ea80d62d9e5cc112b89928435be6be94673c0f39 /drivers/mtd | |
parent | 9dca3432ee063b70a4cfb3f0857d0aeef7b84fa8 (diff) | |
parent | 6a379f67454a3c740671ed6c7793b76ffecef50b (diff) | |
download | linux-104c0d6bc43e10ba84931c45b67e2c76c9c67f68.tar.gz linux-104c0d6bc43e10ba84931c45b67e2c76c9c67f68.tar.bz2 linux-104c0d6bc43e10ba84931c45b67e2c76c9c67f68.zip |
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.c | 43 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap-wl.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 6 |
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); |