diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 14:10:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-21 14:10:16 -0400 |
commit | 104c0d6bc43e10ba84931c45b67e2c76c9c67f68 (patch) | |
tree | ea80d62d9e5cc112b89928435be6be94673c0f39 | |
parent | 9dca3432ee063b70a4cfb3f0857d0aeef7b84fa8 (diff) | |
parent | 6a379f67454a3c740671ed6c7793b76ffecef50b (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
-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 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 27 | ||||
-rw-r--r-- | fs/jffs2/gc.c | 21 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 2 | ||||
-rw-r--r-- | fs/jffs2/os-linux.h | 3 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 5 | ||||
-rw-r--r-- | fs/ubifs/auth.c | 4 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 1 | ||||
-rw-r--r-- | fs/ubifs/super.c | 4 | ||||
-rw-r--r-- | fs/ubifs/tnc_misc.c | 1 |
12 files changed, 69 insertions, 54 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 = { | |||
345 | .init_request = ubiblock_init_request, | 345 | .init_request = ubiblock_init_request, |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static int calc_disk_capacity(struct ubi_volume_info *vi, u64 *disk_capacity) | ||
349 | { | ||
350 | u64 size = vi->used_bytes >> 9; | ||
351 | |||
352 | if (vi->used_bytes % 512) { | ||
353 | pr_warn("UBI: block: volume size is not a multiple of 512, " | ||
354 | "last %llu bytes are ignored!\n", | ||
355 | vi->used_bytes - (size << 9)); | ||
356 | } | ||
357 | |||
358 | if ((sector_t)size != size) | ||
359 | return -EFBIG; | ||
360 | |||
361 | *disk_capacity = size; | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
348 | int ubiblock_create(struct ubi_volume_info *vi) | 366 | int ubiblock_create(struct ubi_volume_info *vi) |
349 | { | 367 | { |
350 | struct ubiblock *dev; | 368 | struct ubiblock *dev; |
351 | struct gendisk *gd; | 369 | struct gendisk *gd; |
352 | u64 disk_capacity = vi->used_bytes >> 9; | 370 | u64 disk_capacity; |
353 | int ret; | 371 | int ret; |
354 | 372 | ||
355 | if ((sector_t)disk_capacity != disk_capacity) | 373 | ret = calc_disk_capacity(vi, &disk_capacity); |
356 | return -EFBIG; | 374 | if (ret) { |
375 | return ret; | ||
376 | } | ||
377 | |||
357 | /* Check that the volume isn't already handled */ | 378 | /* Check that the volume isn't already handled */ |
358 | mutex_lock(&devices_mutex); | 379 | mutex_lock(&devices_mutex); |
359 | if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { | 380 | if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { |
@@ -507,7 +528,8 @@ out_unlock: | |||
507 | static int ubiblock_resize(struct ubi_volume_info *vi) | 528 | static int ubiblock_resize(struct ubi_volume_info *vi) |
508 | { | 529 | { |
509 | struct ubiblock *dev; | 530 | struct ubiblock *dev; |
510 | u64 disk_capacity = vi->used_bytes >> 9; | 531 | u64 disk_capacity; |
532 | int ret; | ||
511 | 533 | ||
512 | /* | 534 | /* |
513 | * Need to lock the device list until we stop using the device, | 535 | * 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) | |||
520 | mutex_unlock(&devices_mutex); | 542 | mutex_unlock(&devices_mutex); |
521 | return -ENODEV; | 543 | return -ENODEV; |
522 | } | 544 | } |
523 | if ((sector_t)disk_capacity != disk_capacity) { | 545 | |
546 | ret = calc_disk_capacity(vi, &disk_capacity); | ||
547 | if (ret) { | ||
524 | mutex_unlock(&devices_mutex); | 548 | mutex_unlock(&devices_mutex); |
525 | dev_warn(disk_to_dev(dev->gd), "the volume is too big (%d LEBs), cannot resize", | 549 | if (ret == -EFBIG) { |
526 | vi->size); | 550 | dev_warn(disk_to_dev(dev->gd), |
527 | return -EFBIG; | 551 | "the volume is too big (%d LEBs), cannot resize", |
552 | vi->size); | ||
553 | } | ||
554 | return ret; | ||
528 | } | 555 | } |
529 | 556 | ||
530 | mutex_lock(&dev->dev_mutex); | 557 | 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) | |||
196 | */ | 196 | */ |
197 | int ubi_wl_get_peb(struct ubi_device *ubi) | 197 | int ubi_wl_get_peb(struct ubi_device *ubi) |
198 | { | 198 | { |
199 | int ret, retried = 0; | 199 | int ret, attempts = 0; |
200 | struct ubi_fm_pool *pool = &ubi->fm_pool; | 200 | struct ubi_fm_pool *pool = &ubi->fm_pool; |
201 | struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; | 201 | struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool; |
202 | 202 | ||
@@ -221,12 +221,12 @@ again: | |||
221 | 221 | ||
222 | if (pool->used == pool->size) { | 222 | if (pool->used == pool->size) { |
223 | spin_unlock(&ubi->wl_lock); | 223 | spin_unlock(&ubi->wl_lock); |
224 | if (retried) { | 224 | attempts++; |
225 | if (attempts == 10) { | ||
225 | ubi_err(ubi, "Unable to get a free PEB from user WL pool"); | 226 | ubi_err(ubi, "Unable to get a free PEB from user WL pool"); |
226 | ret = -ENOSPC; | 227 | ret = -ENOSPC; |
227 | goto out; | 228 | goto out; |
228 | } | 229 | } |
229 | retried = 1; | ||
230 | up_read(&ubi->fm_eba_sem); | 230 | up_read(&ubi->fm_eba_sem); |
231 | ret = produce_free_peb(ubi); | 231 | ret = produce_free_peb(ubi); |
232 | if (ret < 0) { | 232 | 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, | |||
710 | if (!e2) | 710 | if (!e2) |
711 | goto out_cancel; | 711 | goto out_cancel; |
712 | 712 | ||
713 | /* | ||
714 | * Anchor move within the anchor area is useless. | ||
715 | */ | ||
716 | if (e2->pnum < UBI_FM_MAX_START) | ||
717 | goto out_cancel; | ||
718 | |||
713 | self_check_in_wl_tree(ubi, e1, &ubi->used); | 719 | self_check_in_wl_tree(ubi, e1, &ubi->used); |
714 | rb_erase(&e1->u.rb, &ubi->used); | 720 | rb_erase(&e1->u.rb, &ubi->used); |
715 | dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum); | 721 | dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum); |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 05fe6cf5f1ac..ab8cdd9e9325 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -682,33 +682,6 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, | |||
682 | return JFFS2_INODE_INFO(inode); | 682 | return JFFS2_INODE_INFO(inode); |
683 | } | 683 | } |
684 | 684 | ||
685 | unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, | ||
686 | struct jffs2_inode_info *f, | ||
687 | unsigned long offset, | ||
688 | unsigned long *priv) | ||
689 | { | ||
690 | struct inode *inode = OFNI_EDONI_2SFFJ(f); | ||
691 | struct page *pg; | ||
692 | |||
693 | pg = read_cache_page(inode->i_mapping, offset >> PAGE_SHIFT, | ||
694 | jffs2_do_readpage_unlock, inode); | ||
695 | if (IS_ERR(pg)) | ||
696 | return (void *)pg; | ||
697 | |||
698 | *priv = (unsigned long)pg; | ||
699 | return kmap(pg); | ||
700 | } | ||
701 | |||
702 | void jffs2_gc_release_page(struct jffs2_sb_info *c, | ||
703 | unsigned char *ptr, | ||
704 | unsigned long *priv) | ||
705 | { | ||
706 | struct page *pg = (void *)*priv; | ||
707 | |||
708 | kunmap(pg); | ||
709 | put_page(pg); | ||
710 | } | ||
711 | |||
712 | static int jffs2_flash_setup(struct jffs2_sb_info *c) { | 685 | static int jffs2_flash_setup(struct jffs2_sb_info *c) { |
713 | int ret = 0; | 686 | int ret = 0; |
714 | 687 | ||
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 9ed0f26cf023..373b3b7c9f44 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c | |||
@@ -1165,12 +1165,13 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1165 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, | 1165 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, |
1166 | uint32_t start, uint32_t end) | 1166 | uint32_t start, uint32_t end) |
1167 | { | 1167 | { |
1168 | struct inode *inode = OFNI_EDONI_2SFFJ(f); | ||
1168 | struct jffs2_full_dnode *new_fn; | 1169 | struct jffs2_full_dnode *new_fn; |
1169 | struct jffs2_raw_inode ri; | 1170 | struct jffs2_raw_inode ri; |
1170 | uint32_t alloclen, offset, orig_end, orig_start; | 1171 | uint32_t alloclen, offset, orig_end, orig_start; |
1171 | int ret = 0; | 1172 | int ret = 0; |
1172 | unsigned char *comprbuf = NULL, *writebuf; | 1173 | unsigned char *comprbuf = NULL, *writebuf; |
1173 | unsigned long pg; | 1174 | struct page *page; |
1174 | unsigned char *pg_ptr; | 1175 | unsigned char *pg_ptr; |
1175 | 1176 | ||
1176 | memset(&ri, 0, sizeof(ri)); | 1177 | memset(&ri, 0, sizeof(ri)); |
@@ -1325,15 +1326,18 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1325 | * end up here trying to GC the *same* page that jffs2_write_begin() is | 1326 | * end up here trying to GC the *same* page that jffs2_write_begin() is |
1326 | * trying to write out, read_cache_page() will not deadlock. */ | 1327 | * trying to write out, read_cache_page() will not deadlock. */ |
1327 | mutex_unlock(&f->sem); | 1328 | mutex_unlock(&f->sem); |
1328 | pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg); | 1329 | page = read_cache_page(inode->i_mapping, start >> PAGE_SHIFT, |
1329 | mutex_lock(&f->sem); | 1330 | jffs2_do_readpage_unlock, inode); |
1330 | 1331 | if (IS_ERR(page)) { | |
1331 | if (IS_ERR(pg_ptr)) { | ||
1332 | pr_warn("read_cache_page() returned error: %ld\n", | 1332 | pr_warn("read_cache_page() returned error: %ld\n", |
1333 | PTR_ERR(pg_ptr)); | 1333 | PTR_ERR(page)); |
1334 | return PTR_ERR(pg_ptr); | 1334 | mutex_lock(&f->sem); |
1335 | return PTR_ERR(page); | ||
1335 | } | 1336 | } |
1336 | 1337 | ||
1338 | pg_ptr = kmap(page); | ||
1339 | mutex_lock(&f->sem); | ||
1340 | |||
1337 | offset = start; | 1341 | offset = start; |
1338 | while(offset < orig_end) { | 1342 | while(offset < orig_end) { |
1339 | uint32_t datalen; | 1343 | uint32_t datalen; |
@@ -1396,6 +1400,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1396 | } | 1400 | } |
1397 | } | 1401 | } |
1398 | 1402 | ||
1399 | jffs2_gc_release_page(c, pg_ptr, &pg); | 1403 | kunmap(page); |
1404 | put_page(page); | ||
1400 | return ret; | 1405 | return ret; |
1401 | } | 1406 | } |
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index b86c78d178c6..021a4a2190ee 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -226,7 +226,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r | |||
226 | lastend = this->ofs + this->size; | 226 | lastend = this->ofs + this->size; |
227 | } else { | 227 | } else { |
228 | dbg_fragtree2("lookup gave no frag\n"); | 228 | dbg_fragtree2("lookup gave no frag\n"); |
229 | lastend = 0; | 229 | return -EINVAL; |
230 | } | 230 | } |
231 | 231 | ||
232 | /* See if we ran off the end of the fragtree */ | 232 | /* See if we ran off the end of the fragtree */ |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 21071fc2975d..ef1cfa61549e 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -183,9 +183,6 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, | |||
183 | struct jffs2_inode_info *f, | 183 | struct jffs2_inode_info *f, |
184 | unsigned long offset, | 184 | unsigned long offset, |
185 | unsigned long *priv); | 185 | unsigned long *priv); |
186 | void jffs2_gc_release_page(struct jffs2_sb_info *c, | ||
187 | unsigned char *pg, | ||
188 | unsigned long *priv); | ||
189 | void jffs2_flash_cleanup(struct jffs2_sb_info *c); | 186 | void jffs2_flash_cleanup(struct jffs2_sb_info *c); |
190 | 187 | ||
191 | 188 | ||
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 90431dd613b8..5f7e284e0df3 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -527,8 +527,11 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
527 | err = jffs2_fill_scan_buf(c, sumptr, | 527 | err = jffs2_fill_scan_buf(c, sumptr, |
528 | jeb->offset + c->sector_size - sumlen, | 528 | jeb->offset + c->sector_size - sumlen, |
529 | sumlen - buf_len); | 529 | sumlen - buf_len); |
530 | if (err) | 530 | if (err) { |
531 | if (sumlen > buf_size) | ||
532 | kfree(sumptr); | ||
531 | return err; | 533 | return err; |
534 | } | ||
532 | } | 535 | } |
533 | } | 536 | } |
534 | 537 | ||
diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c index d9af2de9084a..8cdbd53d780c 100644 --- a/fs/ubifs/auth.c +++ b/fs/ubifs/auth.c | |||
@@ -479,8 +479,10 @@ int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node, | |||
479 | return -ENOMEM; | 479 | return -ENOMEM; |
480 | 480 | ||
481 | err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac); | 481 | err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac); |
482 | if (err) | 482 | if (err) { |
483 | kfree(hmac); | ||
483 | return err; | 484 | return err; |
485 | } | ||
484 | 486 | ||
485 | err = crypto_memneq(hmac, node + ofs_hmac, hmac_len); | 487 | err = crypto_memneq(hmac, node + ofs_hmac, hmac_len); |
486 | 488 | ||
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index a5f10d79e0dd..e4b52783819d 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -2817,7 +2817,6 @@ void dbg_debugfs_init_fs(struct ubifs_info *c) | |||
2817 | c->vi.ubi_num, c->vi.vol_id); | 2817 | c->vi.ubi_num, c->vi.vol_id); |
2818 | if (n == UBIFS_DFS_DIR_LEN) { | 2818 | if (n == UBIFS_DFS_DIR_LEN) { |
2819 | /* The array size is too small */ | 2819 | /* The array size is too small */ |
2820 | fname = UBIFS_DFS_DIR_NAME; | ||
2821 | return; | 2820 | return; |
2822 | } | 2821 | } |
2823 | 2822 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 5e1e8ec0589e..7d4547e5202d 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -2267,8 +2267,10 @@ static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, | |||
2267 | } | 2267 | } |
2268 | } else { | 2268 | } else { |
2269 | err = ubifs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0); | 2269 | err = ubifs_fill_super(sb, data, flags & SB_SILENT ? 1 : 0); |
2270 | if (err) | 2270 | if (err) { |
2271 | kfree(c); | ||
2271 | goto out_deact; | 2272 | goto out_deact; |
2273 | } | ||
2272 | /* We do not support atime */ | 2274 | /* We do not support atime */ |
2273 | sb->s_flags |= SB_ACTIVE; | 2275 | sb->s_flags |= SB_ACTIVE; |
2274 | if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) | 2276 | if (IS_ENABLED(CONFIG_UBIFS_ATIME_SUPPORT)) |
diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c index 6f293f662d98..49cb34c3f324 100644 --- a/fs/ubifs/tnc_misc.c +++ b/fs/ubifs/tnc_misc.c | |||
@@ -284,6 +284,7 @@ static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr, | |||
284 | err = ubifs_node_check_hash(c, idx, zzbr->hash); | 284 | err = ubifs_node_check_hash(c, idx, zzbr->hash); |
285 | if (err) { | 285 | if (err) { |
286 | ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs); | 286 | ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs); |
287 | kfree(idx); | ||
287 | return err; | 288 | return err; |
288 | } | 289 | } |
289 | 290 | ||