Open pasi-ojala-tridonic opened 5 years ago
Hello @pasi-ojala-tridonic
If I'm not wrong, lfs v1 uses at least 4 blocks (2 for the superblock and 2 others for the root directory). Also each file consumes 1 or more blocks. So, as you have just 10 blocks, you could create up to 6 files.
But, thanks to the COW spirit of lfs, a block with old data will not be released until a succesful write of the new data. It means that if you open a file that already exists, lfs will alloc another block to write to and just after this write the old block where was this file will be free. So, you need at least 1 free block to handle with and this is the source of the "strange behavior".
Resuming, 10 blocks - (4 blocks to metadata (superblock + root directory) + 1 free block to write new data until close the file) = 5 blocks to real data = 5 files max.
If you try to create more than 5 files, you will not respect the lfs spec and the behavior can not be guaranted.
(In v2 all this was changed)
Hi, sorry I haven't been able to dig into this issue yet. I should get better at noting the issues I've written down for later investigation.
Am I guessing right that creating file 6 already reserves too many blocks for all of the updating and directory maintenance to work properly?
Yes, that is likely what's happening, @lsilvaalmeida is right that this is too many files for v1.
However, littlefs should return an error (-ENOSPC) instead of crashing uncontrollably. The fact that it doesn't is a bug.
Unfortunately I'm currently prioritizing v2 issues (and pushing v2 update into Mbed OS), so this issue won't be able to leave my TODO list for now.
@geky, ran into this again... I think I figured out what's going on. When running the following code in a full filesystem, fwrite() happily returns the number of characters I wanted to write. But fclose() returns -1 (after trying to flush to flash, looks like), and errno is set to -ENOSPC. Not sure if this is a flaw or a fact of life, but a good reminder to check return value of fclose(), anyway. `
size_t wrotetotal = fwrite(contents, 1, len, fp);
int err = fclose(fp);
if (err){
tr_error("error closing file, errno %d",errno);
}
`
I have a very small ChainingBlockDevice, 10 blocks total. LFS seems to allow me to create 8 (or more files). Obviously they don't work very well. Test snippet and a log attached. In the snippet, there's a call to mountLittleFS, which does the mount and prints out root directory, and reports the size of the blockdevice.
On the first loop, files get created and initialized (integer, same as filename or 0 for bootcount). Things work reasonably till file 7, where I do get a warning about no more free space. Creating a new file returns a valid handle though, and fwrite() returns a value indicating that the write was fine. Same for file 8.
On second run, I see 8 files in root directory, which should not be possible with the 10 block system. Reading the previous data till file 6 works fine, 7 and 8 return no data. Updating files up to 6 also seems to work according to return values, but
on third run, bootcount is still read as 1, file 2 still has contents of 2, though it should have been updated on previous run. Same for others.
If I use maximum of 5 files total, the system seems to work as intended (the values keep increasing), 6 already show this behavior, in the sense that updating the values will not work. Am I guessing right that creating file 6 already reserves too many blocks for all of the updating and directory maintenance to work properly?
lfstest.txt
LFSv1_10blocks_8files.txt