diff --git a/lfs.c b/lfs.c index 95a3b6a..3419e41 100644 --- a/lfs.c +++ b/lfs.c @@ -2064,10 +2064,14 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { dir->pos = lfs_min(2, off); off -= dir->pos; - while (off != 0) { - dir->id = lfs_min(dir->m.count, off); - dir->pos += dir->id; - off -= dir->id; + // skip superblock entry + dir->id = (off > 0 && lfs_pair_cmp(dir->head, lfs->root) == 0); + + while (off > 0) { + int diff = lfs_min(dir->m.count - dir->id, off); + dir->id += diff; + dir->pos += diff; + off -= diff; if (dir->id == dir->m.count) { if (!dir->m.split) { @@ -2080,6 +2084,8 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { LFS_TRACE("lfs_dir_seek -> %d", err); return err; } + + dir->id = 0; } } diff --git a/tests/test_seek.sh b/tests/test_seek.sh index e5696d0..e136aa0 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -428,4 +428,78 @@ scripts/test.py << TEST TEST done +echo "--- Root seek test ---" +./scripts/test.py << TEST + lfs_mount(&lfs, &cfg) => 0; + for (int i = 3; i < $MEDIUMSIZE; i++) { + sprintf(path, "hi%03d", i); + lfs_mkdir(&lfs, path) => 0; + } + + lfs_dir_open(&lfs, &dir, "/") => 0; + for (int i = 0; i < $MEDIUMSIZE; i++) { + if (i == 0) { + sprintf(path, "."); + } else if (i == 1) { + sprintf(path, ".."); + } else if (i == 2) { + sprintf(path, "hello"); + } else { + sprintf(path, "hi%03d", i); + } + lfs_dir_read(&lfs, &dir, &info) => 1; + strcmp(path, info.name) => 0; + } + lfs_dir_read(&lfs, &dir, &info) => 0; + lfs_dir_close(&lfs, &dir) => 0; + + for (int j = 0; j < $MEDIUMSIZE; j++) { + lfs_soff_t off = -1; + + lfs_dir_open(&lfs, &dir, "/") => 0; + for (int i = 0; i < $MEDIUMSIZE; i++) { + if (i == 0) { + sprintf(path, "."); + } else if (i == 1) { + sprintf(path, ".."); + } else if (i == 2) { + sprintf(path, "hello"); + } else { + sprintf(path, "hi%03d", i); + } + + if (i == j) { + off = lfs_dir_tell(&lfs, &dir); + off >= 0 => true; + } + + lfs_dir_read(&lfs, &dir, &info) => 1; + strcmp(path, info.name) => 0; + } + lfs_dir_read(&lfs, &dir, &info) => 0; + lfs_dir_close(&lfs, &dir) => 0; + + lfs_dir_open(&lfs, &dir, "/") => 0; + lfs_dir_seek(&lfs, &dir, off) => 0; + for (int i = j; i < $MEDIUMSIZE; i++) { + if (i == 0) { + sprintf(path, "."); + } else if (i == 1) { + sprintf(path, ".."); + } else if (i == 2) { + sprintf(path, "hello"); + } else { + sprintf(path, "hi%03d", i); + } + + lfs_dir_read(&lfs, &dir, &info) => 1; + strcmp(path, info.name) => 0; + } + lfs_dir_read(&lfs, &dir, &info) => 0; + lfs_dir_close(&lfs, &dir) => 0; + } + + lfs_unmount(&lfs) => 0; +TEST + scripts/results.py