mtd: ubi: Add sysfs entry to force all pebs' scan
PATCH v2 5/5 mtd: ubi: Add sysfs entry to force all pebs' scan
A given eraseblock can be read many times or not at all.
We do not have the account of such eraseblocks that have
not been accessed since a pre-defined threshold interval.
By means of scanning the entire flash device it is possible to identify all such eraseblocks.
Add a sysfs entry to force scan on all the PEBs on demand basis.
The sysfs entry would be available under /sys/class/ubi/ubiX/peb_scan
- echo 1 to this entry would trigger the scan, ignored if in progress
- On reading returns the scan status (1 = Scan executing, 0 = Scan not executing)
Signed-off-by Pratibhasagar V <[email protected]>
Signed-off-by Tanya Brokhman <[email protected]>
--- drivers/mtd/ubi/build.c | 32 +++++++++-- drivers/mtd/ubi/ubi.h | 3 + drivers/mtd/ubi/wl.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 171 insertions(+), 7 deletions(-)
drivers/mtd/ubi/build.c +28 -4
@@ -154,6 +154,9 @@ static struct device_attribute dev_dt_threshold =static struct device_attribute dev_rd_threshold =__ATTR (rd_threshold, (S_IWUSR |S_IRUGO ), dev_attribute_show, dev_attribute_store); +static struct device_attribute dev_mtd_trigger_scan = +__ATTR (peb_scan, (S_IWUSR |S_IRUGO ), + dev_attribute_show, dev_attribute_store);/** * ubi_volume_notify - send a volume change notification.
@@ -395,6 +398,8 @@ static ssize_t dev_attribute_show(struct device *dev, ret =sprintf (buf,"%d\n" , ubi->dt_threshold); else if (attr == &dev_rd_threshold) ret =sprintf (buf,"%d\n" , ubi->rd_threshold); + else if (attr == &dev_mtd_trigger_scan) + ret =sprintf (buf,"%d\n" , ubi->scan_in_progress); else ret = -EINVAL ;
@@ -406,7 +411,7 @@ static ssize_t dev_attribute_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count) { - int value; + int value, ret;struct ubi_device *ubi; ubi = container_of(dev, struct ubi_device, dev);
@@ -414,8 +419,11 @@ static ssize_t dev_attribute_store(struct device *dev,if (!ubi)return -ENODEV ; -if (kstrtos32 (buf,10 , &value)) -return -EINVAL ; + ret = count; +if (kstrtos32 (buf,10 , &value)) { + ret = -EINVAL ; + goto out; + }/* Consider triggering full scan if threshods change */ else if (attr == &dev_dt_threshold) {if (value <UBI_MAX_DT_THRESHOLD )
@@ -429,9 +437,21 @@ static ssize_t dev_attribute_store(struct device *dev,else pr_err ("Max supported threshold value is %d" ,UBI_MAX_READCOUNTER ); + }else if (attr == &dev_mtd_trigger_scan) { +if (value !=1 ) { +pr_err ("Invalid input. Echo 1 to start trigger" ); + goto out; + } +if (!ubi->lookuptbl) { +pr_err ("lookuptbl is null" ); + goto out; + } + ret =ubi_wl_scan_all (ubi); } -return count; +out: +ubi_put_device (ubi); +return ret; }static void dev_release (struct device *dev)
@@ -500,6 +520,9 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)if (err)return err; err =device_create_file (&ubi->dev, &dev_rd_threshold); +if (err) +return err; + err =device_create_file (&ubi->dev, &dev_mtd_trigger_scan);return err; }
@@ -509,6 +532,7 @@ static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)*/ static void ubi_sysfs_close (struct ubi_device *ubi) { +device_remove_file (&ubi->dev, &dev_mtd_trigger_scan);device_remove_file (&ubi->dev, &dev_mtd_num);device_remove_file (&ubi->dev, &dev_dt_threshold);device_remove_file (&ubi->dev, &dev_rd_threshold);
drivers/mtd/ubi/ubi.h +3 -0
@@ -491,6 +491,7 @@ struct ubi_debug_info {* for more info * @dt_threshold: data retention threshold. See UBI_DT_THRESHOLD * for more info +* @scan_in_progress: true if scanning of device PEBs is in progress * * @flash_size: underlying MTD device size (in bytes) * @peb_count: count of physical eraseblocks on the MTD device
@@ -595,6 +596,7 @@ struct ubi_device {char bgt_name[sizeof (UBI_BGT_NAME_PATTERN )+2 ];int rd_threshold;int dt_threshold; +bool scan_in_progress;/* I/O sub-system's stuff */
@@ -873,6 +875,7 @@ int ubi_is_erase_work(struct ubi_work *wrk);void ubi_refill_pools (struct ubi_device *ubi);int ubi_ensure_anchor_pebs (struct ubi_device *ubi);int ubi_in_wl_tree (struct ubi_wl_entry *e,struct rb_root *root); +int ubi_wl_scan_all (struct ubi_device *ubi);/* io.c */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
drivers/mtd/ubi/wl.c +140 -3
168 lines not on this page · raw message
Signature · 3 lines
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project