forked from Imagelibrary/littlefs
Compare commits
3 Commits
fix-make-b
...
rbyd-devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d272bb62a | ||
|
|
44a196af42 | ||
|
|
1278ec1d08 |
74
lfs.c
74
lfs.c
@@ -300,14 +300,12 @@ static inline int lfs_pair_cmp(
|
|||||||
paira[0] == pairb[1] || paira[1] == pairb[0]);
|
paira[0] == pairb[1] || paira[1] == pairb[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
static inline bool lfs_pair_issync(
|
||||||
static inline bool lfs_pair_sync(
|
|
||||||
const lfs_block_t paira[2],
|
const lfs_block_t paira[2],
|
||||||
const lfs_block_t pairb[2]) {
|
const lfs_block_t pairb[2]) {
|
||||||
return (paira[0] == pairb[0] && paira[1] == pairb[1]) ||
|
return (paira[0] == pairb[0] && paira[1] == pairb[1]) ||
|
||||||
(paira[0] == pairb[1] && paira[1] == pairb[0]);
|
(paira[0] == pairb[1] && paira[1] == pairb[0]);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void lfs_pair_fromle32(lfs_block_t pair[2]) {
|
static inline void lfs_pair_fromle32(lfs_block_t pair[2]) {
|
||||||
pair[0] = lfs_fromle32(pair[0]);
|
pair[0] = lfs_fromle32(pair[0]);
|
||||||
@@ -4215,14 +4213,23 @@ static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
|
|
||||||
// scan directory blocks for superblock and any global updates
|
// scan directory blocks for superblock and any global updates
|
||||||
lfs_mdir_t dir = {.tail = {0, 1}};
|
lfs_mdir_t dir = {.tail = {0, 1}};
|
||||||
lfs_block_t cycle = 0;
|
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
|
||||||
|
lfs_size_t tortoise_i = 1;
|
||||||
|
lfs_size_t tortoise_period = 1;
|
||||||
while (!lfs_pair_isnull(dir.tail)) {
|
while (!lfs_pair_isnull(dir.tail)) {
|
||||||
if (cycle >= lfs->cfg->block_count/2) {
|
// detect cycles with Brent's algorithm
|
||||||
// loop detected
|
if (lfs_pair_issync(dir.tail, tortoise)) {
|
||||||
|
LFS_WARN("Cycle detected in tail list");
|
||||||
err = LFS_ERR_CORRUPT;
|
err = LFS_ERR_CORRUPT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
cycle += 1;
|
if (tortoise_i == tortoise_period) {
|
||||||
|
tortoise[0] = dir.tail[0];
|
||||||
|
tortoise[1] = dir.tail[1];
|
||||||
|
tortoise_i = 0;
|
||||||
|
tortoise_period *= 2;
|
||||||
|
}
|
||||||
|
tortoise_i += 1;
|
||||||
|
|
||||||
// fetch next block in tail list
|
// fetch next block in tail list
|
||||||
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail,
|
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail,
|
||||||
@@ -4373,13 +4380,22 @@ int lfs_fs_rawtraverse(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lfs_block_t cycle = 0;
|
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
|
||||||
|
lfs_size_t tortoise_i = 1;
|
||||||
|
lfs_size_t tortoise_period = 1;
|
||||||
while (!lfs_pair_isnull(dir.tail)) {
|
while (!lfs_pair_isnull(dir.tail)) {
|
||||||
if (cycle >= lfs->cfg->block_count/2) {
|
// detect cycles with Brent's algorithm
|
||||||
// loop detected
|
if (lfs_pair_issync(dir.tail, tortoise)) {
|
||||||
|
LFS_WARN("Cycle detected in tail list");
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
cycle += 1;
|
if (tortoise_i == tortoise_period) {
|
||||||
|
tortoise[0] = dir.tail[0];
|
||||||
|
tortoise[1] = dir.tail[1];
|
||||||
|
tortoise_i = 0;
|
||||||
|
tortoise_period *= 2;
|
||||||
|
}
|
||||||
|
tortoise_i += 1;
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
int err = cb(data, dir.tail[i]);
|
int err = cb(data, dir.tail[i]);
|
||||||
@@ -4458,13 +4474,22 @@ static int lfs_fs_pred(lfs_t *lfs,
|
|||||||
// iterate over all directory directory entries
|
// iterate over all directory directory entries
|
||||||
pdir->tail[0] = 0;
|
pdir->tail[0] = 0;
|
||||||
pdir->tail[1] = 1;
|
pdir->tail[1] = 1;
|
||||||
lfs_block_t cycle = 0;
|
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
|
||||||
|
lfs_size_t tortoise_i = 1;
|
||||||
|
lfs_size_t tortoise_period = 1;
|
||||||
while (!lfs_pair_isnull(pdir->tail)) {
|
while (!lfs_pair_isnull(pdir->tail)) {
|
||||||
if (cycle >= lfs->cfg->block_count/2) {
|
// detect cycles with Brent's algorithm
|
||||||
// loop detected
|
if (lfs_pair_issync(pdir->tail, tortoise)) {
|
||||||
|
LFS_WARN("Cycle detected in tail list");
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
cycle += 1;
|
if (tortoise_i == tortoise_period) {
|
||||||
|
tortoise[0] = pdir->tail[0];
|
||||||
|
tortoise[1] = pdir->tail[1];
|
||||||
|
tortoise_i = 0;
|
||||||
|
tortoise_period *= 2;
|
||||||
|
}
|
||||||
|
tortoise_i += 1;
|
||||||
|
|
||||||
if (lfs_pair_cmp(pdir->tail, pair) == 0) {
|
if (lfs_pair_cmp(pdir->tail, pair) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -4514,13 +4539,22 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
|||||||
// use fetchmatch with callback to find pairs
|
// use fetchmatch with callback to find pairs
|
||||||
parent->tail[0] = 0;
|
parent->tail[0] = 0;
|
||||||
parent->tail[1] = 1;
|
parent->tail[1] = 1;
|
||||||
lfs_block_t cycle = 0;
|
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
|
||||||
|
lfs_size_t tortoise_i = 1;
|
||||||
|
lfs_size_t tortoise_period = 1;
|
||||||
while (!lfs_pair_isnull(parent->tail)) {
|
while (!lfs_pair_isnull(parent->tail)) {
|
||||||
if (cycle >= lfs->cfg->block_count/2) {
|
// detect cycles with Brent's algorithm
|
||||||
// loop detected
|
if (lfs_pair_issync(parent->tail, tortoise)) {
|
||||||
|
LFS_WARN("Cycle detected in tail list");
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
cycle += 1;
|
if (tortoise_i == tortoise_period) {
|
||||||
|
tortoise[0] = parent->tail[0];
|
||||||
|
tortoise[1] = parent->tail[1];
|
||||||
|
tortoise_i = 0;
|
||||||
|
tortoise_period *= 2;
|
||||||
|
}
|
||||||
|
tortoise_i += 1;
|
||||||
|
|
||||||
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, parent, parent->tail,
|
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, parent, parent->tail,
|
||||||
LFS_MKTAG(0x7ff, 0, 0x3ff),
|
LFS_MKTAG(0x7ff, 0, 0x3ff),
|
||||||
@@ -4643,7 +4677,7 @@ static int lfs_fs_deorphan(lfs_t *lfs, bool powerloss) {
|
|||||||
}
|
}
|
||||||
lfs_pair_fromle32(pair);
|
lfs_pair_fromle32(pair);
|
||||||
|
|
||||||
if (!lfs_pair_sync(pair, pdir.tail)) {
|
if (!lfs_pair_issync(pair, pdir.tail)) {
|
||||||
// we have desynced
|
// we have desynced
|
||||||
LFS_DEBUG("Fixing half-orphan "
|
LFS_DEBUG("Fixing half-orphan "
|
||||||
"{0x%"PRIx32", 0x%"PRIx32"} "
|
"{0x%"PRIx32", 0x%"PRIx32"} "
|
||||||
|
|||||||
Reference in New Issue
Block a user