Skip to content

Add Dhara FTL Support to LittleFS#7184

Open
singh-aditya-04 wants to merge 9 commits intoSamsung:masterfrom
singh-aditya-04:littlefs_with_dhara
Open

Add Dhara FTL Support to LittleFS#7184
singh-aditya-04 wants to merge 9 commits intoSamsung:masterfrom
singh-aditya-04:littlefs_with_dhara

Conversation

@singh-aditya-04
Copy link
Copy Markdown
Contributor

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

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>
Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of extern, you should define constant of ioctl, and use driver->u.i_bops->ioctl()

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This need to be checked.
fs->geo.erasesize * fs->geo.neraseblocks is same as size of entire of flash (allocated for littlefs) ?

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prev is correct.

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if my comment is correct (https://github.com/Samsung/TizenRT/pull/7184/changes#r2910443698)
then this can be removed.

Comment thread os/fs/driver/mtd/dhara.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated the PR please check

Comment thread os/fs/driver/mtd/dhara.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please put tab to each of code line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated Please check

Comment thread os/fs/driver/mtd/dhara.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what '64' means exactly? can we change constant value to some kind of formula?
(dev->geo->neraseblocks / dev->geo->blocksize I expect)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

64 represents pages in one bock , sure i will change constant value to some kind of formula

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated Please Check

Comment thread os/fs/driver/mtd/dhara.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (page % 16 == 15)
But let's do not use '16' directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated please check

Comment thread os/fs/driver/mtd/dhara.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
}

Comment thread os/fs/driver/mtd/dhara.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coding rule,

if (((p + 1) % page_per_chunk) == 0) {

Comment thread os/fs/littlefs/lfs_vfs.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. enable CONFIG_RESOURCE_FS
    2 disable CONFIG_AUTOMOUNT_ROMFS
  2. Increase CONFIG_USERMAIN_STACKSIZE, but need to be tested.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread os/fs/driver/mtd/mtd_nand.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prev code is proper.
Above layers expect number of written page

Comment thread os/fs/littlefs/lfs_vfs.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Comment thread apps/system/utils/fscmd.c
if (fd < 0) {
continue;
/* Then Find Littlefs over Dhara */
snprintf(name, sizeof(name), "/dev/mtdblock%d", minor);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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'

Comment thread apps/system/utils/fscmd.c
}
/* TODO Multi root of smartfs should be considered when it enabled */
ret = ioctl(fd, BIOC_BULKERASE, 0);
if (ext_dhara)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so lfs + little.c / lfs + dhara will work by same ioctl, BIOC_BULKERASE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please refer to my comment in fscmd.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of extern, you can add this to nand.h

Comment thread os/fs/driver/mtd/dhara.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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???

Comment thread os/fs/driver/mtd/dhara.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this function is not necessary.

  1. Journal resume : It can call MTD_IOCTL directly, because struct dhara_journal include struct dhara_nand, and dhara_nand include dhara_dev_t.
  2. dhara_ioctl : refer to comment in https://github.com/Samsung/TizenRT/pull/7184/changes#r3099185257
  3. Can't understand why first format you considering. can you please explain it?

Comment thread os/fs/driver/mtd/dhara.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check tab

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think lfs_format is enough. because we guarantee first mount during factory phase.

Comment thread os/fs/littlefs/lfs_vfs.c
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants