This pull request contains the following changes for UBI, UBIFS and JFFS2:
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 -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAl2FzukWHHJpY2hhcmRA c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wZb+EADL6lWqlqIpj+Z6Yc7s3kFkQ4ZM X1bvfp38WAbVYJ9/X3AKw0PqGXZ9OSM6iLq00s9qIx0WwQtLUT43Q8aKOXKqcy3f i8ZTLssRJS6KgcPqSnL0fdD00XZc6cGm+3+6U31KLmW1fWG3mRAt6Vgg1tiEPiUY dcsRtePna9RWtRKZZssYgqLGqChU26o1SPIsj5rDc2YB3s6h2dPe+S8z2Qf4K2TD UmsCVtVerPHL7b9hS9uq6RxVWGxxgBV83rPc4kag3rdu8oMlMgKWKKvwaoqYiU3L KAausS63ZnNltKyuC/hxm9x6RnAXr7t8efXzgdx7JcePYTSApoTJhpsKU/KiTdmg dkAsx46An+LXctUBQy4BFoWdChMIKQvW5UkINp/4hbXqgEroiiwiIUbzr6vU6ViM Z+gLW0r6V/WiN0L9gj5goO/2lulp6e05s+3o214N54Rn/X9bzgWE04b0beLI7LZ/ lED+cFSXs+PjfAQaX+UIf6fuzkudH/f+Y5sGsuwDzN6gwaJcSdgWi+WsMXbX50FU B4vYTQimTPg2RLEvPvu8/squ7paC0lDOjxwwhmX/s+aBNppSyTU1DelAkeEy6JOT BUfIJMQ+FRnDm9PuByS0xlqgNRk+p1q/zMFCP5CIh8yAuJuG4UytnnlojJxgg/bs 19EsCUduqgKxJMf6cQ== =ptT1 -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
104c0d6bc4
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче