Skip to content

Commit 4dd609c

Browse files
Ethan-Arrowoodruyadorno
authored andcommitted
fs: fix bufferSize option for opendir recursive
The bufferSize option was not respected in recursive mode. This PR implements a naive solution to fix this issue until a better implementation can be designed. Fixes: #48820 PR-URL: #55744 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent a30defe commit 4dd609c

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

lib/internal/fs/dir.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,16 @@ class Dir {
164164
return;
165165
}
166166

167-
const result = handle.read(
167+
// Fully read the directory and buffer the entries.
168+
// This is a naive solution and for very large sub-directories
169+
// it can even block the event loop. Essentially, `bufferSize` is
170+
// not respected for recursive mode. This is a known limitation.
171+
// Issue to fix: https://github.com/nodejs/node/issues/55764
172+
let result;
173+
while ((result = handle.read(
168174
this.#options.encoding,
169175
this.#options.bufferSize,
170-
);
171-
172-
if (result) {
176+
))) {
173177
this.processReadResult(path, result);
174178
}
175179

test/sequential/test-fs-opendir-recursive.js

+19
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ function getDirentPath(dirent) {
132132
}
133133

134134
function assertDirents(dirents) {
135+
assert.strictEqual(dirents.length, expected.length);
135136
dirents.sort((a, b) => (getDirentPath(a) < getDirentPath(b) ? -1 : 1));
136137
assert.deepStrictEqual(
137138
dirents.map((dirent) => {
@@ -221,3 +222,21 @@ function processDirCb(dir, cb) {
221222

222223
test().then(common.mustCall());
223224
}
225+
226+
// Issue https://github.com/nodejs/node/issues/48820 highlights that
227+
// opendir recursive does not properly handle the buffer size option.
228+
// This test asserts that the buffer size option is respected.
229+
{
230+
const dir = fs.opendirSync(testDir, { bufferSize: 1, recursive: true });
231+
processDirSync(dir);
232+
dir.closeSync();
233+
}
234+
235+
{
236+
fs.opendir(testDir, { recursive: true, bufferSize: 1 }, common.mustSucceed((dir) => {
237+
processDirCb(dir, common.mustSucceed((dirents) => {
238+
assertDirents(dirents);
239+
dir.close(common.mustSucceed());
240+
}));
241+
}));
242+
}

0 commit comments

Comments
 (0)