Skip to content

Commit

Permalink
Write the detect cycles function as a function to optimize code
Browse files Browse the repository at this point in the history
  • Loading branch information
wdfk-prog committed Sep 22, 2024
1 parent d01280e commit ea53106
Showing 1 changed file with 52 additions and 53 deletions.
105 changes: 52 additions & 53 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4396,6 +4396,32 @@ static int lfs_format_(lfs_t *lfs, const struct lfs_config *cfg) {
}
#endif

struct lfs_tortoise_t
{
lfs_block_t pair[2];
lfs_size_t i;
lfs_size_t period;
};

static int lfs_detect_cycles(lfs_mdir_t *dir, struct lfs_tortoise_t *tortoise)
{
int err = LFS_ERR_OK;
// detect cycles with Brent's algorithm
if (lfs_pair_issync(dir->tail, tortoise->pair)) {
LFS_WARN("Cycle detected in tail list");
return LFS_ERR_CORRUPT;
}
if (tortoise->i == tortoise->period) {
tortoise->pair[0] = dir->tail[0];
tortoise->pair[1] = dir->tail[1];
tortoise->i = 0;
tortoise->period *= 2;
}
tortoise->i += 1;

return err;
}

static int lfs_mount_(lfs_t *lfs, const struct lfs_config *cfg) {
int err = lfs_init(lfs, cfg);
if (err) {
Expand All @@ -4404,23 +4430,16 @@ static int lfs_mount_(lfs_t *lfs, const struct lfs_config *cfg) {

// scan directory blocks for superblock and any global updates
lfs_mdir_t dir = {.tail = {0, 1}};
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
lfs_size_t tortoise_i = 1;
lfs_size_t tortoise_period = 1;
struct lfs_tortoise_t tortoise = {
.pair = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
.i = 1,
.period = 1,
};
while (!lfs_pair_isnull(dir.tail)) {
// detect cycles with Brent's algorithm
if (lfs_pair_issync(dir.tail, tortoise)) {
LFS_WARN("Cycle detected in tail list");
err = LFS_ERR_CORRUPT;
err = lfs_detect_cycles(&dir, &tortoise);
if (err == LFS_ERR_CORRUPT) {
goto cleanup;
}
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
lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail,
Expand Down Expand Up @@ -4633,22 +4652,16 @@ int lfs_fs_traverse_(lfs_t *lfs,
}
#endif

lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
lfs_size_t tortoise_i = 1;
lfs_size_t tortoise_period = 1;
struct lfs_tortoise_t tortoise = {
.pair = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
.i = 1,
.period = 1,
};

while (!lfs_pair_isnull(dir.tail)) {
// detect cycles with Brent's algorithm
if (lfs_pair_issync(dir.tail, tortoise)) {
LFS_WARN("Cycle detected in tail list");
if (lfs_detect_cycles(&dir, &tortoise) == LFS_ERR_CORRUPT) {
return LFS_ERR_CORRUPT;
}
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++) {
int err = cb(data, dir.tail[i]);
Expand Down Expand Up @@ -4727,22 +4740,15 @@ static int lfs_fs_pred(lfs_t *lfs,
// iterate over all directory directory entries
pdir->tail[0] = 0;
pdir->tail[1] = 1;
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
lfs_size_t tortoise_i = 1;
lfs_size_t tortoise_period = 1;
struct lfs_tortoise_t tortoise = {
.pair = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
.i = 1,
.period = 1,
};
while (!lfs_pair_isnull(pdir->tail)) {
// detect cycles with Brent's algorithm
if (lfs_pair_issync(pdir->tail, tortoise)) {
LFS_WARN("Cycle detected in tail list");
if (lfs_detect_cycles(pdir, &tortoise) == LFS_ERR_CORRUPT) {
return LFS_ERR_CORRUPT;
}
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) {
return 0;
Expand Down Expand Up @@ -4792,22 +4798,15 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
// use fetchmatch with callback to find pairs
parent->tail[0] = 0;
parent->tail[1] = 1;
lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL};
lfs_size_t tortoise_i = 1;
lfs_size_t tortoise_period = 1;
struct lfs_tortoise_t tortoise = {
.pair = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
.i = 1,
.period = 1,
};
while (!lfs_pair_isnull(parent->tail)) {
// detect cycles with Brent's algorithm
if (lfs_pair_issync(parent->tail, tortoise)) {
LFS_WARN("Cycle detected in tail list");
if (lfs_detect_cycles(parent, &tortoise) == LFS_ERR_CORRUPT) {
return LFS_ERR_CORRUPT;
}
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_MKTAG(0x7ff, 0, 0x3ff),
Expand Down

0 comments on commit ea53106

Please sign in to comment.