Commit e84bcd61 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 6e135bae 5d3805af
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+26 −5
Original line number Diff line number Diff line
@@ -503,19 +503,40 @@ 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)
@@ -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);
+13 −10
Original line number Diff line number Diff line
@@ -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;
}
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+2 −6
Original line number Diff line number Diff line
@@ -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;
}

Loading