Open justintconroy opened 2 years ago
A couple other observations which may or may not be relevant to this ticket. It might be appropriate to create additional issues for these:
seekg()
/seekp()
and tellg()
/tellp()
seem to both affect the same internal pointer. That is, if we change the input position, the output position is also changed. tellg()
and tellp()
always return the same value.I think you just need to call strm.sync()
. See:
I added a call to strm.sync()
immediately after the strm.flush()
in the above example. This made no difference in the outcome.
I also tried the case of moving the read after the write (and the call to sync()
), and that also is still failing.
are you seeking before reading? What kind of errors are you seeing?
Yes, I call strm.seekg(0)
just before attempting to read with strm.readsome(...)
. strm.rdstate()
returns 0 after every operation on the stream. strm.sync()
also returns 0. So, no errors.
@BrianPugh Any more insight on this issue?
the seekg
/seekp
/tellg
/tellp
issue is a limitation of upstream littlefs. As far as syncing to disk, no idea what could be causing your issues
Were you able to reproduce it with the code snippet I provided above?
I haven't had a chance to test this, i'll try to when i get a chance.
@BrianPugh Is this still on your radar? It would be nice if we can get this resolved. Let me know if there's anything I can do to help.
yeah sorry, been busy with the holidays and work. I'll try and reproduce it this weekend, but not sure if there will be any actionable items. It's PROBABLY an upstream issue, but i'll try and verify that its not something wrong with my port.
@BrianPugh I'm also interested in this topic. Any insight or pointers you can provide? Based on littlefs documentation, I wasn't expecting this behavior but I may be misunderstanding something.
Note that we were eventually able to work around this issue by using file pointers instead of streams. Using fflush
and fsync
works for persisting the files through reboots without first needing to close the file.
During extensive testing I recognized sometimes an fsync is not enough to have all data actually written. Because we are working with small blocks of data (64 bytes), I had to artificially flood the buffer when I really want to have all data written:
void LOG_QuickSync(bool bFloodBuffer)
{
if (logFileWriteHandle != NULL)
{
if (bFloodBuffer)
{
/* Fill Cache with enough data that definitely all events are written. */
static const uint8_t DataBufferFiller[CONFIG_LITTLEFS_WRITE_SIZE] = {0};
fwrite((void *) DataBufferFiller, sizeof(uint8_t), sizeof(DataBufferFiller), logFileWriteHandle);
ESP_LOGI(TAG, "Forced quick sync for up-to-date log done!");
}
fsync(fileno(logFileWriteHandle));
}
}
All tests with different littlefs configurations (changed PAGE, READ, WRITE, LOOKAHEAD and CACHE size) did not help. So I am posting this here that it might resolve the problem for others - or maybe someone comes up with a solution that the workaround is not needed.
I'm not sure if this is a problem with this project, or with littleFS itself, but I'm going to start here.
The main problem is that I have files open when resetting the device. When I try to open the files again after reboot, the files appear to be empty. It doesn't really matter how much data is written. As long as the file stream isn't closed, the data is lost. Doing the same set of steps with SPIFFS, the data is not lost.
Here's as minimal of a repro as I can get. Run this, then hit the reset on the ESP32. Expected behavior is that the first read would read what was written in the previous run. Actual behavior is that it prints nothing and reports a 0 byte file size.
If you uncomment
// strm.close();
at the end, or remove thevTaskDelay(...)
, this code works as expected.For what it's worth, my real-life use case here is for saving logs to the filesystem. Losing everything that was logged at every reset is no bueno. :-/