Commit 104c0d6b authored by Linus Torvalds's avatar Linus Torvalds

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
parents 9dca3432 6a379f67
......@@ -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 @@ int ubiblock_remove(struct ubi_volume_info *vi)
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);
......
......@@ -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 @@ int ubi_wl_get_peb(struct ubi_device *ubi)
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) {
......
......@@ -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);
......
......@@ -682,33 +682,6 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
return JFFS2_INODE_INFO(inode);
}
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
struct jffs2_inode_info *f,
unsigned long offset,
unsigned long *priv)
{
struct inode *inode = OFNI_EDONI_2SFFJ(f);
struct page *pg;
pg = read_cache_page(inode->i_mapping, offset >> PAGE_SHIFT,
jffs2_do_readpage_unlock, inode);
if (IS_ERR(pg))
return (void *)pg;
*priv = (unsigned long)pg;
return kmap(pg);
}
void jffs2_gc_release_page(struct jffs2_sb_info *c,
unsigned char *ptr,
unsigned long *priv)
{
struct page *pg = (void *)*priv;
kunmap(pg);
put_page(pg);
}
static int jffs2_flash_setup(struct jffs2_sb_info *c) {
int ret = 0;
......
......@@ -1165,12 +1165,13 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
uint32_t start, uint32_t end)
{
struct inode *inode = OFNI_EDONI_2SFFJ(f);
struct jffs2_full_dnode *new_fn;
struct jffs2_raw_inode ri;
uint32_t alloclen, offset, orig_end, orig_start;
int ret = 0;
unsigned char *comprbuf = NULL, *writebuf;
unsigned long pg;
struct page *page;
unsigned char *pg_ptr;
memset(&ri, 0, sizeof(ri));
......@@ -1325,15 +1326,18 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
* end up here trying to GC the *same* page that jffs2_write_begin() is
* trying to write out, read_cache_page() will not deadlock. */
mutex_unlock(&f->sem);
pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
mutex_lock(&f->sem);
if (IS_ERR(pg_ptr)) {
page = read_cache_page(inode->i_mapping, start >> PAGE_SHIFT,
jffs2_do_readpage_unlock, inode);
if (IS_ERR(page)) {
pr_warn("read_cache_page() returned error: %ld\n",
PTR_ERR(pg_ptr));
return PTR_ERR(pg_ptr);
PTR_ERR(page));
mutex_lock(&f->sem);
return PTR_ERR(page);
}
pg_ptr = kmap(page);
mutex_lock(&f->sem);
offset = start;
while(offset < orig_end) {
uint32_t datalen;
......@@ -1396,6 +1400,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
}
}
jffs2_gc_release_page(c, pg_ptr, &pg);
kunmap(page);
put_page(page);
return ret;
}
......@@ -226,7 +226,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
lastend = this->ofs + this->size;
} else {
dbg_fragtree2("lookup gave no frag\n");
lastend = 0;
return -EINVAL;
}
/* See if we ran off the end of the fragtree */
......
......@@ -183,9 +183,6 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
struct jffs2_inode_info *f,
unsigned long offset,
unsigned long *priv);
void jffs2_gc_release_page(struct jffs2_sb_info *c,
unsigned char *pg,
unsigned long *priv);
void jffs2_flash_cleanup(struct jffs2_sb_info *c);
......
......@@ -527,8 +527,11 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
err = jffs2_fill_scan_buf(c, sumptr,
jeb->offset + c->sector_size - sumlen,
sumlen - buf_len);
if (err)
if (err) {
if (sumlen > buf_size)
kfree(sumptr);
return err;
}
}
}
......
......@@ -479,8 +479,10 @@ int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node,
return -ENOMEM;
err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac);
if (err)
if (err) {
kfree(hmac);
return err;
}
err = crypto_memneq(hmac, node + ofs_hmac, hmac_len);
......
......@@ -2817,7 +2817,6 @@ void dbg_debugfs_init_fs(struct ubifs_info *c)
c->vi.ubi_num, c->vi.vol_id);
if (n == UBIFS_DFS_DIR_LEN) {
/* The array size is too small */
fname = UBIFS_DFS_DIR_NAME;
return;
}
......
......@@ -2267,8 +2267,10 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags,
}
} else {
err = ubifs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
if (err)
if (err) {
kfree(c);
goto out_deact;
}
/* We do not support atime */
sb->s_flags |= SB_ACTIVE;
if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT))
......
......@@ -284,6 +284,7 @@ static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr,
err = ubifs_node_check_hash(c, idx, zzbr->hash);
if (err) {
ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs);
kfree(idx);
return err;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment