Skip to content

Commit 87d65c7

Browse files
author
pluris
committed
fs: improve error performance for fdatasyncSync
1 parent 783f64b commit 87d65c7

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

lib/fs.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,10 +1282,7 @@ function fdatasync(fd, callback) {
12821282
* @returns {void}
12831283
*/
12841284
function fdatasyncSync(fd) {
1285-
fd = getValidatedFd(fd);
1286-
const ctx = {};
1287-
binding.fdatasync(fd, undefined, ctx);
1288-
handleErrorFromBinding(ctx);
1285+
syncFs.fdatasync(fd);
12891286
}
12901287

12911288
/**

lib/internal/fs/sync.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ function unlink(path) {
9393
return binding.unlinkSync(path);
9494
}
9595

96+
function fdatasync(fd) {
97+
return binding.fdatasyncSync(fd);
98+
}
99+
96100
module.exports = {
97101
readFileUtf8,
98102
exists,
@@ -103,4 +107,5 @@ module.exports = {
103107
open,
104108
close,
105109
unlink,
110+
fdatasync,
106111
};

src/node_file.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,24 @@ inline int64_t GetOffset(Local<Value> value) {
116116
return IsSafeJsInt(value) ? value.As<Integer>()->Value() : -1;
117117
}
118118

119+
inline int GetValidatedFd(Environment* env, Local<Value> value) {
120+
if (!value->IsInt32()) {
121+
env->isolate()->ThrowException(ERR_INVALID_ARG_TYPE(
122+
env->isolate(), "Invalid argument. The fd must be int32."));
123+
return 1 << 30;
124+
}
125+
126+
const int fd = value.As<Int32>()->Value();
127+
128+
if (fd < 0 || fd > INT32_MAX) {
129+
env->isolate()->ThrowException(ERR_OUT_OF_RANGE(
130+
env->isolate(), "It must be >= 0 && <= INT32_MAX. Received %d", fd));
131+
return 1 << 30;
132+
}
133+
134+
return fd;
135+
}
136+
119137
static const char* get_fs_func_name_by_type(uv_fs_type req_type) {
120138
switch (req_type) {
121139
#define FS_TYPE_TO_NAME(type, name) \
@@ -1618,6 +1636,24 @@ static void Fdatasync(const FunctionCallbackInfo<Value>& args) {
16181636
}
16191637
}
16201638

1639+
static void FdatasyncSync(const FunctionCallbackInfo<Value>& args) {
1640+
Environment* env = Environment::GetCurrent(args);
1641+
1642+
CHECK_EQ(args.Length(), 1);
1643+
1644+
const int fd = GetValidatedFd(env, args[0]);
1645+
if (fd == (1 << 30)) return;
1646+
1647+
uv_fs_t req;
1648+
auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
1649+
FS_SYNC_TRACE_BEGIN(fdatasync);
1650+
int err = uv_fs_fdatasync(nullptr, &req, fd, nullptr);
1651+
FS_SYNC_TRACE_END(fdatasync);
1652+
if (err < 0) {
1653+
return env->ThrowUVException(err, "fdatasync");
1654+
}
1655+
}
1656+
16211657
static void Fsync(const FunctionCallbackInfo<Value>& args) {
16221658
Environment* env = Environment::GetCurrent(args);
16231659

@@ -3393,6 +3429,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33933429
SetMethod(isolate, target, "readFileUtf8", ReadFileUtf8);
33943430
SetMethod(isolate, target, "readBuffers", ReadBuffers);
33953431
SetMethod(isolate, target, "fdatasync", Fdatasync);
3432+
SetMethod(isolate, target, "fdatasyncSync", FdatasyncSync);
33963433
SetMethod(isolate, target, "fsync", Fsync);
33973434
SetMethod(isolate, target, "rename", Rename);
33983435
SetMethod(isolate, target, "ftruncate", FTruncate);
@@ -3519,6 +3556,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
35193556
registry->Register(ReadFileUtf8);
35203557
registry->Register(ReadBuffers);
35213558
registry->Register(Fdatasync);
3559+
registry->Register(FdatasyncSync);
35223560
registry->Register(Fsync);
35233561
registry->Register(Rename);
35243562
registry->Register(FTruncate);

typings/internalBinding/fs.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ declare namespace InternalFSBinding {
8484
function fdatasync(fd: number, req: FSReqCallback): void;
8585
function fdatasync(fd: number, req: undefined, ctx: FSSyncContext): void;
8686
function fdatasync(fd: number, usePromises: typeof kUsePromises): Promise<void>;
87+
function fdatasyncSync(fd: number): void;
8788

8889
function fstat(fd: number, useBigint: boolean, req: FSReqCallback<Float64Array | BigUint64Array>): void;
8990
function fstat(fd: number, useBigint: true, req: FSReqCallback<BigUint64Array>): void;

0 commit comments

Comments
 (0)