Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to mkdir after mount #919

Closed
Leonupup opened this issue Jan 9, 2024 · 5 comments
Closed

Fail to mkdir after mount #919

Leonupup opened this issue Jan 9, 2024 · 5 comments
Labels

Comments

@Leonupup
Copy link

Leonupup commented Jan 9, 2024

Hi, I am using littlefs in a stm32 board now.
I want to make a new dir but the function lfs_mkdir() doesn't work. After check, I find this function return LFS_ERR_NOSPC but there are enough block.
I notice that when using lfs_format() and lfs_mount() the element's value in lookahead_buffer is 0x00 sometime, but when lfs_mkdir() they are always 0xff. No free block will be found when using lfs_alloc() .
The picture shows the data in lookahead_buffer and lfs->free before using lfs_mkdir().
I dont know what to do to fix this problem, can you give me some advice?
Thanks very much!

@Leonupup
Copy link
Author

Leonupup commented Jan 9, 2024

data This is the picture. And there is the most important question: the value in lookahead_buffer is really ok? Thank you angin!

@geky geky added the needs investigation no idea what is wrong label Jan 16, 2024
@geky
Copy link
Member

geky commented Jan 16, 2024

Hi @Leonupup, thanks for creating an issue. Sorry if the following is a bit rambly, I'm just trying to write what thoughts come to mind reading your issue.

What is your filesystem configuration? block_size? block_count? lookahead_size? These would be useful to know what's going on.

When allocating blocks, littlefs performs a scan to see what blocks are in use. If it finds a block in use, it marks it as 1 in the lookahead buffer. The fact that the lookahead buffer is all 1s (0xffs) suggests that either the filesystem is full or the allocation code has a bug.

Keep in mind that directories require 2 blocks each. It could be that you're actually out of space because of this.

littlefs can also return LFS_ERR_NOSPC if metadata doesn't fit in a metadata log. There are plans to change this to a different error code (LFS_ERR_RANGE), but at the moment this error is a bit overloaded. To test for this case you could increase the block size, but the lookahead buffer being all 1s (0xffs) suggests this isn't the case...

@Leonupup
Copy link
Author

Leonupup commented Jan 16, 2024

Thanks very much! @geky
The configuration code of my file system is as follows:

uint8_t read_buffer[1024];
uint8_t prog_buffer[1024];
uint8_t lookahead_buffer[1024];

const struct lfs_config lfs_cfg = {
	// block device operations
	.read  = lfs_flash_read,
	.prog  = lfs_flash_prog,
	.erase = lfs_flash_erase,
	.sync  = lfs_flash_sync,
	
	// block device configuration
	.read_size = 256,
	.prog_size = 256,
	.block_size = 4096,
	.block_count = 16,
	.cache_size = 4096,
	.lookahead_size = 1024,
	.block_cycles = 100,
	
	.read_buffer = read_buffer,
	.prog_buffer = prog_buffer,
	.lookahead_buffer = lookahead_buffer,
};
int err;
err = lfs_mount(&lfs, &lfs_cfg);
if(err)
{
    lfs_format(&lfs, &lfs_cfg);
    lfs_mount(&lfs, &lfs_cfg);
}

if(lfs_mkdir(&lfs, "/test"))
{
    while(1)
    {}
}

And this is my test code.

In my opinion, there should be enough blocks for me to create a new dir after lfs_format() and lfs_mount(), but it turns to bad result. I would try to check following your advice.

Anyway there is also another question:
Do I need to modify the code about lfs_free() and lfs_malloc() for using static memory? Or just use LFS_NO_MALLOC and work with littlefs dirctly?
Maybe I need to find the problem in lfs_free() or lfs_malloc() for the reason that I used to modify this part based on the information on the Internet.

Thanks for your advice, Thanks again!

@geky
Copy link
Member

geky commented Jan 16, 2024

Hi @Leonupup, I think this might be the issue:

uint8_t read_buffer[1024];
uint8_t prog_buffer[1024];
uint8_t lookahead_buffer[1024];
	.cache_size = 4096,

The read_buffer and prog_buffer need to be cache_size. This is a bit confusing since there is also read_size/prog_size, but those control the minimum of what can be read/progged, while cache_size controls the maximum.

I could see a call to read_buffer overflowing into the lookahead_buffer in this case. 0xffs are also common here since this is usually the default state of flash after an erase.


As an aside, the lookahead_buffer doesn't really need to be 1024 bytes. Anything past block_count/8 bytes goes unused. There is currently a restrictive alignment requirement, so it does need to be at least 8 bytes, but this requirement is going away soon (#912).


Do I need to modify the code about lfs_free() and lfs_malloc() for using static memory? Or just use LFS_NO_MALLOC and work with littlefs dirctly?

It's up to you. Modifying lfs_free/lfs_malloc to return a single buffer may be an easy solution if you only ever have one file open at a time. Or you can define LFS_NO_MALLOC and provide read_buffer/prog_buffer/lookahead_buffer/file_buffer.

You have most of these already but need one more. Each open file needs its own buffer, which can be provided via lfs_file_opencfg and the buffer field in the lfs_file_config struct:

littlefs/lfs.h

Lines 328 to 330 in 3513ff1

// Optional statically allocated file buffer. Must be cache_size.
// By default lfs_malloc is used to allocate this buffer.
void *buffer;

But because this requires changing all lfs_file_open calls to lfs_file_opencfg, it may be easier to change lfs_malloc to return the buffer if you know you will only have one file open at a time. lfs_file_opencfg is more useful for more complex systems built on top of littlefs.

@geky geky added fixed? and removed needs investigation no idea what is wrong labels Jan 16, 2024
@Leonupup
Copy link
Author

Thanks for your detailed reply! @geky

I'm sorry for taking so long to get back to you. Under your guidance, I find that it is really a overflow error happend in function lfs_cache_zero(), and I change read_buffer and prog_buffer from 1024 bytes to 4096 bytes. It works and I successfully make a dir!

My problem is fixed and I also understand how to use static memory! Thanks for your guidance again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants