Skip to content

Conversation

@wdfk-prog
Copy link
Collaborator

@wdfk-prog wdfk-prog commented Dec 15, 2025

[

为什么提交这份PR (why to submit this PR)

Fix littlefs dir lseek to keep file->pos in user-space offset

  • Convert seek offset to littlefs entry index (skip dot entries) and back to user byte offset after lfs_dir_seek
  • Align telldir/seekdir with getdents behavior

#29

你的解决方案是什么 (what is your solution)

Adjust directory lseek to skip the first two dot entries by converting the byte offset into a dirent index and adding 2 before calling lfs_dir_seek.

请提供验证的bsp和config (provide the config and bsp)

  • BSP: N/A (logic-only change, no board-specific validation yet)

  • .config: N/A

  • action: N/A

  • 测试代码

#define SEEKDIR_FIXTURE "/flash/seekdir_bug"
static void lfs_seekdir_bug(void)
{
    struct stat st;
    rt_bool_t exists = RT_FALSE;
    if (stat(SEEKDIR_FIXTURE, &st) == 0 && S_ISDIR(st.st_mode))
    {
        rt_kprintf("seekdir fixture already exists: %s\n", SEEKDIR_FIXTURE);
        exists = RT_TRUE;
    }

    if (!exists && mkdir(SEEKDIR_FIXTURE, 0) < 0 && errno != EEXIST)
    {
        rt_kprintf("create %s failed, errno=%d\n", SEEKDIR_FIXTURE, errno);
        return;
    }

    /* 准备 3 个文件,确保条目数足够 */
    const char *names[] = {"a", "b", "c"};
    for (int i = 0; i < 3; i++)
    {
        char path[64];
        rt_snprintf(path, sizeof(path), "%s/%s", SEEKDIR_FIXTURE, names[i]);
        int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0);
        if (fd >= 0) { write(fd, "1", 1); close(fd); }
    }

    DIR *dir = opendir(SEEKDIR_FIXTURE);
    if (dir == RT_NULL)
    {
        rt_kprintf("open %s failed, errno=%d\n", SEEKDIR_FIXTURE, errno);
        return;
    }

    char n1[DFS_PATH_MAX] = {0};
    char n2[DFS_PATH_MAX] = {0};
    char n3[DFS_PATH_MAX] = {0};
    struct dirent *de;
    long p1 = -1, p2 = -1;

    seekdir(dir, 0); /* 显式回到起点 */

    de = readdir(dir);
    if (de) rt_strncpy(n1, de->d_name, sizeof(n1));
    p1 = telldir(dir);

    de = readdir(dir);
    if (de) rt_strncpy(n2, de->d_name, sizeof(n2));
    p2 = telldir(dir);

    seekdir(dir, p2);
    de = readdir(dir);
    if (de) rt_strncpy(n3, de->d_name, sizeof(n3));

    rt_kprintf("readdir1=%s, telldir_after1=%ld (expect 0), readdir2=%s, telldir_after2=%ld (expect %d), after_seek=%s, errno=%d\n",
               n1[0] ? n1 : "(null)",
               p1,
               n2[0] ? n2 : "(null)",
               p2, (int)sizeof(struct dirent),
               n3[0] ? n3 : "(null)",
               errno);

    if (p1 == 0 &&
        p2 == sizeof(struct dirent) &&
        n2[0] && n3[0] && rt_strcmp(n2, n3) == 0)
        rt_kprintf("PASS: seekdir/telldir 一致\n");
    else
        rt_kprintf("FAIL: mismatch\n");

    closedir(dir);
}
MSH_CMD_EXPORT(lfs_seekdir_bug, reproduce seekdir / telldir mismatch);
  • 修复前
msh />lfs_seekdir_bug
seekdir fixture already exists: /flash/seekdir_bug
readdir1=a, telldir_after1=2 (expect 0), readdir2=b, telldir_after2=262 (expect 260), after_seek=b, errno=0
FAIL: mismatch
  • 修复后
msh />lfs_seekdir_bug
seekdir fixture already exists: /flash/seekdir_bug
readdir1=a, telldir_after1=0 (expect 0), readdir2=b, telldir_after2=260 (expect 260), after_seek=b, errno=0
PASS: seekdir/telldir 一致

]

当前拉取/合并请求的状态 Intent for your PR

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用formatting等源码格式化工具确保格式符合规范 This PR complies with RT-Thread code specification
  • 如果是新增bsp, 已经添加ci检查到.github/ALL_BSP_COMPILE.json(如适用)

Summary by CodeRabbit

  • Bug Fixes
    • Corrected directory seek behavior so user-visible directory positions skip the implicit "." and ".." entries, ensuring directory listings and offsets align with expected entry indexing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Walkthrough

The _dfs_lfs_lseek function in dfs_lfs.c was changed to convert user-space byte offsets to directory-entry indices before seeking. For directories the code now computes off = offset / sizeof(struct dirent) + 2, calls lfs_dir_seek(off), and maps the internal position back to user-space excluding "." and "..".

Changes

Cohort / File(s) Summary
Directory seek offset conversion
dfs_lfs.c
_dfs_lfs_lseek now translates byte offsets for directory targets into directory-entry indices by dividing by sizeof(struct dirent) and adding 2 before calling lfs_dir_seek; post-seek, the file position is converted back to user-space by subtracting the two leading entries.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Specific areas requiring attention:
    • Verify offset / sizeof(struct dirent) + 2 correctly maps user-space offsets to littlefs directory-entry indices.
    • Confirm post-seek conversion of internal dir.pos back to user-space (subtracting 2) is consistent and safe for edge cases.

Possibly related issues

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing littlefs directory lseek to maintain file->pos as a user-space offset, which is the core purpose of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 644344b and cef0433.

📒 Files selected for processing (1)
  • dfs_lfs.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • dfs_lfs.c

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a8be27 and 644344b.

📒 Files selected for processing (1)
  • dfs_lfs.c (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
dfs_lfs.c (1)
lfs.c (1)
  • lfs_dir_seek (6385-6398)
🪛 GitHub Actions: test
dfs_lfs.c

[error] 1-1: Compilation failed: fatal error: rtdevice.h: No such file or directory (included by dfs_lfs.c)

@wdfk-prog
Copy link
Collaborator Author

- Convert seek offset to littlefs entry index (skip dot entries) and back to user byte offset after lfs_dir_seek
- Align telldir/seekdir with getdents behavior
@wdfk-prog wdfk-prog changed the title fix littlefs dir lseek to skip dot entries Fix littlefs dir lseek to keep file->pos in user-space offset Dec 15, 2025
@wdfk-prog
Copy link
Collaborator Author

@coderabbitai

@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Tip

For best results, initiate chat on the files or code changes.

@wdfk-prog Hello! How can I help you with this PR?

Would you like me to:

  • Review the changes in this pull request?
  • Answer specific questions about the code?
  • Help with something else?

Please let me know what you need, and I'll be happy to assist!

@Rbb666 Rbb666 merged commit 14907b6 into RT-Thread-packages:master Dec 15, 2025
2 of 19 checks passed
@wdfk-prog wdfk-prog deleted the lseek branch December 15, 2025 08:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants