littlefs-project / littlefs

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

issue when append data to a file #981

Closed stingdau1206 closed 1 month ago

stingdau1206 commented 1 month ago
    external_littlefs_init(W25Q128_spi_read, W25Q128_spi_write, W25Q128_spi_erase, W25Q128_spi_sync);
    printf("begin %d\n", external_littlefs_begin());

    lfs_file_t audio_file;
    memset(data, 'x', 64);
    file_open(&audio_file, "audio.mp3", LFS_O_CREAT | LFS_O_RDWR);
    file_write(&audio_file, data, 64);
    file_close(&audio_file);

    file_open(&audio_file, "audio.mp3", LFS_O_RDWR);
    file_read(&audio_file, buf, 64);
    printArray(buf, 64);
    file_close(&audio_file);

    memset(data, 'k', 64);
    file_open(&audio_file, "audio.mp3", LFS_O_CREAT | LFS_O_RDWR | LFS_O_APPEND);
    file_write(&audio_file, data, 64);
    file_close(&audio_file);

at first time i write to file, and after that i read from this file it ok log: value of buf array as hex 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78

finally i continue to push data to file at append, it have err (loop infinity)

littlefs/lfs.c:3292:debug: Bad block at 0xc86
littlefs/lfs.c:3292:debug: Bad block at 0xc87
littlefs/lfs.c:3292:debug: Bad block at 0xc88
littlefs/lfs.c:3292:debug: Bad block at 0xc89 ...

what happend and how can i fix it ?

stingdau1206 commented 1 month ago

the log is from this func

static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
    while (true) {
        // just relocate what exists into new block
        lfs_block_t nblock;
        int err = lfs_alloc(lfs, &nblock);
        if (err) {
            return err;
        }

        err = lfs_bd_erase(lfs, nblock);
        if (err) {
            if (err == LFS_ERR_CORRUPT) {
                goto relocate;
            }
            return err;
        }

        // either read from dirty cache or disk
        for (lfs_off_t i = 0; i < file->off; i++) {
            uint8_t data;
            if (file->flags & LFS_F_INLINE) {
                err = lfs_dir_getread(lfs, &file->m,
                        // note we evict inline files before they can be dirty
                        NULL, &file->cache, file->off-i,
                        LFS_MKTAG(0xfff, 0x1ff, 0),
                        LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0),
                        i, &data, 1);
                if (err) {
                    return err;
                }
            } else {
                err = lfs_bd_read(lfs,
                        &file->cache, &lfs->rcache, file->off-i,
                        file->block, i, &data, 1);
                if (err) {
                    return err;
                }
            }

            err = lfs_bd_prog(lfs,
                    &lfs->pcache, &lfs->rcache, true,
                    nblock, i, &data, 1);
            if (err) {
                if (err == LFS_ERR_CORRUPT) {
                    goto relocate;
                }
                return err;
            }
        }

        // copy over new state of file
        memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->cache_size);
        file->cache.block = lfs->pcache.block;
        file->cache.off = lfs->pcache.off;
        file->cache.size = lfs->pcache.size;
        lfs_cache_zero(lfs, &lfs->pcache);

        file->block = nblock;
        file->flags |= LFS_F_WRITING;
        return 0;

relocate:
        LFS_DEBUG("Bad block at 0x%"PRIx32, nblock); // at this line 

        // just clear cache and try a new block
        lfs_cache_drop(lfs, &lfs->pcache);
    }
}
stingdau1206 commented 1 month ago
    memset(&_lfs_cfg, 0, sizeof(_lfs_cfg));
    _lfs_cfg.read = external_read_func;
    _lfs_cfg.prog = external_write_func;
    _lfs_cfg.erase = external_erase_func;
    _lfs_cfg.sync = external_sync_func;
    _lfs_cfg.read_size = 64;
    _lfs_cfg.prog_size = 64;
    _lfs_cfg.block_size = 4096;
    _lfs_cfg.block_count = (16*256);
    _lfs_cfg.block_cycles = 100; // TODO - need better explanation
    _lfs_cfg.cache_size = 4096;
    _lfs_cfg.lookahead_size = 64;
    _lfs_cfg.read_buffer = NULL;
    _lfs_cfg.prog_buffer = NULL;
    _lfs_cfg.lookahead_buffer = NULL;
    _lfs_cfg.name_max = LFS_NAME_MAX;
    _lfs_cfg.file_max = LFS_FILE_MAX;
    _lfs_cfg.attr_max = LFS_ATTR_MAX;

my config

geky commented 1 week ago

Hi @stingdau1206, sorry about the late response.

Were you able to solve your issue? This looks like it may have been a misconfigured block device.

A quick note may help others who have the same issue and stumble on this from google.