mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
### What does this PR do? Fixes #24007 Possibly fixes https://github.com/oven-sh/bun/issues/18902, https://github.com/oven-sh/bun/issues/7412 Some filesystems (bind mounts, FUSE, NFS) don't provide `d_type` in directory entries, returning `DT_UNKNOWN`. This caused glob and recursive readdir to skip entries entirely. ## Problem On Linux filesystems that don't populate `d_type` in directory entries (bind mounts, FUSE, NFS, some ext4 configurations), `readdir()` returns `DT_UNKNOWN` instead of the actual file type. This caused: - `Bun.Glob` to skip files/directories entirely - `fs.readdirSync(..., {recursive: true})` to not recurse into subdirectories - `fs.readdirSync(..., {withFileTypes: true})` to report incorrect types ## Solution Implemented a **lazy `lstatat()` fallback** when `d_type == DT_UNKNOWN`: - **`sys.zig`**: Added `lstatat()` function - same as `fstatat()` but with `AT_SYMLINK_NOFOLLOW` flag to correctly identify symlinks - **`GlobWalker.zig`**: When encountering `.unknown` entries, first check if filename matches pattern, then call `lstatat()` only if needed - **`node_fs.zig`**: Handle `.unknown` in both async and sync recursive readdir paths; propagate resolved kind to Dirent objects - **`dir_iterator.zig`**: Return `.unknown` for `DT_UNKNOWN` entries, letting callers handle lazy stat **Why `lstatat` instead of `fstatat`?** We use `AT_SYMLINK_NOFOLLOW` to preserve consistent behavior with normal filesystems - symlinks should be reported as symlinks, not as their target type. This matches [Node.js behavior](https://github.com/nodejs/node/blob/main/lib/internal/fs/utils.js#L251-L269) which uses `lstat()` for the DT_UNKNOWN fallback, and follows the lazy stat pattern established in PR #18172. ### How did you verify your code works? **Testing:** - Regression test: `test/regression/issue/24007.test.ts` - FUSE filesystem test: `test/cli/run/glob-on-fuse.test.ts` (reuses `fuse-fs.py` from PR #18172, includes symlink verification) - All existing glob/readdir tests pass - **Verified in Docker bind-mount environment:** - Official Bun: `0 files` - Patched Bun: `3 files` **Performance:** No impact on normal filesystems - the `.unknown` branch is only hit when `d_type == DT_UNKNOWN`. The lazy stat pattern avoids unnecessary syscalls by checking pattern match first. --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>