littlefs-project / littlefs

A little fail-safe filesystem designed for microcontrollers
BSD 3-Clause "New" or "Revised" License
4.9k stars 771 forks source link

Littlle Fs Multiple partition Issue #925

Open evaneight opened 5 months ago

evaneight commented 5 months ago

Have set up multiple lfs_t's, lfs_config's and read/write/lookahead buffers and using the context to store an offset into a single flash device allowing multiple partitions - all seems to work ok as long as all the partitions are the same size (block count). As soon as one of the partitions has a different block count to the others they all fail at the mount call. The issue is at this section (approx line 4445):-

        // this is where we get the block_count from disk if block_count=0
        if (lfs->cfg->block_count
                && superblock.block_count != lfs->cfg->block_count) {
            LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
                    superblock.block_count, lfs->cfg->block_count);
            err = LFS_ERR_INVAL;
            goto cleanup;

The superblock count and block count dont match so the goto is taken.

Have debugged all the read writes through my flash driver - all ok - no block overwrites etc. Something seems to be shared that I am unaware of or perhaps an issue within LittleFs (which seems hard to believe at this point).

geky commented 5 months ago

That's weird, if you have separate lfs_config structs, they should be fine with different block_counts.

Do you keep the lfs_config structs allocated for the lifetime of each littlefs instance? littlefs keeps a reference to the lfs_config struct and I could see malloc returning the same memory.

Other than that this probably needs to be debugged on the device by setting a watchpoint on your lfs->cfg->block_size and see when it stops being the expected value. Maybe there's memory corruption elsewhere?

You're welcome to try to recreate this locally in a littlefs test (unfortunately there's not great documentation at the moment), but I don't think it will be very fruitful. The separate configurations is pretty simple code.

evaneight commented 5 months ago

Hi - thanks for the prompt reply. Yes there are separate data structs, config structs and read write lookaheqd buffers. The buffers are permanently allocated. When debugging, the block counts mismatch but they are not random values, they are from one of the other partitions. Debugging all the flash - and there aren’t many accesses in the mount (fail) format process you can see all the addresses being written to and the number of bytes. Only two blocks are accessed in each partition and they are megabytes apart. I’ve also noticed that if I start that partitions num blocks+1 apart instead of num blocks it also works. So if partition 0 is 2000 blocks in size (I presume you index that as 0-1999), partition 1 starts at block 2000. That fails. If partition 1 starts at block 2001 then it seems to work.

geky commented 5 months ago

So the issue is the flash contains the wrong block_size in the superblock?

Are you able to check that the flash has different contents on those two blocks outside of littlefs after lfs_format?

Is lfs_format being called with the right lfs_config struct for each filesystem?

Is it possible the block device layer is not adjusting the block addresses correctly for the new block_size, and is somehow overflowing and picking up the wrong superblock?

evaneight commented 5 months ago

Don’t know. I will look further, but I assume so as I have logged all writes to blocks. Absolutely 100% different lfs_t’s and lfs_config’s to each filesystem. I guess so, I find it hard it believe issue is with little_fs which I (and 000s of others) have used for years, although not exactly like this this. Thanks.