forked from Minki/linux
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 -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAl4k1v8WHHJpY2hhcmRA c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wTGuD/9PU3qZJq1w5F499YAJb2qx2hLD rseg7SZ4rzKwXI5m2g2EP63lgMQkJZC7u5YUv9c1m0gQnNvVXbTdhba3M1V437Kd F0Ce2SeqbVRi4faGWyEH0TEEmFo2Nk7Uz3iJeaXxUY8BqVrvQZaBYk6GWtj+wWIl Yc2ONKwzIF2BDTU5pFvP2yubHnTm00M4uP46MqAcaWoehd9L+xZhC0xiXyWFiAQE g/ITk4vgD3bJRkI0nYNuHxFIgafIweGlyuNfMMpfh2Yqo5/tGnppPE+H+Maokb8V 6Gqmt9XR34ZGH8mOZsMFWxeK6e68DP2AkzL1EsiT2FlUc6hhCr+pOVEN17Y4eb// IRpy7l8f9BkHvR72roaQusE1UjANC2sw2VtDi4TJO6WpFRx4n94//bf+IxO32os8 0AbIyzYCEo1Kql0wTxhqTZnHJr+zHjcFWOuzZ/95iH5wVQmb3hvlmmozL6ZPV9sG cqyV1sEcFhkUKgCSTmbtoYBKfEJLj4j3WYvLoI7apLYN014ExNJY7PIVfIUtMfZQ Sn0sN8+/gpQOOben67IQK9EdcvEhEkY4JdTHpuZEQmh3cS4HNnhzjM2A+n2sWTU8 lxkakeemcO2sV6ue/Vg6Fq4fPEnQtyOVVsSUHjA7hIy5JXwprDvft4gHkI2r40FI fC9PuCjoUIIJtMyA7g== =9tMk -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
e84bcd61f6
@ -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);
|
||||
|
@ -502,20 +502,41 @@ static void uif_close(struct ubi_device *ubi)
|
||||
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* ubi_free_volumes_from - free volumes from specific index.
|
||||
* @ubi: UBI device description object
|
||||
* @from: the start index used for volume free.
|
||||
*/
|
||||
static void ubi_free_volumes_from(struct ubi_device *ubi, int from)
|
||||
{
|
||||
int 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)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = ubi->vtbl_slots;
|
||||
i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
|
||||
ubi_eba_replace_table(ubi->volumes[i], NULL);
|
||||
ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
|
||||
kfree(ubi->volumes[i]);
|
||||
}
|
||||
ubi_free_volumes_from(ubi, ubi->vtbl_slots);
|
||||
}
|
||||
|
||||
static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -786,7 +786,9 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
|
||||
|
||||
if (page_offset > end_index)
|
||||
break;
|
||||
page = find_or_create_page(mapping, page_offset, ra_gfp_mask);
|
||||
page = pagecache_get_page(mapping, page_offset,
|
||||
FGP_LOCK|FGP_ACCESSED|FGP_CREAT|FGP_NOWAIT,
|
||||
ra_gfp_mask);
|
||||
if (!page)
|
||||
break;
|
||||
if (!PageUptodate(page))
|
||||
|
@ -17,10 +17,14 @@
|
||||
#include "ubifs.h"
|
||||
|
||||
/* Need to be kept consistent with checked flags in ioctl2ubifs() */
|
||||
#define UBIFS_SUPPORTED_IOCTL_FLAGS \
|
||||
#define UBIFS_SETTABLE_IOCTL_FLAGS \
|
||||
(FS_COMPR_FL | FS_SYNC_FL | FS_APPEND_FL | \
|
||||
FS_IMMUTABLE_FL | FS_DIRSYNC_FL)
|
||||
|
||||
/* Need to be kept consistent with checked flags in ubifs2ioctl() */
|
||||
#define UBIFS_GETTABLE_IOCTL_FLAGS \
|
||||
(UBIFS_SETTABLE_IOCTL_FLAGS | FS_ENCRYPT_FL)
|
||||
|
||||
/**
|
||||
* ubifs_set_inode_flags - set VFS inode flags.
|
||||
* @inode: VFS inode to set flags for
|
||||
@ -91,6 +95,8 @@ static int ubifs2ioctl(int ubifs_flags)
|
||||
ioctl_flags |= FS_IMMUTABLE_FL;
|
||||
if (ubifs_flags & UBIFS_DIRSYNC_FL)
|
||||
ioctl_flags |= FS_DIRSYNC_FL;
|
||||
if (ubifs_flags & UBIFS_CRYPT_FL)
|
||||
ioctl_flags |= FS_ENCRYPT_FL;
|
||||
|
||||
return ioctl_flags;
|
||||
}
|
||||
@ -113,7 +119,8 @@ static int setflags(struct inode *inode, int flags)
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
ui->flags = ioctl2ubifs(flags);
|
||||
ui->flags &= ~ioctl2ubifs(UBIFS_SETTABLE_IOCTL_FLAGS);
|
||||
ui->flags |= ioctl2ubifs(flags);
|
||||
ubifs_set_inode_flags(inode);
|
||||
inode->i_ctime = current_time(inode);
|
||||
release = ui->dirty;
|
||||
@ -155,8 +162,9 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
if (get_user(flags, (int __user *) arg))
|
||||
return -EFAULT;
|
||||
|
||||
if (flags & ~UBIFS_SUPPORTED_IOCTL_FLAGS)
|
||||
if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS)
|
||||
return -EOPNOTSUPP;
|
||||
flags &= UBIFS_SETTABLE_IOCTL_FLAGS;
|
||||
|
||||
if (!S_ISDIR(inode->i_mode))
|
||||
flags &= ~FS_DIRSYNC_FL;
|
||||
|
@ -129,7 +129,7 @@ static void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o)
|
||||
static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
|
||||
{
|
||||
if (orph->del) {
|
||||
dbg_gen("deleted twice ino %lu", orph->inum);
|
||||
dbg_gen("deleted twice ino %lu", (unsigned long)orph->inum);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
|
||||
orph->del = 1;
|
||||
orph->dnext = c->orph_dnext;
|
||||
c->orph_dnext = orph;
|
||||
dbg_gen("delete later ino %lu", orph->inum);
|
||||
dbg_gen("delete later ino %lu", (unsigned long)orph->inum);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ static int create_default_filesystem(struct ubifs_info *c)
|
||||
sup = kzalloc(ALIGN(UBIFS_SB_NODE_SZ, c->min_io_size), GFP_KERNEL);
|
||||
mst = kzalloc(c->mst_node_alsz, GFP_KERNEL);
|
||||
idx_node_size = ubifs_idx_node_sz(c, 1);
|
||||
idx = kzalloc(ALIGN(tmp, c->min_io_size), GFP_KERNEL);
|
||||
idx = kzalloc(ALIGN(idx_node_size, c->min_io_size), GFP_KERNEL);
|
||||
ino = kzalloc(ALIGN(UBIFS_INO_NODE_SZ, c->min_io_size), GFP_KERNEL);
|
||||
cs = kzalloc(ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size), GFP_KERNEL);
|
||||
|
||||
|
@ -1599,6 +1599,7 @@ out_free:
|
||||
vfree(c->ileb_buf);
|
||||
vfree(c->sbuf);
|
||||
kfree(c->bottom_up_buf);
|
||||
kfree(c->sup_node);
|
||||
ubifs_debugging_exit(c);
|
||||
return err;
|
||||
}
|
||||
@ -1641,6 +1642,7 @@ static void ubifs_umount(struct ubifs_info *c)
|
||||
vfree(c->ileb_buf);
|
||||
vfree(c->sbuf);
|
||||
kfree(c->bottom_up_buf);
|
||||
kfree(c->sup_node);
|
||||
ubifs_debugging_exit(c);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user