Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34653fd8 authored by Richard Weinberger's avatar Richard Weinberger
Browse files

ubi: fastmap: Check each mapping only once



Maintain a bitmap to keep track of which LEB->PEB mapping
was checked already.
That way we have to read back VID headers only once.

Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 78193237
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -526,6 +526,7 @@ void ubi_free_internal_volumes(struct ubi_device *ubi)
	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]);
	}
}
+4 −0
Original line number Diff line number Diff line
@@ -517,6 +517,9 @@ static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnu
	if (!ubi->fast_attach)
		return 0;

	if (!vol->checkmap || test_bit(lnum, vol->checkmap))
		return 0;

	vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS);
	if (!vidb)
		return -ENOMEM;
@@ -551,6 +554,7 @@ static int check_mapping(struct ubi_device *ubi, struct ubi_volume *vol, int lnu
		goto out_free;
	}

	set_bit(lnum, vol->checkmap);
	err = 0;

out_free:
+20 −0
Original line number Diff line number Diff line
@@ -1100,6 +1100,26 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
	goto out;
}

int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count)
{
	struct ubi_device *ubi = vol->ubi;

	if (!ubi->fast_attach)
		return 0;

	vol->checkmap = kcalloc(BITS_TO_LONGS(leb_count), sizeof(unsigned long),
				GFP_KERNEL);
	if (!vol->checkmap)
		return -ENOMEM;

	return 0;
}

void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol)
{
	kfree(vol->checkmap);
}

/**
 * ubi_write_fastmap - writes a fastmap.
 * @ubi: UBI device object
+11 −0
Original line number Diff line number Diff line
@@ -334,6 +334,9 @@ struct ubi_eba_leb_desc {
 * @changing_leb: %1 if the atomic LEB change ioctl command is in progress
 * @direct_writes: %1 if direct writes are enabled for this volume
 *
 * @checkmap: bitmap to remember which PEB->LEB mappings got checked,
 *            protected by UBI LEB lock tree.
 *
 * The @corrupted field indicates that the volume's contents is corrupted.
 * Since UBI protects only static volumes, this field is not relevant to
 * dynamic volumes - it is user's responsibility to assure their data
@@ -377,6 +380,10 @@ struct ubi_volume {
	unsigned int updating:1;
	unsigned int changing_leb:1;
	unsigned int direct_writes:1;

#ifdef CONFIG_MTD_UBI_FASTMAP
	unsigned long *checkmap;
#endif
};

/**
@@ -965,8 +972,12 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi);
int ubi_update_fastmap(struct ubi_device *ubi);
int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
		     struct ubi_attach_info *scan_ai);
int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count);
void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol);
#else
static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; }
int static inline ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) { return 0; }
static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {}
#endif

/* block.c */
+1 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ static void vol_release(struct device *dev)
	struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev);

	ubi_eba_replace_table(vol, NULL);
	ubi_fastmap_destroy_checkmap(vol);
	kfree(vol);
}

Loading