@@ -4396,6 +4396,30 @@ static int lfs_format_(lfs_t *lfs, const struct lfs_config *cfg) {
43964396}
43974397#endif
43984398
4399+ struct lfs_tortoise_t {
4400+ lfs_block_t pair [2 ];
4401+ lfs_size_t i ;
4402+ lfs_size_t period ;
4403+ };
4404+
4405+ static int lfs_tortoise_detectcycles (
4406+ const lfs_mdir_t * dir , struct lfs_tortoise_t * tortoise ) {
4407+ // detect cycles with Brent's algorithm
4408+ if (lfs_pair_issync (dir -> tail , tortoise -> pair )) {
4409+ LFS_WARN ("Cycle detected in tail list" );
4410+ return LFS_ERR_CORRUPT ;
4411+ }
4412+ if (tortoise -> i == tortoise -> period ) {
4413+ tortoise -> pair [0 ] = dir -> tail [0 ];
4414+ tortoise -> pair [1 ] = dir -> tail [1 ];
4415+ tortoise -> i = 0 ;
4416+ tortoise -> period *= 2 ;
4417+ }
4418+ tortoise -> i += 1 ;
4419+
4420+ return LFS_ERR_OK ;
4421+ }
4422+
43994423static int lfs_mount_ (lfs_t * lfs , const struct lfs_config * cfg ) {
44004424 int err = lfs_init (lfs , cfg );
44014425 if (err ) {
@@ -4404,23 +4428,16 @@ static int lfs_mount_(lfs_t *lfs, const struct lfs_config *cfg) {
44044428
44054429 // scan directory blocks for superblock and any global updates
44064430 lfs_mdir_t dir = {.tail = {0 , 1 }};
4407- lfs_block_t tortoise [2 ] = {LFS_BLOCK_NULL , LFS_BLOCK_NULL };
4408- lfs_size_t tortoise_i = 1 ;
4409- lfs_size_t tortoise_period = 1 ;
4431+ struct lfs_tortoise_t tortoise = {
4432+ .pair = {LFS_BLOCK_NULL , LFS_BLOCK_NULL },
4433+ .i = 1 ,
4434+ .period = 1 ,
4435+ };
44104436 while (!lfs_pair_isnull (dir .tail )) {
4411- // detect cycles with Brent's algorithm
4412- if (lfs_pair_issync (dir .tail , tortoise )) {
4413- LFS_WARN ("Cycle detected in tail list" );
4414- err = LFS_ERR_CORRUPT ;
4437+ err = lfs_tortoise_detectcycles (& dir , & tortoise );
4438+ if (err < 0 ) {
44154439 goto cleanup ;
44164440 }
4417- if (tortoise_i == tortoise_period ) {
4418- tortoise [0 ] = dir .tail [0 ];
4419- tortoise [1 ] = dir .tail [1 ];
4420- tortoise_i = 0 ;
4421- tortoise_period *= 2 ;
4422- }
4423- tortoise_i += 1 ;
44244441
44254442 // fetch next block in tail list
44264443 lfs_stag_t tag = lfs_dir_fetchmatch (lfs , & dir , dir .tail ,
@@ -4633,22 +4650,17 @@ int lfs_fs_traverse_(lfs_t *lfs,
46334650 }
46344651#endif
46354652
4636- lfs_block_t tortoise [2 ] = {LFS_BLOCK_NULL , LFS_BLOCK_NULL };
4637- lfs_size_t tortoise_i = 1 ;
4638- lfs_size_t tortoise_period = 1 ;
4653+ struct lfs_tortoise_t tortoise = {
4654+ .pair = {LFS_BLOCK_NULL , LFS_BLOCK_NULL },
4655+ .i = 1 ,
4656+ .period = 1 ,
4657+ };
4658+ int err = LFS_ERR_OK ;
46394659 while (!lfs_pair_isnull (dir .tail )) {
4640- // detect cycles with Brent's algorithm
4641- if (lfs_pair_issync (dir .tail , tortoise )) {
4642- LFS_WARN ("Cycle detected in tail list" );
4660+ err = lfs_tortoise_detectcycles (& dir , & tortoise );
4661+ if (err < 0 ) {
46434662 return LFS_ERR_CORRUPT ;
46444663 }
4645- if (tortoise_i == tortoise_period ) {
4646- tortoise [0 ] = dir .tail [0 ];
4647- tortoise [1 ] = dir .tail [1 ];
4648- tortoise_i = 0 ;
4649- tortoise_period *= 2 ;
4650- }
4651- tortoise_i += 1 ;
46524664
46534665 for (int i = 0 ; i < 2 ; i ++ ) {
46544666 int err = cb (data , dir .tail [i ]);
@@ -4727,22 +4739,17 @@ static int lfs_fs_pred(lfs_t *lfs,
47274739 // iterate over all directory directory entries
47284740 pdir -> tail [0 ] = 0 ;
47294741 pdir -> tail [1 ] = 1 ;
4730- lfs_block_t tortoise [2 ] = {LFS_BLOCK_NULL , LFS_BLOCK_NULL };
4731- lfs_size_t tortoise_i = 1 ;
4732- lfs_size_t tortoise_period = 1 ;
4742+ struct lfs_tortoise_t tortoise = {
4743+ .pair = {LFS_BLOCK_NULL , LFS_BLOCK_NULL },
4744+ .i = 1 ,
4745+ .period = 1 ,
4746+ };
4747+ int err = LFS_ERR_OK ;
47334748 while (!lfs_pair_isnull (pdir -> tail )) {
4734- // detect cycles with Brent's algorithm
4735- if (lfs_pair_issync (pdir -> tail , tortoise )) {
4736- LFS_WARN ("Cycle detected in tail list" );
4749+ err = lfs_tortoise_detectcycles (pdir , & tortoise );
4750+ if (err < 0 ) {
47374751 return LFS_ERR_CORRUPT ;
47384752 }
4739- if (tortoise_i == tortoise_period ) {
4740- tortoise [0 ] = pdir -> tail [0 ];
4741- tortoise [1 ] = pdir -> tail [1 ];
4742- tortoise_i = 0 ;
4743- tortoise_period *= 2 ;
4744- }
4745- tortoise_i += 1 ;
47464753
47474754 if (lfs_pair_cmp (pdir -> tail , pair ) == 0 ) {
47484755 return 0 ;
@@ -4792,22 +4799,17 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
47924799 // use fetchmatch with callback to find pairs
47934800 parent -> tail [0 ] = 0 ;
47944801 parent -> tail [1 ] = 1 ;
4795- lfs_block_t tortoise [2 ] = {LFS_BLOCK_NULL , LFS_BLOCK_NULL };
4796- lfs_size_t tortoise_i = 1 ;
4797- lfs_size_t tortoise_period = 1 ;
4802+ struct lfs_tortoise_t tortoise = {
4803+ .pair = {LFS_BLOCK_NULL , LFS_BLOCK_NULL },
4804+ .i = 1 ,
4805+ .period = 1 ,
4806+ };
4807+ int err = LFS_ERR_OK ;
47984808 while (!lfs_pair_isnull (parent -> tail )) {
4799- // detect cycles with Brent's algorithm
4800- if (lfs_pair_issync (parent -> tail , tortoise )) {
4801- LFS_WARN ("Cycle detected in tail list" );
4802- return LFS_ERR_CORRUPT ;
4803- }
4804- if (tortoise_i == tortoise_period ) {
4805- tortoise [0 ] = parent -> tail [0 ];
4806- tortoise [1 ] = parent -> tail [1 ];
4807- tortoise_i = 0 ;
4808- tortoise_period *= 2 ;
4809+ err = lfs_tortoise_detectcycles (parent , & tortoise );
4810+ if (err < 0 ) {
4811+ return err ;
48094812 }
4810- tortoise_i += 1 ;
48114813
48124814 lfs_stag_t tag = lfs_dir_fetchmatch (lfs , parent , parent -> tail ,
48134815 LFS_MKTAG (0x7ff , 0 , 0x3ff ),
0 commit comments