Add Dhara FTL Support to LittleFS#7184
Add Dhara FTL Support to LittleFS#7184singh-aditya-04 wants to merge 9 commits intoSamsung:masterfrom
Conversation
Add support to littlefs VFS layer to choose the driver based on INODE. For MTD driver select the MTD defined functions otherwise use block device.
Register dhara as block driver on top of MTD device. This block device is used to mount littlfs on /mnt.
Dhara documentation shows that in case of successful read 0 should be returned. But current TizeRT code returns numnber of read.
These changes modifies the format_filesystem function to add support for formatting LittleFS over Dhara (MTD-based filesystem) in addition to the existing block device formatting capabilities.
autoformat not working in case mount fails. memory corruption due to wrong assignment for dhara. causing corruption of dhara structure.
in case nand erase encounter bad block, return eagain and continue erasing other blocks. Also fix return for nand_bread
Two changes are done for this to sync the behaviour between Dhara and littleFS 1) We change littlefs_blocksize from fs->geo.erasesize (128 KB) to fs->geo.blocksize(2 KB). 2) As we are reserving some sectors (pages) for dhara inside files os/fs/driver/mtd/dhara/journal.c and os/fs/driver/mtd/dhara/map.c so we are going to give total pages - reserved pages as available blocks to Littlefs. Signed-off-by: Aditya Singh <aditya.s4@samsung.com> Signed-off-by: Aashish Lakhwara <aashish.l@samsung.com>
We have varified dhara itself manages bad block checking so we do not need mtd to manage bad block checking as it increases flash read operations. Signed-off-by: Aditya Singh <aditya.s4@samsung.com> Signed-off-by: Aashish Lakhwara <aashish.l@samsung.com>
There was a problem hiding this comment.
instead of extern, you should define constant of ioctl, and use driver->u.i_bops->ioctl()
There was a problem hiding this comment.
This need to be checked.
fs->geo.erasesize * fs->geo.neraseblocks is same as size of entire of flash (allocated for littlefs) ?
There was a problem hiding this comment.
So erase size of MTD driver will be asigned.
But ftl will use blocksize of erase (Not erase internally). I mean lfs doesn't care flash is nor or nand. so if nand is attached, then blocksize will be used as a erasesize.
If I am right then geometry of ftl (include dhara) need to be updated.
There was a problem hiding this comment.
if my comment is correct (https://github.com/Samsung/TizenRT/pull/7184/changes#r2910443698)
then this can be removed.
There was a problem hiding this comment.
please remove this line
There was a problem hiding this comment.
updated the PR please check
There was a problem hiding this comment.
please put tab to each of code line.
There was a problem hiding this comment.
updated Please check
There was a problem hiding this comment.
what '64' means exactly? can we change constant value to some kind of formula?
(dev->geo->neraseblocks / dev->geo->blocksize I expect)
There was a problem hiding this comment.
64 represents pages in one bock , sure i will change constant value to some kind of formula
There was a problem hiding this comment.
Updated Please Check
There was a problem hiding this comment.
if (page % 16 == 15)
But let's do not use '16' directly.
There was a problem hiding this comment.
Updated please check
There was a problem hiding this comment.
You reused this code from origin code of dhara. and I think this is implemented wrongly.
Because MTD_BREAD can be failed because of other issue, for example SPI.(of course w25n returns ERROR when status is ECC Fail. so I think we should put some TODO Comment here. I think kind of below logic is required
if (ret < 0) {
dhara_insert_metadatacache(dev, mcache);
if (check_ecc_check_logic) {
dhara_set_error(err, DHARA_E_ECC);
}
return ret;
}
030fe79 to
c817e72
Compare
There was a problem hiding this comment.
coding rule,
if (((p + 1) % page_per_chunk) == 0) {
There was a problem hiding this comment.
can you please add bracket ? according to our coding rule, bracket must be added for 1 line of code.
| CONFIG_MTD_NAND_MAXPAGESPARESIZE=128 | ||
| CONFIG_MTD_NAND_MAXSPAREECCBYTES=64 | ||
| CONFIG_MTD_NAND_BLOCKCHECK=y | ||
| #CONFIG_MTD_NAND_BLOCKCHECK=y |
There was a problem hiding this comment.
- enable CONFIG_RESOURCE_FS
2 disable CONFIG_AUTOMOUNT_ROMFS - Increase CONFIG_USERMAIN_STACKSIZE, but need to be tested.
There was a problem hiding this comment.
Also some values are changed in flat_dev_ddr, can you please update entire of defconfig? we can change only fs, mtd, ftl and above configs I mentioned from flat_dev_ddr
There was a problem hiding this comment.
prev code is proper.
Above layers expect number of written page
There was a problem hiding this comment.
even if mount failed, bulkerase should not be happened. because of sudden power off, this can be reached.
A Metadata Cache based on Most Recently Used Metadata Page has been implemented inside file dhara.c that can be useful for faster page reads. Signed-off-by: Aditya Singh <aditya.s4@samsung.com> Signed-off-by: Aashish Lakhwara <aashish.l@samsung.com>w
c817e72 to
5c61406
Compare
| if (fd < 0) { | ||
| continue; | ||
| /* Then Find Littlefs over Dhara */ | ||
| snprintf(name, sizeof(name), "/dev/mtdblock%d", minor); |
There was a problem hiding this comment.
hmm I think this is very dangerous code, other partition which use bch can be erased.
I think we should allow access dhara_initialize_by_path from partitions.c and use '/dev/little%dp%d'
| } | ||
| /* TODO Multi root of smartfs should be considered when it enabled */ | ||
| ret = ioctl(fd, BIOC_BULKERASE, 0); | ||
| if (ext_dhara) |
There was a problem hiding this comment.
so lfs + little.c / lfs + dhara will work by same ioctl, BIOC_BULKERASE
There was a problem hiding this comment.
I think someday we can use nand for internal flash so minor will be decided by defconfig.
hence below is enough for now.
#ifdef CONFIG_MTD_DHARA
...
int ret = dhara_initialize(dhara_minor, mtd_part);
...
#else
little_initialize(minor, mtd_part, partref);
#endif
partinfo->littlefs_partno = g_partno;
There was a problem hiding this comment.
please refer to my comment in fscmd.
There was a problem hiding this comment.
instead of extern, you can add this to nand.h
There was a problem hiding this comment.
so, if below code should use this function,
https://github.com/Samsung/TizenRT/pull/7184/changes#diff-2e8e8a310aaa1d9332c8ce08cf1a2b6af261d63277ce4d18579eff09097dda1bR981
then we can consider below.
#journal.c
dhara_block_t dhara_journal_get_block_capacity(const struct dhara_journal *j)
{
const dhara_block_t max_bad = j->bb_last > j->bb_current ? j->bb_last : j->bb_current;
const dhara_block_t good_blocks = j->nand->num_blocks - max_bad - 1;
return good_blocks;
}
#map.c
dhara_sector_t dhara_map_get_good_block(const struct dhara_map *m)
{
return dhara_journal_get_block_capacity(&m->journal);
}
#dhara.c
static int dhara_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
{
FAR dhara_dev_t *dev;
int ret;
DEBUGASSERT(inode->i_private);
dev = inode->i_private;
/* No other block driver ioctl commands are not recognized by this
* driver. Other possible MTD driver ioctl commands are passed through
* to the MTD driver (unchanged).
*/
ret = MTD_IOCTL(dev->mtd, cmd, arg);
if (ret < 0 && ret != -ENOTTY) {
ferr("MTD ioctl(%04x) failed: %d\n", cmd, ret);
return ret;
}
if (cmd == MTDIOC_GEOMETRY)
{
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg;
if (geo) {
/* Populate the geometry structure with information needed to know
* the capacity and how to access the device.
*/
geo->neraseblocks = dhara_map_get_good_block(dev->map);
}
}
return ret;
#lfs_Vfs.c
static int littlefs_bind(FAR struct inode *driver, FAR const void *data, FAR void **handle)
{
...
fs->cfg.read_size = fs->geo.blocksize;
fs->cfg.prog_size = fs->geo.blocksize;
fs->cfg.block_size = fs->geo.blocksize;
fs->cfg.block_count = fs->geo.neraseblocks * fs->geo.erasesize / fs->geo.blocksize;
}
But is lfs should know number of capacity???
There was a problem hiding this comment.
I think this function is not necessary.
- Journal resume : It can call MTD_IOCTL directly, because struct dhara_journal include struct dhara_nand, and dhara_nand include dhara_dev_t.
- dhara_ioctl : refer to comment in https://github.com/Samsung/TizenRT/pull/7184/changes#r3099185257
- Can't understand why first format you considering. can you please explain it?
There was a problem hiding this comment.
I think lfs_format is enough. because we guarantee first mount during factory phase.
There was a problem hiding this comment.
can you please check 'fs->cfg.sync = littlefs_sync_block;' can be used instead of this?
I think below can be used.
int lfs_check_format(lfs_t *lfs, const struct lfs_config *cfg)
{
....
cleanup:
if (err == LFS_ERR_OK) {
cfg->sync(cfg);
}
lfs_deinit(lfs);
LFS_UNLOCK(cfg);
return err;
}
of course BIOC_FLUSH need to be added to ioctl.h
1) Integrates Dhara FTL with LittleFS filesystem
2) Fix autoformat and memory corruption
3) Fix nand erase to continue if bad block
4) Reduces internal fragmentation of Littlefs with dhara
5) Adds metadata cache for improved read speeds