littlefs icon indicating copy to clipboard operation
littlefs copied to clipboard

lfs_file_seek hangs.

Open muratdemirtas opened this issue 2 years ago • 11 comments

Hello,

I'm trying to implement littlefs on ESP32 with 16Gb sd card over SDSPI interface. I have faced an issue that causes hangs. I do not know why but i want to understand. The file is sqlite3 db file which one we using our embedded system.

I have flashed my sd card with these commands with little-fs fuse. I'm using latest version 2.5.0 of littlefs both embedded and little-fs fuse.

sudo ./lfs --read_size=512 --prog_size=512 --block_size=512 --block_count=19000 --cache_size=512 --lookahead_size=128 --format /dev/sdb sudo ./lfs --read_size=512 --prog_size=512 --block_size=512 --block_count=19000 --cache_size=512 --lookahead_size=128 /dev/sdb mount sudo cp /home/murat/Desktop/deneme.db mount/JanStore.db sudo umount mount

my littlefs configuration in esp32 is

  struct lfs_config config = {0};
	config.context = sd_storage;

	// block device operations
	config.read = littlefs_api_read;
	config.prog = littlefs_api_prog;
	config.erase = littlefs_api_erase;
	config.sync = littlefs_api_sync;

	// block device configuration
	config.read_size = 512;
	config.prog_size = 512;
	config.block_size = 512;
	config.block_count = 19000;//conf->sd_card->csd.capacity;
	config.cache_size = 512;;
	config.lookahead_size = 128;
	config.block_cycles = 512;;
}

my JanStore.db file is 2958336 bytes. I'm using that for insert/update operations in sql. It works perfects for small file sizes. But when my database file size is grown lfs_file_seek functions causing hangs until current file position reach to end of file.

static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file)

The function is calling by lfs_file_seek which responsible for unnecessary loop.

        while (file->pos < file->ctz.size) {
            // copy over a byte at a time, leave it up to caching
            // to make this efficient
            uint8_t data;
            lfs_ssize_t res = lfs_file_flushedread(lfs, &orig, &data, 1);
            if (res < 0) {
			
                return res;
            }
            res = lfs_file_flushedwrite(lfs, file, &data, 1);
            if (res < 0) {
                return res;
            }

            // keep our reference to the rcache in sync
            if (lfs->rcache.block != LFS_BLOCK_NULL) {
                lfs_cache_drop(lfs, &orig.cache);
                lfs_cache_drop(lfs, &lfs->rcache);
            }
        }

[02:52:10:236] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffdcaa0, 802304, 0)␍␊ [02:52:10:236] ./main/bab.module.littlefs/littlefs/lfs.c:5604:trace: lfs_file_seek -> 802304␍␊ [02:52:10:236] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:280] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:323] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:323] esp32_Read: 3r /littlefs/JanStore.db 512 512 OK␍␊ [02:52:10:323] esp32_Read: 1r /littlefs/JanStore.db 512 801792[801792] ␍␊ [02:52:10:323] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffdcaa0, 801792, 0)␍␊ [02:52:10:323] ./main/bab.module.littlefs/littlefs/lfs.c:5604:trace: lfs_file_seek -> 801792␍␊ [02:52:10:323] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:389] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdcaa0, 0x3ffdce3c, 128)␍␊ [02:52:10:432] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:10:432] esp32_Read: 3r /littlefs/JanStore.db 512 512 OK␍␊ [02:52:10:518] esp32_Write: 1w /littlefs/JanStore.db 512 801792[801792] ␍␊ [02:52:10:566] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffdcaa0, 801792, 0)␍␊ [02:52:10:566] ./main/bab.module.littlefs/littlefs/lfs.c:5604:trace: lfs_file_seek -> 801792␍␊ [02:52:10:566] ./main/bab.module.littlefs/littlefs/lfs.c:5581:trace: lfs_file_write(0x3ffc98f8, 0x3ffdcaa0, 0x3ffe2c20, 512)␍␊ [02:52:13:423] ./main/bab.module.littlefs/littlefs/lfs.c:5586:trace: lfs_file_write -> 512␍␊ [02:52:13:423] esp32_Write: 3w /littlefs/JanStore.db OK␍␊ [02:52:13:423] esp32_Read: 1r /littlefs/JanStore.db 512 807424[807424] ␍␊ [02:52:13:423] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffdcaa0, 807424, 0)␍␊ [02:52:13:423] file pos : 802304 file ctz size: 2958336␍␊ [02:52:13:423] file pos : 802305 file ctz size:2958336␍␊ [02:52:13:423] file pos : 802306 file ctz size:2958336␍␊

lfs_file_seek call lfs_file_flush and this flush functions flushing the one byte(prog size is 512 but tries to write one byte??) to the sd card while reaching the current file size. This causes the biggest and most unacceptable timeout.

I have not faced this issue with reading operations. This problem becomes after one write operation. I double-checked the file open flags, sdspi read/write checksum, memory leak, etc. but no luck. I have not modified the littlefs source codes.

There is no problem when creating 3mb text file with append mode. Because in append mode file->pos == file->ctz.size

I created a new and empty db file using littlefs over esp32 itself. We insert new users into the SQLite file but after every SQL insert operation (writing to sd card over littlefs) the insert time becomes unacceptable.

Because flush size is growing also.

         while (file->pos < file->ctz.size) {
            // copy over a byte at a time, leave it up to caching
            // to make this efficient
            uint8_t data;
            lfs_ssize_t res = lfs_file_flushedread(lfs, &orig, &data, 1);
            if (res < 0) {
			
                return res;
            }
            res = lfs_file_flushedwrite(lfs, file, &data, 1);
            if (res < 0) {
                return res;
            }

There is no problem to use this db file with FatFs. I believe my configuration or little-fs fuse configuration is wrong. I hope.

What can be a problem?. Thanks

And I have a different issue. I have set the minimum read size to sd card block size (512 bytes). But little-fs tries to read one sector(512 bytes) in 4 steps using 128 bytes read.

[02:52:07:666] esp32_Read: 1r /littlefs/JanStore.db 512 7168[7168] ␍␊ [02:52:07:666] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffdb98c, 7168, 0)␍␊ [02:52:07:666] ./main/bab.module.littlefs/littlefs/lfs.c:5604:trace: lfs_file_seek -> 7168␍␊ [02:52:07:666] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdb98c, 0x3ffdecec, 128)␍␊ [02:52:07:794] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:07:837] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdb98c, 0x3ffdecec, 128)␍␊ [02:52:07:837] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:07:837] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdb98c, 0x3ffdecec, 128)␍␊ [02:52:07:837] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:07:837] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffdb98c, 0x3ffdecec, 128)␍␊ [02:52:08:013] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [02:52:08:013] esp32_Read: 3r /littlefs/JanStore.db 512 512 OK␍␊

this is the log of the littlefs mount sequence on embedded system.

[04:01:41:078] Name: SD␍␊ [04:01:41:078] Type: SDHC/SDXC␍␊ [04:01:41:078] Speed: 40 MHz␍␊ [04:01:41:078] Size: 14922MB␍␊ [04:01:41:078] SD MCC init ok␍␊ [04:01:41:078] <0x1b>[0;32mI (00:00:00.775) Factory JAN V2.3: Initializing LittleFS<0x1b>[0m␍␊ [04:01:41:078] <0x1b>[0;32mI (00:00:00.776) esp_littlefs: -----------LittleFS Configuration-----------<0x1b>[0m␍␊ [04:01:41:078] <0x1b>[0;32mI (00:00:00.784) esp_littlefs: SIZE: READ 512 WRITE 512 ,BLOCK 512 BLOCK COUNT 19000<0x1b>[0m␍␊ [04:01:41:078] <0x1b>[0;32mI (00:00:00.792) esp_littlefs: SIZE: CACHE 512 LOOK 128 ,BLOCK CYCLES 512<0x1b>[0m␍␊ [04:01:41:078] <0x1b>[0;32mI (00:00:00.800) esp_littlefs: -----------LittleFS Configuration-----------<0x1b>[0m␍␊ [04:01:41:121] ./main/bab.module.littlefs/littlefs/lfs.c:5367:trace: lfs_mount(0x3ffc98f8, 0x3ffc9844 {.context=0x3ffc97c4, .read=0x400f2e54, .prog=0x400f2ed0, .erase=0x401c898c, .sync=0x401c8994, .read_size=512, .prog_size=512, .block_size=512, .block_count=19000, .block_cycles=512, .cache_size=512, .lookahead_size=128, .read_buffer=0x0, .prog_buffer=0x0, .lookahead_buffer=0x0, .name_max=0, .file_max=0, .attr_max=0})␍␊ [04:01:41:121] ./main/bab.module.littlefs/littlefs/lfs.c:5371:trace: lfs_mount -> 0␍␊ [04:01:41:121] ok 3␍␊ [04:01:41:121] <0x1b>[0;32mI (00:00:00.850) esp_littlefs: Successfully registered LittleFS to "/littlefs"<0x1b>[0m␍␊ [04:01:41:166] <0x1b>[0;32mI (00:00:00.857) Factory JAN V2.3: initialized LittleFS<0x1b>[0m␍␊ [04:01:41:166] <0x1b>[0;31mE (00:00:00.863) TAG: Initializing Virtual Sqlite Filesystem<0x1b>[0m␍␊ [04:01:41:166] <0x1b>[0;31mE (00:00:00.870) TAG: Initializing Sqlite<0x1b>[0m␍␊ [04:01:41:166] <0x1b>[0;31mE (00:00:00.875) TAG: Initializing Sqlite Done<0x1b>[0m␍␊ [04:01:41:166] ./main/bab.module.littlefs/littlefs/lfs.c:5427:trace: lfs_stat(0x3ffc98f8, "/JanStore.db", 0x3ffba524)␍␊ [04:01:41:166] ./main/bab.module.littlefs/littlefs/lfs.c:5431:trace: lfs_stat -> 0␍␊ [04:01:41:207] ./main/bab.module.littlefs/littlefs/lfs.c:5443:trace: lfs_getattr(0x3ffc98f8, "/JanStore.db", 116, 0x3ffba4ec, 4)␍␊ [04:01:41:207] ./main/bab.module.littlefs/littlefs/lfs.c:5447:trace: lfs_getattr -> -61␍␊ [04:01:41:207] <0x1b>[0;32mI (00:00:00.911) esp_littlefs: Failed to get mtime attribute LFS_ERR_NOATTR (-61)<0x1b>[0m␍␊ [04:01:41:207] <0x1b>[0;33mW (00:00:00.919) TAG: /littlefs/JanStore.db is available<0x1b>[0m␍␊ [04:01:41:207] <0x1b>[0;33mW (00:00:00.925) -: DB before open:1000423 <0x1b>[0m␍␊ [04:01:41:207] esp32_FullPathname: /littlefs/JanStore.db␍␊ [04:01:41:207] esp32_Open: 0o /littlefs/JanStore.db r␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5427:trace: lfs_stat(0x3ffc98f8, "/JanStore.db", 0x3ffba364)␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5431:trace: lfs_stat -> 0␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5443:trace: lfs_getattr(0x3ffc98f8, "/JanStore.db", 116, 0x3ffba32c, 4)␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5447:trace: lfs_getattr -> -61␍␊ [04:01:41:250] <0x1b>[0;32mI (00:00:00.969) esp_littlefs: Failed to get mtime attribute LFS_ERR_NOATTR (-61)<0x1b>[04:01:41:207] <0x1b>[0;33mW (00:00:00.919) TAG: /littlefs/JanStore.db is available<0x1b>[0m␍␊ [04:01:41:207] <0x1b>[0;33mW (00:00:00.925) -: DB before open:1000423 <0x1b>[0m␍␊ [04:01:41:207] esp32_FullPathname: /littlefs/JanStore.db␍␊ [04:01:41:207] esp32_Open: 0o /littlefs/JanStore.db r␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5427:trace: lfs_stat(0x3ffc98f8, "/JanStore.db", 0x3ffba364)␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5431:trace: lfs_stat -> 0␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5443:trace: lfs_getattr(0x3ffc98f8, "/JanStore.db", 116, 0x3ffba32c, 4)␍␊ [04:01:41:250] ./main/bab.module.littlefs/littlefs/lfs.c:5447:trace: lfs_getattr -> -61␍␊ [04:01:41:250] <0x1b>[0;32mI (00:00:00.969) esp_littlefs: Failed to get mtime attribute LFS_ERR_NOATTR (-61)<0x1b>[0m␍␊ [04:01:41:250] esp32_Access: /littlefs/JanStore.db 1 0 2793472␍␊ [04:01:41:293] esp32_Open: 1o /littlefs/JanStore.db r+␍␊ [04:01:41:293] char /littlefs/JanStore.db, r+␍␊ [04:01:41:293] <0x1b>[0;32mI (00:00:00.987) esp_littlefs: Opening /JanStore.db<0x1b>[0m␍␊ [04:01:41:293] <0x1b>[0;32mI (00:00:00.993) esp_littlefs: O_RDWR<0x1b>[0m␍␊ [04:01:41:293] ./main/bab.module.littlefs/littlefs/lfs.c:5493:trace: lfs_file_open(0x3ffc98f8, 0x3ffca340, "/JanStore.db", 3)␍␊ [04:01:41:293] ./main/bab.module.littlefs/littlefs/lfs.c:5498:trace: lfs_file_open -> 0␍␊ [04:01:41:293] ./main/bab.module.littlefs/littlefs/lfs.c:5545:trace: lfs_file_sync(0x3ffc98f8, 0x3ffca340)␍␊ [04:01:41:336] ./main/bab.module.littlefs/littlefs/lfs.c:5550:trace: lfs_file_sync -> 0␍␊ [04:01:41:336] ./main/bab.module.littlefs/littlefs/lfs.c:5460:trace: lfs_setattr(0x3ffc98f8, "/JanStore.db", 116, 0x3ffba45c, 4)␍␊ [04:01:41:336] ./main/bab.module.littlefs/littlefs/lfs.c:5464:trace: lfs_setattr -> 0␍␊ [04:01:41:336] <0x1b>[0;32mI (00:00:01.048) esp_littlefs: Done opening /JanStore.db<0x1b>[0m␍␊ [04:01:41:336] esp32_Open: 2o /littlefs/JanStore.db OK␍␊ [04:01:41:379] esp32_Read: 1r /littlefs/JanStore.db 100 0[0] ␍␊ [04:01:41:379] ./main/bab.module.littlefs/littlefs/lfs.c:5427:trace: lfs_stat(0x3ffc98f8, "/JanStore.db", 0x3ffba2d4)␍␊ [04:01:41:379] ./main/bab.module.littlefs/littlefs/lfs.c:5431:trace: lfs_stat -> 0␍␊ [04:01:41:379] ./main/bab.module.littlefs/littlefs/lfs.c:5443:trace: lfs_getattr(0x3ffc98f8, "/JanStore.db", 116, 0x3ffba29c, 4)␍␊ [04:01:41:379] ./main/bab.module.littlefs/littlefs/lfs.c:5447:trace: lfs_getattr -> 4␍␊ [04:01:41:379] ./main/bab.module.littlefs/littlefs/lfs.c:5599:trace: lfs_file_seek(0x3ffc98f8, 0x3ffca340, 0, 0)␍␊ [04:01:41:422] ./main/bab.module.littlefs/littlefs/lfs.c:5604:trace: lfs_file_seek -> 0␍␊ [04:01:41:422] ./main/bab.module.littlefs/littlefs/lfs.c:5563:trace: lfs_file_read(0x3ffc98f8, 0x3ffca340, 0x3ffcaef8, 128)␍␊ [04:01:41:422] ./main/bab.module.littlefs/littlefs/lfs.c:5568:trace: lfs_file_read -> 128␍␊ [04:01:41:422] esp32_Read: 3r /littlefs/JanStore.db 100 100 OK␍␊ [04:01:41:422] <0x1b>[0;33mW (00:00:01.142) -: DB after open:988215 <0x1b>[0m␍␊ [04:01:41:422] <0x1b>[0;33mW (00:00:01.146) SQLite3DataProvider: Database init successful<0x1b>[0m␍␊

muratdemirtas avatar Jul 18 '22 00:07 muratdemirtas

@ #591 #701

muratdemirtas avatar Jul 18 '22 00:07 muratdemirtas

How big is the file? I have found that as the file size grows, lfs can take a very long time to seek to the end of the file.

sslupsky avatar Jul 18 '22 19:07 sslupsky

How big is the file? I have found that as the file size grows, lfs can take a very long time to seek to the end of the file.

JanStore.db file is 2958336 bytes, 3MB

and i want to write a 100 byte.

muratdemirtas avatar Jul 18 '22 19:07 muratdemirtas

If you are using sqlite, you aren't just appending 100 bytes to the end of your database file. You could be relocating several blocks just for inserting a single record.

hagibr avatar Jul 18 '22 19:07 hagibr

If you are using sqlite, you aren't just appending 100 bytes to the end of your database file. You could be relocating several blocks just for inserting a single record.

is this littlefs library suitable for work with sql files?

in every insert single record, the file size grows, and littlefs flush the bytes from the current position to end of file position. Is this expected?

if it is normal, i will use fatfs without power resilience :(

muratdemirtas avatar Jul 18 '22 19:07 muratdemirtas

JanStore.db file is 2958336 bytes, 3MB

and i want to write a 100 byte.

I believe that is a big file size for littlefs. Are you using serial flash? Opening the file and seeking the end of file could take several minutes. I think I read in another thread where someone mentioned the time it took to append data to a 59MB log file was about 23 minutes. I think once the file is opened and the seek is done, subsequent writes append the data quickly. So, for the append use case I think it is best that you open the file and leave it open and keep writing to the file.

is this littlefs library suitable for work with sql files?

I am not certain but I think for a large db, you would have to be prepared for worst case which would be similar to seeking the end of file each time.

sslupsky avatar Jul 18 '22 20:07 sslupsky

JanStore.db file is 2958336 bytes, 3MB and i want to write a 100 byte.

I believe that is a big file size for littlefs. Are you using serial flash? Opening the file and seeking the end of file could take several minutes. I think I read in another thread where someone mentioned the time it took to append data to a 59MB log file was about 23 minutes. I think once the file is opened and the seek is done, subsequent writes append the data quickly. So, for the append use case I think it is best that you open the file and leave it open and keep writing to the file.

is this littlefs library suitable for work with sql files?

I am not certain but I think for a large db, you would have to be prepared for worst case which would be similar to seeking the end of file each time.

thanks a lot of. I'm using 16GB Type: SDHC/SDXC␍ sd card. I decided to stay with FatFS. Because FatFS is doesnt do that.

muratdemirtas avatar Jul 18 '22 22:07 muratdemirtas

I believe the journaling nature of the file system causes this behaviour. It provides the power resilience that FAT does not have but there is a significant performance cost.

sslupsky avatar Jul 18 '22 22:07 sslupsky

I believe the journaling nature of the file system causes this behaviour. It provides the power resilience that FAT does not have but there is a significant performance cost.

Looks like I have to design the hardware systems which detects a power loss and provide 3-4 seconds to supply esp32 voltage before brownout.

I have used littlefs before for my old client to append log data into a single text file for 8Mbit(1MB) spi nor flash. There was no problem like that.

But currently... It is not possible.

muratdemirtas avatar Jul 18 '22 22:07 muratdemirtas

Same comment as in #701, if your minimum read size is the same as your block size, all file system traversals will read every single file in its entirety.

You may want to increase --block_size=512 to 4k, 32k, or even bigger, depending on your requirements.

On mount or any traversal, read size * block count is the amount of bytes that will be read when the filesystem is full!

kaetemi avatar Jul 19 '22 16:07 kaetemi

You may want to increase --block_size=512 to 4k, 32k, or even bigger, depending on your requirements.

On mount or any traversal, read size * block count is the amount of bytes that will be read when the filesystem is full!

SD cards use nand flash memory which have erase block sizes reaching into the MB's. So, the OP's block erase size is likely much larger than 512 bytes. However, it does not appear this parameter is well documented for SD cards. I looked up the block size for a 16GB SD card I have plugged into a RPI that shows a block erase size of 4MB.

@muratdemirtas I would be interest to know how much of an improvement you see by using the actual erase block size of the sd card.

sslupsky avatar Jul 19 '22 17:07 sslupsky

@sslupsky So, for the append use case I think it is best that you open the file and leave it open and keep writing to the file.

But if you cut power, wouldn't you loose complete file?

klemdev avatar Nov 24 '22 20:11 klemdev

I believe the journaling nature of the file system causes this behaviour. It provides the power resilience that FAT does not have but there is a significant performance cost.

Just to clarify this isn't an inherent issue with journaling, it happens because of a poor design choice in in the file data-structure. Something more B-tree like can avoid this, with some complexity trade-offs. I have some plans to address this but the implementation will take some time.

The first issue for this was here: https://github.com/littlefs-project/littlefs/issues/27 (commenting for tracking purposes)

On mount or any traversal, read size * block count is the amount of bytes that will be read when the filesystem is full!

Maybe interesting to note this will also be improved with B-trees. They move the tree metadata out of the data blocks, so even with a large read_size you only need to read the inner nodes of the tree to traverse.

So, for the append use case I think it is best that you open the file and leave it open and keep writing to the file.

If you append, no matter how you append, it will be orders of magnitude faster than random writes. If you're seeing performance issues with appends that may be worth a different issue.

But if you cut power, wouldn't you loose complete file?

Calling lfs_file_sync at good checkpoints will avoid this, but it does have a cost with needing to copy the last block due to padding issues.


Also sorry for inconsistent replies to open issues.

geky avatar Dec 02 '22 17:12 geky