Description
After a file is successfully opened and written, if the SD card fails (for example, the card is removed), subsequent operations may behave incorrectly.
A simplified example:
file = lfs_open(); // ok
lfs_write(file, "something 1"); // ok
// now remove sd card, so lfs->cfg->read() returns a negative error code
lfs_write(file, "something 2"); // failed
error_code = lfs_read(file, buffer); // return code is "OK", but data is invalid
In this scenario:
- lfs_write("something 2") correctly returns an error
- However, lfs_read() returns success, but the returned data is invalid
This appears to be caused by rcache containing stale/invalid data.
Root Cause Analysis
lfs_write(file, "something 2") calls:
lfs_file_flushedwrite()
→ lfs_ctz_find()
→ lfs_bd_read()
Inside lfs_bd_read():
rcache->block = block;
rcache->off = lfs_aligndown(off, lfs->cfg->read_size);
rcache->size = lfs_min(
lfs_min(
lfs_alignup(off+hint, lfs->cfg->read_size),
lfs->cfg->block_size)
- rcache->off,
lfs->cfg->cache_size);
int err = lfs->cfg->read(lfs->cfg, rcache->block,
rcache->off, rcache->buffer, rcache->size);
LFS_ASSERT(err <= 0);
if (err) {
return err;
}
If lfs->cfg->read() returns an error:
- rcache->block, rcache->off, and rcache->size are already updated
- rcache->buffer still contains invalid / partial data
- The cache is not cleared
Later, lfs_read() may use this invalid rcache data and return incorrect content.
Proposed Fix
Would the following change be appropriate?
if (err) {
lfs_cache_drop(lfs, rcache);
return err;
}
This ensures that invalid cache data is not reused after a failed read.
Question
Is this the correct fix, or is there a reason why rcache should remain unchanged on read failure?
Description
After a file is successfully opened and written, if the SD card fails (for example, the card is removed), subsequent operations may behave incorrectly.
A simplified example:
In this scenario:
This appears to be caused by rcache containing stale/invalid data.
Root Cause Analysis
lfs_write(file, "something 2") calls:
Inside lfs_bd_read():
If
lfs->cfg->read()returns an error:Later, lfs_read() may use this invalid rcache data and return incorrect content.
Proposed Fix
Would the following change be appropriate?
This ensures that invalid cache data is not reused after a failed read.
Question
Is this the correct fix, or is there a reason why rcache should remain unchanged on read failure?