littlefs-project / littlefs

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

Filesystem gets corrupted with block sizes >512 #737

Closed fwolter closed 8 months ago

fwolter commented 2 years ago

My filesytem gets corrupted (error 25), when I set block_size larger than 512 and a sector beyond 512 sectors is written. To rule out a bug in my bdio functions, I added an offset of 512 sectors in each function resulting in using sectors 513-1024 of my flash. That do work without any corruption.

The application runs on a PIC32MZW1 with a SST26 flash (sector size 4096, entire size 4MB).

Does anybody have an idea what could be wrong?

Here is my configuration:

#define     LFS_READ_SIZE   1
#define     LFS_PROG_SIZE   1
#define     LFS_BLOCK_SIZE   4096
#define     LFS_BLOCK_COUNT   512 // values >512 corrupt the filesystem
#define     LFS_BLOCK_CYCLES   1000
#define     LFS_CACHE_SIZE   256
#define     LFS_LOOKAHEAD_SIZE   4096/8

uint8_t ReadBuf[LFS_CACHE_SIZE] = {0};
uint8_t ProgBuf[LFS_CACHE_SIZE] = {0};
uint8_t __attribute__((aligned(4))) LookaheadBuf[LFS_LOOKAHEAD_SIZE] = {0};

static const struct lfs_config cfg = {
        .context        = 0,
        .read           = myRead,
        .prog           = myProg,
        .erase          = myErase,
        .sync           = mySync,
        .read_size      = LFS_READ_SIZE,
        .prog_size      = LFS_PROG_SIZE,
        .block_size     = LFS_BLOCK_SIZE,
        .block_count    = LFS_BLOCK_COUNT,
        .block_cycles   = LFS_BLOCK_CYCLES,
        .cache_size     = LFS_CACHE_SIZE,
        .lookahead_size = LFS_LOOKAHEAD_SIZE,
        .read_buffer    = ReadBuf,
        .prog_buffer    = ProgBuf,
        .lookahead_buffer = LookaheadBuf,
    };
rapp70 commented 8 months ago

This is indeed a definite problem. See issue #938. My test harness fails (so far) with any block size other than 512, my device can have 4096 blocks. Thanks for highlighting this.

geky commented 8 months ago

@rapp70, do you have any hints for @fwolter since https://github.com/littlefs-project/littlefs/issues/938 was solvable?

Sorry I don't have much else to add.

One thing that could cause this is if the block address is truncated at some point. If you need a different flash command to write with block addresses >512 for example.

geky commented 8 months ago
uint8_t __attribute__((aligned(4))) LookaheadBuf[LFS_LOOKAHEAD_SIZE] = {0};

As of v2.9 you don't need this alignment anymore, just FYI.

geky commented 8 months ago

I added an offset of 512 sectors in each function resulting in using sectors 513-1024 of my flash. That do work without any corruption.

If the address is truncated, these may map to 0-512 without you noticing. Trying to write to 0 and 512 simultaneously may lead somewhere.

Also try writing to the last block, littlefs chooses a random block to start after the superblocks, so it may be really far beyond the 1024 block range.

There are some additional block-device specific tests here that may be interesting to try: https://github.com/littlefs-project/littlefs/blob/master/tests/test_bd.toml

fwolter commented 8 months ago

That's a bit embarrassing. When looking at it with some distance after so long time, I noticed that I populated only the 2MB version of the flash, which of course just has 512 pages... Sorry for the trouble and thanks for raising this up again! I'm so glad this is resolved now and there is no bug in the underlying framework code for accessing the flash or LittleFS or, of course my code.