diff options
author | Christopher Haster <chaster@utexas.edu> | 2018-07-16 23:22:02 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2018-07-16 23:33:52 +0300 |
commit | 041e90a1ca7153e408bd2e9cea1f2157d8b0cb72 (patch) | |
tree | 58c5c65586a17bef9b4090961bf195f026855826 /lfs.c | |
parent | f94d233deb494bbe1cb5488d69539607d354b2ac (diff) |
Added handling for corrupt as initial state of blocksfix-corrupt-read
Before this, littlefs incorrectly assumed corrupt blocks were only the result
of our own modification. This would be fine for most cases of freshly
erased storage, but for storage with block-level ECC this wasn't always
true.
Fortunately, it's quite easy for littlefs to handle this case correctly,
as long as corrupt storage always reports that it is corrupt, which for
most forms of ECC is the case unless we perform a write on the storage.
found by rojer
Diffstat (limited to 'lfs.c')
-rw-r--r-- | lfs.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -417,11 +417,14 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) { // rather than clobbering one of the blocks we just pretend // the revision may be valid int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->d.rev, 4); - dir->d.rev = lfs_fromle32(dir->d.rev); - if (err) { + if (err && err != LFS_ERR_CORRUPT) { return err; } + if (err != LFS_ERR_CORRUPT) { + dir->d.rev = lfs_fromle32(dir->d.rev); + } + // set defaults dir->d.rev += 1; dir->d.size = sizeof(dir->d)+4; @@ -445,6 +448,9 @@ static int lfs_dir_fetch(lfs_t *lfs, int err = lfs_bd_read(lfs, tpair[i], 0, &test, sizeof(test)); lfs_dir_fromle32(&test); if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } return err; } @@ -464,6 +470,9 @@ static int lfs_dir_fetch(lfs_t *lfs, err = lfs_bd_crc(lfs, tpair[i], sizeof(test), (0x7fffffff & test.size) - sizeof(test), &crc); if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } return err; } |