diff --git a/emubd/lfs_emubd.c b/emubd/lfs_emubd.c index ca2b6b9..b87d6de 100644 --- a/emubd/lfs_emubd.c +++ b/emubd/lfs_emubd.c @@ -138,8 +138,8 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block, snprintf(emu->child, LFS_NAME_MAX, "%x", block); FILE *f = fopen(emu->path, "r+b"); - if (!f && errno != ENOENT) { - return -errno; + if (!f) { + return (errno == EACCES) ? 0 : -errno; } // Check that file was erased @@ -189,14 +189,14 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) { return -errno; } - if (!err && S_ISREG(st.st_mode)) { + if (!err && S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode)) { int err = unlink(emu->path); if (err) { return -errno; } } - if (err || S_ISREG(st.st_mode)) { + if (errno == ENOENT || (S_ISREG(st.st_mode) && (S_IWUSR & st.st_mode))) { FILE *f = fopen(emu->path, "w"); if (!f) { return -errno; diff --git a/lfs.c b/lfs.c index b043bd9..d757ffb 100644 --- a/lfs.c +++ b/lfs.c @@ -531,18 +531,19 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir, } // successful commit, check checksum to make sure - crc = 0xffffffff; + uint32_t ncrc = 0xffffffff; err = lfs_bd_crc(lfs, dir->pair[0], 0, - 0x7fffffff & dir->d.size, &crc); + (0x7fffffff & dir->d.size)-4, &ncrc); if (err) { return err; } - if (crc == 0) { - break; + if (ncrc != crc) { + goto relocate; } } + break; relocate: //commit was corrupted LFS_DEBUG("Bad block at %d", dir->pair[0]); diff --git a/tests/test_corrupt.sh b/tests/test_corrupt.sh index d79a8c8..44f1cae 100755 --- a/tests/test_corrupt.sh +++ b/tests/test_corrupt.sh @@ -82,6 +82,17 @@ do lfs_chktree done +echo "--- Block persistance ---" +for i in {0..33} +do + rm -rf blocks + mkdir blocks + lfs_mktree + chmod a-w blocks/$(printf '%x' $i) + lfs_mktree + lfs_chktree +done + echo "--- Big region corruption ---" rm -rf blocks mkdir blocks