Skip to content

Commit a7c9daa

Browse files
cjihrigruyadorno
authored andcommitted
fs: add statfs() functions
This commit adds statfs() and statfsSync() to the fs module, and statfs() to the fsPromises module. Co-authored-by: cjihrig <[email protected]> Fixes: #10745 Refs: #31351 PR-URL: #46358 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 968db21 commit a7c9daa

File tree

10 files changed

+457
-12
lines changed

10 files changed

+457
-12
lines changed

doc/api/fs.md

+159
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,19 @@ changes:
15311531
* Returns: {Promise} Fulfills with the {fs.Stats} object for the
15321532
given `path`.
15331533
1534+
### `fsPromises.statfs(path[, options])`
1535+
1536+
<!-- YAML
1537+
added: REPLACEME
1538+
-->
1539+
1540+
* `path` {string|Buffer|URL}
1541+
* `options` {Object}
1542+
* `bigint` {boolean} Whether the numeric values in the returned
1543+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
1544+
* Returns: {Promise} Fulfills with the {fs.StatFs} object for the
1545+
given `path`.
1546+
15341547
### `fsPromises.symlink(target, path[, type])`
15351548
15361549
<!-- YAML
@@ -4101,6 +4114,26 @@ Stats {
41014114
}
41024115
```
41034116

4117+
### `fs.statfs(path[, options], callback)`
4118+
4119+
<!-- YAML
4120+
added: REPLACEME
4121+
-->
4122+
4123+
* `path` {string|Buffer|URL}
4124+
* `options` {Object}
4125+
* `bigint` {boolean} Whether the numeric values in the returned
4126+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
4127+
* `callback` {Function}
4128+
* `err` {Error}
4129+
* `stats` {fs.StatFs}
4130+
4131+
Asynchronous statfs(2). Returns information about the mounted file system which
4132+
contains `path`. The callback gets two arguments `(err, stats)` where `stats`
4133+
is an {fs.StatFs} object.
4134+
4135+
In case of an error, the `err.code` will be one of [Common System Errors][].
4136+
41044137
### `fs.symlink(target, path[, type], callback)`
41054138

41064139
<!-- YAML
@@ -5852,6 +5885,23 @@ changes:
58525885

58535886
Retrieves the {fs.Stats} for the path.
58545887

5888+
### `fs.statfsSync(path[, options])`
5889+
5890+
<!-- YAML
5891+
added: REPLACEME
5892+
-->
5893+
5894+
* `path` {string|Buffer|URL}
5895+
* `options` {Object}
5896+
* `bigint` {boolean} Whether the numeric values in the returned
5897+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
5898+
* Returns: {fs.StatFs}
5899+
5900+
Synchronous statfs(2). Returns information about the mounted file system which
5901+
contains `path`.
5902+
5903+
In case of an error, the `err.code` will be one of [Common System Errors][].
5904+
58555905
### `fs.symlinkSync(target, path[, type])`
58565906

58575907
<!-- YAML
@@ -6944,6 +6994,114 @@ The times in the stat object have the following semantics:
69446994
Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As
69456995
of 0.12, `ctime` is not "creation time", and on Unix systems, it never was.
69466996

6997+
### Class: `fs.StatFs`
6998+
6999+
<!-- YAML
7000+
added: REPLACEME
7001+
-->
7002+
7003+
Provides information about a mounted file system.
7004+
7005+
Objects returned from [`fs.statfs()`][] and its synchronous counterpart are of
7006+
this type. If `bigint` in the `options` passed to those methods is `true`, the
7007+
numeric values will be `bigint` instead of `number`.
7008+
7009+
```console
7010+
StatFs {
7011+
type: 1397114950,
7012+
bsize: 4096,
7013+
blocks: 121938943,
7014+
bfree: 61058895,
7015+
bavail: 61058895,
7016+
files: 999,
7017+
ffree: 1000000
7018+
}
7019+
```
7020+
7021+
`bigint` version:
7022+
7023+
```console
7024+
StatFs {
7025+
type: 1397114950n,
7026+
bsize: 4096n,
7027+
blocks: 121938943n,
7028+
bfree: 61058895n,
7029+
bavail: 61058895n,
7030+
files: 999n,
7031+
ffree: 1000000n
7032+
}
7033+
```
7034+
7035+
#### `statfs.bavail`
7036+
7037+
<!-- YAML
7038+
added: REPLACEME
7039+
-->
7040+
7041+
* {number|bigint}
7042+
7043+
Free blocks available to unprivileged users.
7044+
7045+
#### `statfs.bfree`
7046+
7047+
<!-- YAML
7048+
added: REPLACEME
7049+
-->
7050+
7051+
* {number|bigint}
7052+
7053+
Free blocks in file system.
7054+
7055+
#### `statfs.blocks`
7056+
7057+
<!-- YAML
7058+
added: REPLACEME
7059+
-->
7060+
7061+
* {number|bigint}
7062+
7063+
Total data blocks in file system.
7064+
7065+
#### `statfs.bsize`
7066+
7067+
<!-- YAML
7068+
added: REPLACEME
7069+
-->
7070+
7071+
* {number|bigint}
7072+
7073+
Optimal transfer block size.
7074+
7075+
#### `statfs.ffree`
7076+
7077+
<!-- YAML
7078+
added: REPLACEME
7079+
-->
7080+
7081+
* {number|bigint}
7082+
7083+
Free file nodes in file system.
7084+
7085+
#### `statfs.files`
7086+
7087+
<!-- YAML
7088+
added: REPLACEME
7089+
-->
7090+
7091+
* {number|bigint}
7092+
7093+
Total file nodes in file system.
7094+
7095+
#### `statfs.type`
7096+
7097+
<!-- YAML
7098+
added: REPLACEME
7099+
-->
7100+
7101+
* {number|bigint}
7102+
7103+
Type of file system.
7104+
69477105
### Class: `fs.WriteStream`
69487106

69497107
<!-- YAML
@@ -7787,6 +7945,7 @@ the file contents.
77877945
[`fs.rmSync()`]: #fsrmsyncpath-options
77887946
[`fs.rmdir()`]: #fsrmdirpath-options-callback
77897947
[`fs.stat()`]: #fsstatpath-options-callback
7948+
[`fs.statfs()`]: #fsstatfspath-options-callback
77907949
[`fs.symlink()`]: #fssymlinktarget-path-type-callback
77917950
[`fs.utimes()`]: #fsutimespath-atime-mtime-callback
77927951
[`fs.watch()`]: #fswatchfilename-options-listener

lib/fs.js

+30
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const {
102102
nullCheck,
103103
preprocessSymlinkDestination,
104104
Stats,
105+
getStatFsFromBinding,
105106
getStatsFromBinding,
106107
realpathCacheKey,
107108
stringToFlags,
@@ -1509,6 +1510,24 @@ function stat(path, options = { bigint: false }, callback) {
15091510
binding.stat(pathModule.toNamespacedPath(path), options.bigint, req);
15101511
}
15111512

1513+
function statfs(path, options = { bigint: false }, callback) {
1514+
if (typeof options === 'function') {
1515+
callback = options;
1516+
options = kEmptyObject;
1517+
}
1518+
callback = maybeCallback(callback);
1519+
path = getValidatedPath(path);
1520+
const req = new FSReqCallback(options.bigint);
1521+
req.oncomplete = (err, stats) => {
1522+
if (err) {
1523+
return callback(err);
1524+
}
1525+
1526+
callback(err, getStatFsFromBinding(stats));
1527+
};
1528+
binding.statfs(pathModule.toNamespacedPath(path), options.bigint, req);
1529+
}
1530+
15121531
function hasNoEntryError(ctx) {
15131532
if (ctx.errno) {
15141533
const uvErr = uvErrmapGet(ctx.errno);
@@ -1583,6 +1602,15 @@ function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {
15831602
return getStatsFromBinding(stats);
15841603
}
15851604

1605+
function statfsSync(path, options = { bigint: false }) {
1606+
path = getValidatedPath(path);
1607+
const ctx = { path };
1608+
const stats = binding.statfs(pathModule.toNamespacedPath(path),
1609+
options.bigint, undefined, ctx);
1610+
handleErrorFromBinding(ctx);
1611+
return getStatFsFromBinding(stats);
1612+
}
1613+
15861614
/**
15871615
* Reads the contents of a symbolic link
15881616
* referred to by `path`.
@@ -3013,7 +3041,9 @@ module.exports = fs = {
30133041
rmdir,
30143042
rmdirSync,
30153043
stat,
3044+
statfs,
30163045
statSync,
3046+
statfsSync,
30173047
symlink,
30183048
symlinkSync,
30193049
truncate,

lib/internal/fs/promises.js

+9
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const {
5252
emitRecursiveRmdirWarning,
5353
getDirents,
5454
getOptions,
55+
getStatFsFromBinding,
5556
getStatsFromBinding,
5657
getValidatedPath,
5758
getValidMode,
@@ -781,6 +782,13 @@ async function stat(path, options = { bigint: false }) {
781782
return getStatsFromBinding(result);
782783
}
783784

785+
async function statfs(path, options = { bigint: false }) {
786+
path = getValidatedPath(path);
787+
const result = await binding.statfs(pathModule.toNamespacedPath(path),
788+
options.bigint, kUsePromises);
789+
return getStatFsFromBinding(result);
790+
}
791+
784792
async function link(existingPath, newPath) {
785793
existingPath = getValidatedPath(existingPath, 'existingPath');
786794
newPath = getValidatedPath(newPath, 'newPath');
@@ -953,6 +961,7 @@ module.exports = {
953961
symlink,
954962
lstat,
955963
stat,
964+
statfs,
956965
link,
957966
unlink,
958967
chmod,

lib/internal/fs/utils.js

+19
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,24 @@ function getStatsFromBinding(stats, offset = 0) {
556556
);
557557
}
558558

559+
class StatFs {
560+
constructor(type, bsize, blocks, bfree, bavail, files, ffree) {
561+
this.type = type;
562+
this.bsize = bsize;
563+
this.blocks = blocks;
564+
this.bfree = bfree;
565+
this.bavail = bavail;
566+
this.files = files;
567+
this.ffree = ffree;
568+
}
569+
}
570+
571+
function getStatFsFromBinding(stats) {
572+
return new StatFs(
573+
stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], stats[6]
574+
);
575+
}
576+
559577
function stringToFlags(flags, name = 'flags') {
560578
if (typeof flags === 'number') {
561579
validateInt32(flags, name);
@@ -912,6 +930,7 @@ module.exports = {
912930
nullCheck,
913931
preprocessSymlinkDestination,
914932
realpathCacheKey: Symbol('realpathCacheKey'),
933+
getStatFsFromBinding,
915934
getStatsFromBinding,
916935
stringToFlags,
917936
stringToSymlinkType,

0 commit comments

Comments
 (0)