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

LittleFS not truncating previous file content when overwriting a file #945

Closed lrodorigo closed 4 months ago

lrodorigo commented 4 months ago

Hi, I am trying to use LittleFS (v 2.8.0) on MX25LM51245G Octo-SPI flash, with STM32U5 microcontroller. Everything seems to properly work, except for this strange behaviour.

When an existing file is opened, written and closed multiple times, it seems that the file is not truncated to the "latest" new size, and it is actually possible to read the previous content.

- open
- write 256 bytes of 0x01
- close

- open
- write 128 bytes of 0x02
- close

- read file size (128 bytes expected, but 256 bytes are returned)
- check file content (128 bytes of 0x02 expected, byte 128 bytes of 0x02 + 128 bytes of 0x01 are read) 

I also tried to perform a SEEK 0 just after opening the file, but nothing changes. The issue seems to be not present if file is opened with the LFS_O_TRUNC flag.

static lfs_t* get_lfs() {
    static lfs_t lfs_instance;
    return &lfs_instance;
}

void test() {
    static uint8_t buf[256];
    lfs_file_t lfs_file;
    size_t file_size = 0;

    assert(lfs_mount(get_lfs(), &lfs_cfg));

    // write 256 bytes
    ret = lfs_file_open(get_lfs(), &lfs_file, "my.txt",  LFS_O_RDWR | LFS_O_CREAT);
    assert(ret >= 0);
    memset(buf, 1, 256);
    lfs_file_write(get_lfs(), &lfs_file, buf, 256);
    lfs_file_close(get_lfs(), &lfs_file);

    // write 128 bytes
    ret = lfs_file_open(get_lfs(), &lfs_file, "my.txt",  LFS_O_RDWR | LFS_O_CREAT);
    assert(ret >= 0);
    memset(buf, 2, 128);
    lfs_file_write(get_lfs(), &lfs_file, buf, 128);
    lfs_file_close(get_lfs(), &lfs_file);

    // assert file size
    ret = lfs_file_open(get_lfs(), &lfs_file, "my.txt",  LFS_O_RDWR | LFS_O_CREAT);
    assert (ret == LFS_ERR_OK);

    file_size = lfs_file_size(get_lfs(), &lfs_file);
    // assert(file_size == 128); <--- this is failing, since returned file_size==256

    lfs_file_read(get_lfs(), &lfs_file, buf, 256); 
    lfs_file_close(get_lfs(), &lfs_file);

    // the content of the file is 128 bytes of "2" and then the old 128 bytes of "1" 
}

follows my current lfs_config struct:

    static struct lfs_config lfs_cfg =
    {
        .context = NULL,                  // not implemented
        .read = &ospi_read_lfs_block,     // read function
        .prog = &ospi_write_lfs_block,    // program function
        .erase = &ospi_erase_lfs_block,   // erase function
        .sync = &ospi_lfs_sync,           // sync function

        .read_size = 4,                   // minimum read size (Our Flash interface supports single byte reads)
        .prog_size = 4,                   // minimum program size (Our Flash interface supports 4 byte writes)

        .block_size  = 4096,                    // block_size - 4096 erase sectors
        .block_count = (16*1024*1024)/4096,     // block_count - number of sectors

        .block_cycles = 512,              // block_cycles - suggested value: 100 - 1000

        .cache_size   = 2048,             // cache_size - multiple of read and program block size
        .lookahead_size = 2048,           // lookahead_size (multiple of 8)

        // The following three buffer pointers, if set to NULL, a buffer will be malloc'ed, using the size provided
        .read_buffer = lfs_read_buffer,         // read_buffer
        .prog_buffer = lfs_write_buffer,        // prog_buffer
        .lookahead_buffer = lfs_lookahead_buffer,  // lookahead_buffer (if null, a buffer will be malloc'ed)

        .name_max = LFS_NAME_MAX,           // name_max
        .file_max = LFS_FILE_MAX,           // file_max
        .attr_max = LFS_ATTR_MAX,           // attr_max
    };
lrodorigo commented 4 months ago

Update: sorry for opening this. I noticed that is the standard linux behaviour and the "w" mode actually open with TRUNCATE flag. So everything is working properly.

Please close/delete this issue.

Sorry Many thanks