diff options
author | Christopher Haster <chaster@utexas.edu> | 2017-05-14 20:01:45 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2017-05-15 08:40:56 +0300 |
commit | fd1da602d77a812c15db8113960517ac99f5f6f7 (patch) | |
tree | d8a464fb4f92a564ef54832f5b4c2538e96ce62c /emubd | |
parent | b35d7611964d1470409269bf25e3499721dcbe7d (diff) |
Added support for handling corrupted blocks
This provides a limited form of wear leveling. While wear is
not actually balanced across blocks, the filesystem can recover
from corrupted blocks and extend the lifetime of a device nearly
as much as dynamic wear leveling.
For use-cases where wear is important, it would be better to use
a full form of dynamic wear-leveling at the block level. (or
consider a logging filesystem).
Corrupted block handling was simply added on top of the existing
logic in place for the filesystem, so it's a bit more noodly than
it may have to be, but it gets the work done.
Diffstat (limited to 'emubd')
-rw-r--r-- | emubd/lfs_emubd.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/emubd/lfs_emubd.c b/emubd/lfs_emubd.c index 6423cb4..6616b32 100644 --- a/emubd/lfs_emubd.c +++ b/emubd/lfs_emubd.c @@ -144,13 +144,24 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block, return -errno; } + err = fseek(f, off, SEEK_SET); + if (err) { + return -errno; + } + + uint8_t dat; + res = fread(&dat, 1, 1, f); + if (res < 1) { + return -errno; + } + err = fclose(f); if (err) { return -errno; } emu->stats.prog_count += 1; - return 0; + return (dat != data[0]) ? LFS_ERR_CORRUPT : 0; } int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) { |