Skip to content

Commit 643545a

Browse files
cjihrigjuanarbol
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 129dccf commit 643545a

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
@@ -1525,6 +1525,19 @@ changes:
15251525
* Returns: {Promise} Fulfills with the {fs.Stats} object for the
15261526
given `path`.
15271527
1528+
### `fsPromises.statfs(path[, options])`
1529+
1530+
<!-- YAML
1531+
added: REPLACEME
1532+
-->
1533+
1534+
* `path` {string|Buffer|URL}
1535+
* `options` {Object}
1536+
* `bigint` {boolean} Whether the numeric values in the returned
1537+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
1538+
* Returns: {Promise} Fulfills with the {fs.StatFs} object for the
1539+
given `path`.
1540+
15281541
### `fsPromises.symlink(target, path[, type])`
15291542
15301543
<!-- YAML
@@ -4082,6 +4095,26 @@ Stats {
40824095
}
40834096
```
40844097

4098+
### `fs.statfs(path[, options], callback)`
4099+
4100+
<!-- YAML
4101+
added: REPLACEME
4102+
-->
4103+
4104+
* `path` {string|Buffer|URL}
4105+
* `options` {Object}
4106+
* `bigint` {boolean} Whether the numeric values in the returned
4107+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
4108+
* `callback` {Function}
4109+
* `err` {Error}
4110+
* `stats` {fs.StatFs}
4111+
4112+
Asynchronous statfs(2). Returns information about the mounted file system which
4113+
contains `path`. The callback gets two arguments `(err, stats)` where `stats`
4114+
is an {fs.StatFs} object.
4115+
4116+
In case of an error, the `err.code` will be one of [Common System Errors][].
4117+
40854118
### `fs.symlink(target, path[, type], callback)`
40864119

40874120
<!-- YAML
@@ -5822,6 +5855,23 @@ changes:
58225855

58235856
Retrieves the {fs.Stats} for the path.
58245857

5858+
### `fs.statfsSync(path[, options])`
5859+
5860+
<!-- YAML
5861+
added: REPLACEME
5862+
-->
5863+
5864+
* `path` {string|Buffer|URL}
5865+
* `options` {Object}
5866+
* `bigint` {boolean} Whether the numeric values in the returned
5867+
{fs.StatFs} object should be `bigint`. **Default:** `false`.
5868+
* Returns: {fs.StatFs}
5869+
5870+
Synchronous statfs(2). Returns information about the mounted file system which
5871+
contains `path`.
5872+
5873+
In case of an error, the `err.code` will be one of [Common System Errors][].
5874+
58255875
### `fs.symlinkSync(target, path[, type])`
58265876

58275877
<!-- YAML
@@ -6908,6 +6958,114 @@ The times in the stat object have the following semantics:
69086958
Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As
69096959
of 0.12, `ctime` is not "creation time", and on Unix systems, it never was.
69106960

6961+
### Class: `fs.StatFs`
6962+
6963+
<!-- YAML
6964+
added: REPLACEME
6965+
-->
6966+
6967+
Provides information about a mounted file system.
6968+
6969+
Objects returned from [`fs.statfs()`][] and its synchronous counterpart are of
6970+
this type. If `bigint` in the `options` passed to those methods is `true`, the
6971+
numeric values will be `bigint` instead of `number`.
6972+
6973+
```console
6974+
StatFs {
6975+
type: 1397114950,
6976+
bsize: 4096,
6977+
blocks: 121938943,
6978+
bfree: 61058895,
6979+
bavail: 61058895,
6980+
files: 999,
6981+
ffree: 1000000
6982+
}
6983+
```
6984+
6985+
`bigint` version:
6986+
6987+
```console
6988+
StatFs {
6989+
type: 1397114950n,
6990+
bsize: 4096n,
6991+
blocks: 121938943n,
6992+
bfree: 61058895n,
6993+
bavail: 61058895n,
6994+
files: 999n,
6995+
ffree: 1000000n
6996+
}
6997+
```
6998+
6999+
#### `statfs.bavail`
7000+
7001+
<!-- YAML
7002+
added: REPLACEME
7003+
-->
7004+
7005+
* {number|bigint}
7006+
7007+
Free blocks available to unprivileged users.
7008+
7009+
#### `statfs.bfree`
7010+
7011+
<!-- YAML
7012+
added: REPLACEME
7013+
-->
7014+
7015+
* {number|bigint}
7016+
7017+
Free blocks in file system.
7018+
7019+
#### `statfs.blocks`
7020+
7021+
<!-- YAML
7022+
added: REPLACEME
7023+
-->
7024+
7025+
* {number|bigint}
7026+
7027+
Total data blocks in file system.
7028+
7029+
#### `statfs.bsize`
7030+
7031+
<!-- YAML
7032+
added: REPLACEME
7033+
-->
7034+
7035+
* {number|bigint}
7036+
7037+
Optimal transfer block size.
7038+
7039+
#### `statfs.ffree`
7040+
7041+
<!-- YAML
7042+
added: REPLACEME
7043+
-->
7044+
7045+
* {number|bigint}
7046+
7047+
Free file nodes in file system.
7048+
7049+
#### `statfs.files`
7050+
7051+
<!-- YAML
7052+
added: REPLACEME
7053+
-->
7054+
7055+
* {number|bigint}
7056+
7057+
Total file nodes in file system.
7058+
7059+
#### `statfs.type`
7060+
7061+
<!-- YAML
7062+
added: REPLACEME
7063+
-->
7064+
7065+
* {number|bigint}
7066+
7067+
Type of file system.
7068+
69117069
### Class: `fs.WriteStream`
69127070

69137071
<!-- YAML
@@ -7751,6 +7909,7 @@ the file contents.
77517909
[`fs.rmSync()`]: #fsrmsyncpath-options
77527910
[`fs.rmdir()`]: #fsrmdirpath-options-callback
77537911
[`fs.stat()`]: #fsstatpath-options-callback
7912+
[`fs.statfs()`]: #fsstatfspath-options-callback
77547913
[`fs.symlink()`]: #fssymlinktarget-path-type-callback
77557914
[`fs.utimes()`]: #fsutimespath-atime-mtime-callback
77567915
[`fs.watch()`]: #fswatchfilename-options-listener

lib/fs.js

+30
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ const {
104104
nullCheck,
105105
preprocessSymlinkDestination,
106106
Stats,
107+
getStatFsFromBinding,
107108
getStatsFromBinding,
108109
realpathCacheKey,
109110
stringToFlags,
@@ -1523,6 +1524,24 @@ function stat(path, options = { bigint: false }, callback) {
15231524
binding.stat(pathModule.toNamespacedPath(path), options.bigint, req);
15241525
}
15251526

1527+
function statfs(path, options = { bigint: false }, callback) {
1528+
if (typeof options === 'function') {
1529+
callback = options;
1530+
options = kEmptyObject;
1531+
}
1532+
callback = maybeCallback(callback);
1533+
path = getValidatedPath(path);
1534+
const req = new FSReqCallback(options.bigint);
1535+
req.oncomplete = (err, stats) => {
1536+
if (err) {
1537+
return callback(err);
1538+
}
1539+
1540+
callback(err, getStatFsFromBinding(stats));
1541+
};
1542+
binding.statfs(pathModule.toNamespacedPath(path), options.bigint, req);
1543+
}
1544+
15261545
function hasNoEntryError(ctx) {
15271546
if (ctx.errno) {
15281547
const uvErr = uvErrmapGet(ctx.errno);
@@ -1597,6 +1616,15 @@ function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {
15971616
return getStatsFromBinding(stats);
15981617
}
15991618

1619+
function statfsSync(path, options = { bigint: false }) {
1620+
path = getValidatedPath(path);
1621+
const ctx = { path };
1622+
const stats = binding.statfs(pathModule.toNamespacedPath(path),
1623+
options.bigint, undefined, ctx);
1624+
handleErrorFromBinding(ctx);
1625+
return getStatFsFromBinding(stats);
1626+
}
1627+
16001628
/**
16011629
* Reads the contents of a symbolic link
16021630
* referred to by `path`.
@@ -3025,7 +3053,9 @@ module.exports = fs = {
30253053
rmdir,
30263054
rmdirSync,
30273055
stat,
3056+
statfs,
30283057
statSync,
3058+
statfsSync,
30293059
symlink,
30303060
symlinkSync,
30313061
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,
@@ -767,6 +768,13 @@ async function stat(path, options = { bigint: false }) {
767768
return getStatsFromBinding(result);
768769
}
769770

771+
async function statfs(path, options = { bigint: false }) {
772+
path = getValidatedPath(path);
773+
const result = await binding.statfs(pathModule.toNamespacedPath(path),
774+
options.bigint, kUsePromises);
775+
return getStatFsFromBinding(result);
776+
}
777+
770778
async function link(existingPath, newPath) {
771779
existingPath = getValidatedPath(existingPath, 'existingPath');
772780
newPath = getValidatedPath(newPath, 'newPath');
@@ -919,6 +927,7 @@ module.exports = {
919927
symlink,
920928
lstat,
921929
stat,
930+
statfs,
922931
link,
923932
unlink,
924933
chmod,

lib/internal/fs/utils.js

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

560+
class StatFs {
561+
constructor(type, bsize, blocks, bfree, bavail, files, ffree) {
562+
this.type = type;
563+
this.bsize = bsize;
564+
this.blocks = blocks;
565+
this.bfree = bfree;
566+
this.bavail = bavail;
567+
this.files = files;
568+
this.ffree = ffree;
569+
}
570+
}
571+
572+
function getStatFsFromBinding(stats) {
573+
return new StatFs(
574+
stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], stats[6]
575+
);
576+
}
577+
560578
function stringToFlags(flags, name = 'flags') {
561579
if (typeof flags === 'number') {
562580
validateInt32(flags, name);
@@ -934,6 +952,7 @@ module.exports = {
934952
nullCheck,
935953
preprocessSymlinkDestination,
936954
realpathCacheKey: Symbol('realpathCacheKey'),
955+
getStatFsFromBinding,
937956
getStatsFromBinding,
938957
stringToFlags,
939958
stringToSymlinkType,

0 commit comments

Comments
 (0)