Little FS "No more free space" on Large Flash

Hello,
I am working on an application where large amount of data are being stored onto a NOR flash. The flash is a W25Q02JV with 2Gb of storage, running little FS. My application works as expected filling a little over half of the flash with data, but runs into issues afterwards. The FS write calls take very long and errors out with little_fs claiming there is no more free space. There is still however 32,769 blocks remaining. I am using the default settings for little_fs parameters. Could I be making some better choices here? I've included some of my debug logs from both startup and runtime. Thank you for any help.

During startup:
...
00> [00:00:01.031,005] <inf> StorageLib: Enter Setup Little FS
00> [00:00:01.031,036] <inf> StorageLib: Area 1 at 0x0 on w25q02jv@0 for 268435456 bytes
00> [00:00:01.031,066] <inf> littlefs: LittleFS version 2.5, disk version 2.0
00> [00:00:01.092,742] <inf> littlefs: FS at w25q02jv@0:0x0 is 65536 0x1000-byte blocks with 512 cycle
00> [00:00:01.092,742] <inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32
00> [00:00:01.248,077] <inf> StorageLib: Filesystem mounted at /lfs
00> [00:00:02.980,407] <inf> StorageLib: /lfs: bsize = 16 ; frsize = 4096 ; blocks = 65536 ; bfree = 32770
00> [00:00:03.130,615] <inf> StorageLib: Attempting to open directory: /lfs
00> [00:00:03.134,704] <inf> StorageLib: Listing directory /lfs ...
00> [00:01:00.086,242] <inf> StorageLib: [FILE] 12F5C425CAA9-669A57.DAT (size = 210248)
00> [00:01:00.188,659] <inf> StorageLib: [FILE] 12F5C425CAA9-669A58.DAT (size = 211314)
00> [00:01:00.291,015] <inf> StorageLib: [FILE] 12F5C425CAA9-669A59.DAT (size = 210002)
00> [00:01:00.393,127] <inf> StorageLib: [FILE] 12F5C425CAA9-669A5A.DAT (size = 210658)
00> [00:01:00.495,147] <inf> StorageLib: [FILE] 12F5C425CAA9-669A5B.DAT (size = 211314)
00> [00:01:00.596,923] <inf> StorageLib: [FILE] 12F5C425CAA9-669A5C.DAT (size = 210412)
...
During runtime:
...
00> [00:01:27.008,605] <inf> System: --- Device started and collecting data ---
00> [00:01:42.999,938] <inf> StorageLib: Opening file: /lfs/12F5C425CAA9-669E78.DAT
00> [00:01:45.201,293] <inf> StorageLib: Header written to file: /lfs/12F5C425CAA9-669E78.DAT
00> [00:14:36.135,070] <err> littlefs: WEST_TOPDIR/modules/fs/littlefs/lfs.c:589: No more free space 32769
00> [00:14:36.135,192] <err> fs: file write error (-28)
00> [00:14:36.136,383] <err> StorageLib: Failed to write sample 100 to file /lfs/12F5C425CAA9-669E78.DAT: -28

Parents
  • Hi,

    Can you check which parameter is tested when littlefs decides that it is out of space, in the library code?

    Regards,
    Sigurd Hellesvik

  • It is failing inside of lfs.c on check of free.ack == 0, here is the code from lfsc:

    static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
        while (true) {
            while (lfs->free.i != lfs->free.size) {
                lfs_block_t off = lfs->free.i;
                lfs->free.i += 1;
                lfs->free.ack -= 1;
    
                if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
                    // found a free block
                    *block = (lfs->free.off + off) % lfs->cfg->block_count;
    
                    // eagerly find next off so an alloc ack can
                    // discredit old lookahead blocks
                    while (lfs->free.i != lfs->free.size &&
                            (lfs->free.buffer[lfs->free.i / 32]
                                & (1U << (lfs->free.i % 32)))) {
                        lfs->free.i += 1;
                        lfs->free.ack -= 1;
                    }
    
                    return 0;
                }
            }
    
            // check if we have looked at all blocks since last ack
            if (lfs->free.ack == 0) {
                LFS_ERROR("No more free space %"PRIu32,
                        lfs->free.i + lfs->free.off);
                return LFS_ERR_NOSPC;
            }
    ...


    If I understand correctly, I might be able to increase my lookahead size so that littlefs sepnds more time looking for the next free block? What littlefs parameters could be set to limit fragmentation?

    As a side note, restarting the device does regain functionality, but only a short while before getting the memory full error again.

    Thank you,
    Eric

Reply
  • It is failing inside of lfs.c on check of free.ack == 0, here is the code from lfsc:

    static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
        while (true) {
            while (lfs->free.i != lfs->free.size) {
                lfs_block_t off = lfs->free.i;
                lfs->free.i += 1;
                lfs->free.ack -= 1;
    
                if (!(lfs->free.buffer[off / 32] & (1U << (off % 32)))) {
                    // found a free block
                    *block = (lfs->free.off + off) % lfs->cfg->block_count;
    
                    // eagerly find next off so an alloc ack can
                    // discredit old lookahead blocks
                    while (lfs->free.i != lfs->free.size &&
                            (lfs->free.buffer[lfs->free.i / 32]
                                & (1U << (lfs->free.i % 32)))) {
                        lfs->free.i += 1;
                        lfs->free.ack -= 1;
                    }
    
                    return 0;
                }
            }
    
            // check if we have looked at all blocks since last ack
            if (lfs->free.ack == 0) {
                LFS_ERROR("No more free space %"PRIu32,
                        lfs->free.i + lfs->free.off);
                return LFS_ERR_NOSPC;
            }
    ...


    If I understand correctly, I might be able to increase my lookahead size so that littlefs sepnds more time looking for the next free block? What littlefs parameters could be set to limit fragmentation?

    As a side note, restarting the device does regain functionality, but only a short while before getting the memory full error again.

    Thank you,
    Eric

Children
No Data
Related