diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-08 11:40:45 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-08 11:40:45 (GMT) |
commit | e9eca4de957ac33744fb994ccacd4a5102e445a8 (patch) | |
tree | fc1cf7c808d3daa365a56856321834d030fcf10d /drivers/mtd/ubi/build.c | |
parent | 1929041bd8afeb3995b7c68d6f16e03422848a4c (diff) | |
parent | 76ac66e469f084d41742ba08923de76fbdc7dce3 (diff) | |
download | linux-fsl-qoriq-e9eca4de957ac33744fb994ccacd4a5102e445a8.tar.xz |
Merge tag 'upstream-3.7-rc1-fastmap' of git://git.infradead.org/linux-ubi
Pull UBI fastmap changes from Artem Bityutskiy:
"This pull request contains the UBI fastmap support implemented by
Richard Weinberger from Linutronix. Fastmap is designed to address
UBI's slow scanning issues. Namely, it introduces a new on-flash
data-structure called "fastmap", which stores the information about
logical<->physical eraseblocks mappings. So now to get this
information just read the fastmap, instead of doing full scan. More
information here can be found in Richard's announcement in LKML
(Subject: UBI: Fastmap request for inclusion (v19)):
http://thread.gmane.org/gmane.linux.kernel/1364922/focus=1369109
One thing I want to explicitly say is that fastmap did not have large
enough linux-next exposure. It is partially my fault - I did not
respond quickly enough. I _really_ apologize for this. But it had
good testing and disabled by default, so I do not expect that we'll
break anything.
Fastmap is declared as experimental so far, and it is off by default.
We did declare that the on-flash format may be changed. The reason
for this is that no one used it in real production so far, so there is
a high risk that something is missing. Besides, we do not have
user-space tools supporting fastmap so far.
Nevertheless, I suggest we merge this feature. Many people want UBI's
scanning bottleneck to be fixed and merging fastmap now should
accelerate its production use. The plan is to make it bullet-prove,
somewhat clean-up, and make it the default for UBI. I do not know how
many kernel releases will it take.
Basically, I what I want to do for fastmap is something like Linus did
for btrfs few years ago."
* tag 'upstream-3.7-rc1-fastmap' of git://git.infradead.org/linux-ubi:
UBI: Wire-up fastmap
UBI: Add fastmap core
UBI: Add fastmap support to the WL sub-system
UBI: Add fastmap stuff to attach.c
UBI: Wire-up ->fm_sem
UBI: Add fastmap bits to build.c
UBI: Add self_check_eba()
UBI: Export next_sqnum()
UBI: Add fastmap stuff to ubi.h
UBI: Add fastmap on-flash data structures
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 3497703..344b4cb 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -76,7 +76,10 @@ static int __initdata mtd_devs; /* MTD devices specification parameters */ static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES]; - +#ifdef CONFIG_MTD_UBI_FASTMAP +/* UBI module parameter to enable fastmap automatically on non-fastmap images */ +static bool fm_autoconvert; +#endif /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ struct class *ubi_class; @@ -153,6 +156,19 @@ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) ubi_do_get_device_info(ubi, &nt.di); ubi_do_get_volume_info(ubi, vol, &nt.vi); + +#ifdef CONFIG_MTD_UBI_FASTMAP + switch (ntype) { + case UBI_VOLUME_ADDED: + case UBI_VOLUME_REMOVED: + case UBI_VOLUME_RESIZED: + case UBI_VOLUME_RENAMED: + if (ubi_update_fastmap(ubi)) { + ubi_err("Unable to update fastmap!"); + ubi_ro_mode(ubi); + } + } +#endif return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); } @@ -918,10 +934,40 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; +#ifdef CONFIG_MTD_UBI_FASTMAP + ubi->fm_pool.used = ubi->fm_pool.size = 0; + ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0; + + /* + * fm_pool.max_size is 5% of the total number of PEBs but it's also + * between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE. + */ + ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size, + ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE); + if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) + ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; + + ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; + ubi->fm_disabled = !fm_autoconvert; + + if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) + <= UBI_FM_MAX_START) { + ubi_err("More than %i PEBs are needed for fastmap, sorry.", + UBI_FM_MAX_START); + ubi->fm_disabled = 1; + } + + ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); +#else + ubi->fm_disabled = 1; +#endif mutex_init(&ubi->buf_mutex); mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->device_mutex); spin_lock_init(&ubi->volumes_lock); + mutex_init(&ubi->fm_mutex); + init_rwsem(&ubi->fm_sem); ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); @@ -934,11 +980,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi->peb_buf) goto out_free; +#ifdef CONFIG_MTD_UBI_FASTMAP + ubi->fm_size = ubi_calc_fm_size(ubi); + ubi->fm_buf = vzalloc(ubi->fm_size); + if (!ubi->fm_buf) + goto out_free; +#endif err = ubi_debugging_init_dev(ubi); if (err) goto out_free; - err = ubi_attach(ubi); + err = ubi_attach(ubi, 0); if (err) { ubi_err("failed to attach mtd%d, error %d", mtd->index, err); goto out_debugging; @@ -1012,6 +1064,7 @@ out_debugging: ubi_debugging_exit_dev(ubi); out_free: vfree(ubi->peb_buf); + vfree(ubi->fm_buf); if (ref) put_device(&ubi->dev); else @@ -1061,7 +1114,11 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); - +#ifdef CONFIG_MTD_UBI_FASTMAP + /* If we don't write a new fastmap at detach time we lose all + * EC updates that have been made since the last written fastmap. */ + ubi_update_fastmap(ubi); +#endif /* * Before freeing anything, we have to stop the background thread to * prevent it from doing anything on this device while we are freeing. @@ -1077,12 +1134,14 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_debugfs_exit_dev(ubi); uif_close(ubi); + ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); ubi_debugging_exit_dev(ubi); vfree(ubi->peb_buf); + vfree(ubi->fm_buf); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); put_device(&ubi->dev); return 0; @@ -1404,7 +1463,10 @@ MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|pa "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); - +#ifdef CONFIG_MTD_UBI_FASTMAP +module_param(fm_autoconvert, bool, 0644); +MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); +#endif MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_DESCRIPTION("UBI - Unsorted Block Images"); MODULE_AUTHOR("Artem Bityutskiy"); |