LittleFS unexpected behaviour · Issue #7426 · esp8266/Arduino (original) (raw)

Basic Infos

Platform

Settings in IDE

Problem Description

When working with big files on LittleFS, overwriting a big file might fail as LittleFS seems to release the previous file contents only after a sync (i.e. close) of that file as it uses a COW strategy (see littlefs-project/littlefs#123)

So if you have a 1MB FS and a file of 512KB you cannot overwrite that file with 512KB of data. This will fail since during that overwrite up to 1024KB need to be in that 1M FS which has less net space.

Remedy: you have to truncate the file by

This should be somehow documented in the docs. It would also be nice to have a call like
LittleFS.sync(); or another flag LittleFS.open(... "ws") to indicate that writing should be synced. The lower lfs_* calls seem to provide such functionality.

MCVE Sketch

#include <LittleFS.h> #define BAUDRATE 74880

uint16_t listDir(String indent, String path) { uint16_t dirCount = 0; Dir dir = LittleFS.openDir(path); while (dir.next()) { ++dirCount; if (dir.isDirectory()) { Serial.printf_P(PSTR("%s%s [Dir]\n"), indent.c_str(), dir.fileName().c_str()); dirCount += listDir(indent + " ", path + dir.fileName() + "/"); } else Serial.printf_P(PSTR("%s%-16s (%ld Bytes)\n"), indent.c_str(), dir.fileName().c_str(), (uint32_t)dir.fileSize()); } return dirCount; }

void create_file(String path, uint32_t fsize) { File f = LittleFS.open(path, "w"); char buf[536]; // whatever for (auto i = 0; i < fsize; ) { auto n = fsize - i; if (n > sizeof(buf)) n = sizeof(buf); auto nw = f.write(buf, n); if (nw != n) Serial.printf_P(PSTR("\n\nBug at position %u: expected %d written, got %d written...\n"), i, n, nw); i += nw; if (0 == nw) break; } f.close(); }

void setup(void) { Serial.begin(BAUDRATE); Serial.printf_P(PSTR("FS init: %s\n"), LittleFS.begin() ? PSTR("ok") : PSTR("fail!")); LittleFS.format();

listDir("", "/");

uint32_t maxL = 768 * 1024;

Serial.printf_P(PSTR("Create /a.bin with size %u..."), maxL); uint32_t startTime = millis(); create_file("/a.bin", maxL); Serial.printf_P(PSTR(" took %lu ms!\n"), millis() - startTime);

listDir("", "/");

maxL += 1024; Serial.printf_P(PSTR("Overwriting /a.bin with size %d..."), maxL);

startTime = millis(); create_file("/a.bin", maxL); Serial.printf_P(PSTR(" took %lu ms!\n"), millis() - startTime);

listDir("", "/"); }

void loop() {}

Debug Messages

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3456, room 16 
tail 0
chksum 0x84
csum 0x84
va5432625
~ld
FS init: ok
Create /a.bin with size 786432... took 15225 ms!
a.bin            (786432 Bytes)
Overwriting /a.bin with size 787456...

Bug at position 212792: expected 536 written, got 0 written...
 took 4063 ms!
a.bin            (786432 Bytes)