diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-30 15:44:12 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-30 15:44:12 -0800 |
commit | e84bcd61f686d65956c9f54872778bb215059519 (patch) | |
tree | d51d2870e628bea30af37dde063ac2da0a3f1ac1 /drivers | |
parent | 6e135baed8e70b00b88f7608f6b041461a5270bc (diff) | |
parent | 5d3805af279c93ef49a64701f35254676d709622 (diff) |
Merge tag 'upstream-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI/UBIFS updates from Miquel Raynal:
"This pull request contains mostly fixes for UBI and UBIFS:
UBI:
- Fixes for memory leaks in error paths
- Fix for an logic error in a fastmap selfcheck
UBIFS:
- Fix for FS_IOC_SETFLAGS related to fscrypt flag
- Support for FS_ENCRYPT_FL
- Fix for a dead lock in bulk-read mode"
Sent on behalf of Richard Weinberger who is traveling.
* tag 'upstream-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs:
ubi: Fix an error pointer dereference in error handling code
ubifs: Fix memory leak from c->sup_node
ubifs: Fix ino_t format warnings in orphan_delete()
ubifs: Fix deadlock in concurrent bulk-read and writepage
ubifs: Fix wrong memory allocation
ubi: Free the normal volumes in error paths of ubi_attach_mtd_dev()
ubi: Check the presence of volume before call ubi_fastmap_destroy_checkmap()
ubifs: Add support for FS_ENCRYPT_FL
ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag
ubi: wl: Remove set but not used variable 'prev_e'
ubi: fastmap: Fix inverted logic in seen selfcheck
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/attach.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 31 | ||||
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 23 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 3 |
6 files changed, 44 insertions, 24 deletions
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 10b2459f8951..ea7440ac913b 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1640,7 +1640,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) out_wl: ubi_wl_close(ubi); out_vtbl: - ubi_free_internal_volumes(ubi); + ubi_free_all_volumes(ubi); vfree(ubi->vtbl); out_ai: destroy_ai(ai); diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index d636bbe214cb..25fb72b2efa0 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -503,21 +503,42 @@ static void uif_close(struct ubi_device *ubi) } /** - * ubi_free_internal_volumes - free internal volumes. + * ubi_free_volumes_from - free volumes from specific index. * @ubi: UBI device description object + * @from: the start index used for volume free. */ -void ubi_free_internal_volumes(struct ubi_device *ubi) +static void ubi_free_volumes_from(struct ubi_device *ubi, int from) { int i; - for (i = ubi->vtbl_slots; - i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { + for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { + if (!ubi->volumes[i]) + continue; ubi_eba_replace_table(ubi->volumes[i], NULL); ubi_fastmap_destroy_checkmap(ubi->volumes[i]); kfree(ubi->volumes[i]); + ubi->volumes[i] = NULL; } } +/** + * ubi_free_all_volumes - free all volumes. + * @ubi: UBI device description object + */ +void ubi_free_all_volumes(struct ubi_device *ubi) +{ + ubi_free_volumes_from(ubi, 0); +} + +/** + * ubi_free_internal_volumes - free internal volumes. + * @ubi: UBI device description object + */ +void ubi_free_internal_volumes(struct ubi_device *ubi) +{ + ubi_free_volumes_from(ubi, ubi->vtbl_slots); +} + static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) { int limit, device_pebs; @@ -1013,7 +1034,7 @@ out_uif: out_detach: ubi_devices[ubi_num] = NULL; ubi_wl_close(ubi); - ubi_free_internal_volumes(ubi); + ubi_free_all_volumes(ubi); vfree(ubi->vtbl); out_free: vfree(ubi->peb_buf); diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 1c7be4eb3ba6..53f448e7433a 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -64,7 +64,7 @@ static int self_check_seen(struct ubi_device *ubi, unsigned long *seen) return 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) { - if (test_bit(pnum, seen) && ubi->lookuptbl[pnum]) { + if (!test_bit(pnum, seen) && ubi->lookuptbl[pnum]) { ubi_err(ubi, "self-check failed for PEB %d, fastmap didn't see it", pnum); ret = -EINVAL; } @@ -1137,7 +1137,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, struct rb_node *tmp_rb; int ret, i, j, free_peb_count, used_peb_count, vol_count; int scrub_peb_count, erase_peb_count; - unsigned long *seen_pebs = NULL; + unsigned long *seen_pebs; fm_raw = ubi->fm_buf; memset(ubi->fm_buf, 0, ubi->fm_size); @@ -1151,7 +1151,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID); if (!dvbuf) { ret = -ENOMEM; - goto out_kfree; + goto out_free_avbuf; } avhdr = ubi_get_vid_hdr(avbuf); @@ -1160,7 +1160,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, seen_pebs = init_seen(ubi); if (IS_ERR(seen_pebs)) { ret = PTR_ERR(seen_pebs); - goto out_kfree; + goto out_free_dvbuf; } spin_lock(&ubi->volumes_lock); @@ -1328,7 +1328,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf); if (ret) { ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); - goto out_kfree; + goto out_free_seen; } for (i = 0; i < new_fm->used_blocks; i++) { @@ -1350,7 +1350,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, if (ret) { ubi_err(ubi, "unable to write vid_hdr to PEB %i!", new_fm->e[i]->pnum); - goto out_kfree; + goto out_free_seen; } } @@ -1360,7 +1360,7 @@ static int ubi_write_fastmap(struct ubi_device *ubi, if (ret) { ubi_err(ubi, "unable to write fastmap to PEB %i!", new_fm->e[i]->pnum); - goto out_kfree; + goto out_free_seen; } } @@ -1370,10 +1370,13 @@ static int ubi_write_fastmap(struct ubi_device *ubi, ret = self_check_seen(ubi, seen_pebs); dbg_bld("fastmap written!"); -out_kfree: - ubi_free_vid_buf(avbuf); - ubi_free_vid_buf(dvbuf); +out_free_seen: free_seen(seen_pebs); +out_free_dvbuf: + ubi_free_vid_buf(dvbuf); +out_free_avbuf: + ubi_free_vid_buf(avbuf); + out: return ret; } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 9688b411c930..73c67e5c08f8 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -950,6 +950,7 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ubi_notify_all(struct ubi_device *ubi, int ntype, struct notifier_block *nb); int ubi_enumerate_volumes(struct notifier_block *nb); +void ubi_free_all_volumes(struct ubi_device *ubi); void ubi_free_internal_volumes(struct ubi_device *ubi); /* kapi.c */ diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 53d8ab54e181..f700f0e4f2ec 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -782,7 +782,7 @@ static int check_attaching_info(const struct ubi_device *ubi, */ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) { - int i, err; + int err; struct ubi_ainf_volume *av; empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); @@ -851,11 +851,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai) out_free: vfree(ubi->vtbl); - for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { - ubi_fastmap_destroy_checkmap(ubi->volumes[i]); - kfree(ubi->volumes[i]); - ubi->volumes[i] = NULL; - } + ubi_free_all_volumes(ubi); return err; } diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 5d77a38dba54..837d690a8c60 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -319,7 +319,7 @@ static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi, struct rb_root *root, int diff) { struct rb_node *p; - struct ubi_wl_entry *e, *prev_e = NULL; + struct ubi_wl_entry *e; int max; e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb); @@ -334,7 +334,6 @@ static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi, p = p->rb_left; else { p = p->rb_right; - prev_e = e; e = e1; } } |