X Tutup
Skip to content

fs: expose frsize field in statfs results#62495

Open
juicecultus wants to merge 1 commit intonodejs:mainfrom
juicecultus:fs-statfs-expose-frsize
Open

fs: expose frsize field in statfs results#62495
juicecultus wants to merge 1 commit intonodejs:mainfrom
juicecultus:fs-statfs-expose-frsize

Conversation

@juicecultus
Copy link
Copy Markdown

Description

fs.statfs() exposes bsize (optimal I/O block size) but not frsize (fundamental filesystem block size). Per POSIX, block counts (blocks, bfree, bavail) are in units of frsize, not bsize. libuv already reads f_frsize from the kernel and stores it in uv_statfs_t β€” it was simply never mapped to JavaScript.

On most native filesystems bsize == frsize, so the omission was harmless. However, on FUSE mounts (e.g. Docker Desktop on macOS with VirtioFS or gRPC FUSE), they can diverge by orders of magnitude:

Field Value * blocks result
bsize 2,097,152 (2 MiB) 1.82 PiB ❌
frsize 16,384 (16 KiB) 14.9 TiB βœ…

This causes any application computing disk space as bsize * blocks to report wildly inflated values. Real-world example: Immich photo manager shows "602 TiB of 1.8 PiB" on a 15 TB disk when running in Docker on macOS.

Changes

Adds the frsize property to the StatFs object returned by fs.statfs(), fs.statfsSync(), and fsPromises.statfs(), in both normal and bigint modes.

Files changed:

  • src/node_file.h β€” add kFrSize to FsStatFsOffset enum
  • src/node_file-inl.h β€” map s->f_frsize in FillStatFsArray()
  • lib/internal/fs/utils.js β€” add frsize to StatFs class and binding
  • doc/api/fs.md β€” document the new field
  • test/parallel/test-fs-statfs.js β€” include frsize in property checks
  • test/parallel/test-fs-promises.js β€” include frsize in type assertions

Notes

  • On Linux, libuv sets f_frsize from the kernel's statfs.f_frsize
  • On non-Linux (macOS, etc.), libuv falls back to f_frsize = f_bsize, so this is always populated
  • This is a semver-minor addition (new property on existing object)

Node.js statfs() exposes bsize (optimal I/O block size) but not frsize
(fundamental filesystem block size). Per POSIX, block counts (blocks,
bfree, bavail) are in units of frsize, not bsize. libuv already reads
f_frsize from the kernel β€” it was simply not mapped to JavaScript.

On most native filesystems bsize == frsize, so the omission was
harmless. However, on FUSE mounts (e.g. Docker Desktop on macOS with
VirtioFS or gRPC FUSE), they can differ by orders of magnitude
(bsize=2MiB vs frsize=16KiB), causing applications that compute disk
space as bsize*blocks to report wildly inflated values.

This commit adds the frsize property to the StatFs object returned by
fs.statfs(), fs.statfsSync(), and fsPromises.statfs(), in both normal
and bigint modes.
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

X Tutup