Skip to content

Commit 286fcbb

Browse files
committed
fix(API): prefer frsize over bsize for disk-space calculation
Defensive fix from bugbot review of #1627. Node's fs.statfs() currently only exposes bsize (libuv's uv_statfs_t doesn't copy frsize from the underlying statfs(2) syscall), and on Linux+ext4 'blocks * bsize' matches 'df -B1' byte-exactly. But POSIX statvfs denominates blocks in frsize, not bsize, and on exotic filesystems (e.g. VirtioFS on Docker) the two can differ. Using 'stats.frsize ?? stats.bsize' is a zero-cost hedge that automatically picks up frsize if a future Node version or a polyfill exposes it, while keeping today's behavior unchanged on every mainstream environment.
1 parent e6d4396 commit 286fcbb

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

src/utils/system-info.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,19 @@ const getDiskInfo = async (targetPath) => {
6161
}
6262

6363
const stats = await fs.promises.statfs(resolvedPath);
64+
// Per POSIX statvfs(3) the `blocks`/`bavail` fields are denominated in
65+
// `f_frsize` (fundamental block size), not `f_bsize` (optimal transfer
66+
// block size). Node's libuv wrapper currently only exposes `bsize`, and
67+
// on Linux+ext4 the two are equal so `blocks * bsize` matches `df -B1`
68+
// byte-exactly. We still prefer `frsize` when present (some Node forks
69+
// and future versions expose it) and fall back to `bsize` -- a zero-cost
70+
// hedge against environments like Docker+VirtioFS where the two can
71+
// differ.
72+
const blockSize = stats.frsize ?? stats.bsize;
6473
return {
6574
path: resolvedPath,
66-
totalBytes: stats.blocks * stats.bsize,
67-
freeBytes: stats.bavail * stats.bsize,
75+
totalBytes: stats.blocks * blockSize,
76+
freeBytes: stats.bavail * blockSize,
6877
};
6978
} catch (error) {
7079
logger.debug(`[diagnostics]: failed to stat disk for ${targetPath}: ${error.message}`);

0 commit comments

Comments
 (0)