Commit 669d2044 authored by Zhihao Cheng's avatar Zhihao Cheng Committed by Richard Weinberger

ubi: fastmap: Add fastmap control support for 'UBI_IOCATT' ioctl

[1] suggests that fastmap is suitable for large flash devices. Module
parameter 'fm_autoconvert' is a coarse grained switch to enable all
ubi devices to generate fastmap, which may turn on fastmap even for
small flash devices.

This patch imports a new field 'disable_fm' in struct 'ubi_attach_req'
to support following situations by ioctl 'UBI_IOCATT'.
 [old functions]
 A. Disable 'fm_autoconvert': Disbable fastmap for all ubi devices
 B. Enable 'fm_autoconvert': Enable fastmap for all ubi devices
 [new function]
 C. Enable 'fm_autoconvert', set 'disable_fm' for given device: Don't
    create new fastmap and do full scan (existed fastmap will be
    destroyed) for the given ubi device.

A simple test case in [2].

[1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_fastmap
[2] https://bugzilla.kernel.org/show_bug.cgi?id=216278Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent e7f35da2
...@@ -807,6 +807,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) ...@@ -807,6 +807,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
* @ubi_num: number to assign to the new UBI device * @ubi_num: number to assign to the new UBI device
* @vid_hdr_offset: VID header offset * @vid_hdr_offset: VID header offset
* @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
* @disable_fm: whether disable fastmap
* *
* This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number
* to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in
...@@ -814,11 +815,15 @@ static int autoresize(struct ubi_device *ubi, int vol_id) ...@@ -814,11 +815,15 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
* automatically. Returns the new UBI device number in case of success and a * automatically. Returns the new UBI device number in case of success and a
* negative error code in case of failure. * negative error code in case of failure.
* *
* If @disable_fm is true, ubi doesn't create new fastmap even the module param
* 'fm_autoconvert' is set, and existed old fastmap will be destroyed after
* doing full scanning.
*
* Note, the invocations of this function has to be serialized by the * Note, the invocations of this function has to be serialized by the
* @ubi_devices_mutex. * @ubi_devices_mutex.
*/ */
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024) int vid_hdr_offset, int max_beb_per1024, bool disable_fm)
{ {
struct ubi_device *ubi; struct ubi_device *ubi;
int i, err; int i, err;
...@@ -921,7 +926,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ...@@ -921,7 +926,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
UBI_FM_MIN_POOL_SIZE); UBI_FM_MIN_POOL_SIZE);
ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2; ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2;
ubi->fm_disabled = !fm_autoconvert; ubi->fm_disabled = (!fm_autoconvert || disable_fm) ? 1 : 0;
if (fm_debug) if (fm_debug)
ubi_enable_dbg_chk_fastmap(ubi); ubi_enable_dbg_chk_fastmap(ubi);
...@@ -962,7 +967,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, ...@@ -962,7 +967,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
if (!ubi->fm_buf) if (!ubi->fm_buf)
goto out_free; goto out_free;
#endif #endif
err = ubi_attach(ubi, 0); err = ubi_attach(ubi, disable_fm ? 1 : 0);
if (err) { if (err) {
ubi_err(ubi, "failed to attach mtd%d, error %d", ubi_err(ubi, "failed to attach mtd%d, error %d",
mtd->index, err); mtd->index, err);
...@@ -1242,7 +1247,8 @@ static int __init ubi_init(void) ...@@ -1242,7 +1247,8 @@ static int __init ubi_init(void)
mutex_lock(&ubi_devices_mutex); mutex_lock(&ubi_devices_mutex);
err = ubi_attach_mtd_dev(mtd, p->ubi_num, err = ubi_attach_mtd_dev(mtd, p->ubi_num,
p->vid_hdr_offs, p->max_beb_per1024); p->vid_hdr_offs, p->max_beb_per1024,
false);
mutex_unlock(&ubi_devices_mutex); mutex_unlock(&ubi_devices_mutex);
if (err < 0) { if (err < 0) {
pr_err("UBI error: cannot attach mtd%d\n", pr_err("UBI error: cannot attach mtd%d\n",
......
...@@ -1041,7 +1041,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, ...@@ -1041,7 +1041,7 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
*/ */
mutex_lock(&ubi_devices_mutex); mutex_lock(&ubi_devices_mutex);
err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset,
req.max_beb_per1024); req.max_beb_per1024, !!req.disable_fm);
mutex_unlock(&ubi_devices_mutex); mutex_unlock(&ubi_devices_mutex);
if (err < 0) if (err < 0)
put_mtd_device(mtd); put_mtd_device(mtd);
......
...@@ -937,7 +937,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -937,7 +937,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
/* build.c */ /* build.c */
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024); int vid_hdr_offset, int max_beb_per1024,
bool disable_fm);
int ubi_detach_mtd_dev(int ubi_num, int anyway); int ubi_detach_mtd_dev(int ubi_num, int anyway);
struct ubi_device *ubi_get_device(int ubi_num); struct ubi_device *ubi_get_device(int ubi_num);
void ubi_put_device(struct ubi_device *ubi); void ubi_put_device(struct ubi_device *ubi);
......
...@@ -247,6 +247,7 @@ enum { ...@@ -247,6 +247,7 @@ enum {
* @vid_hdr_offset: VID header offset (use defaults if %0) * @vid_hdr_offset: VID header offset (use defaults if %0)
* @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs
* @padding: reserved for future, not used, has to be zeroed * @padding: reserved for future, not used, has to be zeroed
* @disable_fm: whether disable fastmap
* *
* This data structure is used to specify MTD device UBI has to attach and the * This data structure is used to specify MTD device UBI has to attach and the
* parameters it has to use. The number which should be assigned to the new UBI * parameters it has to use. The number which should be assigned to the new UBI
...@@ -281,13 +282,18 @@ enum { ...@@ -281,13 +282,18 @@ enum {
* eraseblocks for new bad eraseblocks, but attempts to use available * eraseblocks for new bad eraseblocks, but attempts to use available
* eraseblocks (if any). The accepted range is 0-768. If 0 is given, the * eraseblocks (if any). The accepted range is 0-768. If 0 is given, the
* default kernel value of %CONFIG_MTD_UBI_BEB_LIMIT will be used. * default kernel value of %CONFIG_MTD_UBI_BEB_LIMIT will be used.
*
* If @disable_fm is not zero, ubi doesn't create new fastmap even the module
* param 'fm_autoconvert' is set, and existed old fastmap will be destroyed
* after doing full scanning.
*/ */
struct ubi_attach_req { struct ubi_attach_req {
__s32 ubi_num; __s32 ubi_num;
__s32 mtd_num; __s32 mtd_num;
__s32 vid_hdr_offset; __s32 vid_hdr_offset;
__s16 max_beb_per1024; __s16 max_beb_per1024;
__s8 padding[10]; __s8 disable_fm;
__s8 padding[9];
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment