Skip to content

Commit c3049ae

Browse files
Cloudflare Workspace Agentaron-cf
authored andcommitted
wsd: avoid this binding in ftruncate
1 parent 4799ada commit c3049ae

2 files changed

Lines changed: 73 additions & 48 deletions

File tree

packages/wsd/src/fuse/driver.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,3 +1023,24 @@ test("xattr: getxattr for a VFS-backed file returns correct codes", async () =>
10231023
// removexattr returns ENODATA.
10241024
expect(await status((cb) => ops.removexattr("/xattr-backed.txt", "user.x", cb))).toBe(-61);
10251025
});
1026+
1027+
test("FUSE ftruncate does not depend on fuse-native binding this", async () => {
1028+
const { vfs } = await createNodeVirtualFileSystem();
1029+
const ops = makeFUSEOps(vfs);
1030+
1031+
const create = await callback((cb: (errno: number, result: unknown) => void) =>
1032+
ops.create("/ftruncate-this.txt", 0o644, cb),
1033+
);
1034+
expect(create.errno).toBe(0);
1035+
const fh = create.result as number;
1036+
1037+
const payload = Buffer.from("abcdef", "utf8");
1038+
expect(
1039+
await status((cb) => ops.write("/ftruncate-this.txt", fh, payload, payload.byteLength, 0, cb)),
1040+
).toBe(payload.byteLength);
1041+
1042+
const ftruncate = ops.ftruncate;
1043+
expect(await status((cb) => ftruncate.call(undefined, "/ftruncate-this.txt", fh, 3, cb))).toBe(0);
1044+
expect(await status((cb) => ops.flush("/ftruncate-this.txt", fh, cb))).toBe(0);
1045+
expect(Buffer.from(vfs.readFileSync("/ftruncate-this.txt")).toString("utf8")).toBe("abc");
1046+
});

packages/wsd/src/fuse/driver.ts

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,56 @@ export function makeFUSEOps(vfs: NodeVirtualFileSystem, mountPoint = "/"): FuseO
387387
}
388388
};
389389

390+
const truncatePath = (path: string, size: number, cb: StatusCallback): void => {
391+
if (!exists(path)) {
392+
cb(ERRNO.ENOENT);
393+
return;
394+
}
395+
let entry = files.get(path);
396+
if (entry === undefined) {
397+
if (hasDirectWrites) {
398+
if (size > MAX_FILE_BYTES) {
399+
cb(ERRNO.EFBIG);
400+
return;
401+
}
402+
try {
403+
directWriteVfs.truncateFileSync?.(toVfs(path), size);
404+
cb(0);
405+
} catch (error) {
406+
cb(toErrno(error));
407+
}
408+
return;
409+
}
410+
try {
411+
const data = vfs.readFileSync(toVfs(path));
412+
entry = {
413+
buf: data,
414+
size: data.length,
415+
dirty: false,
416+
dirtyRanges: [],
417+
pendingCreate: false,
418+
mode: modeFromVfs(path),
419+
pendingMtime: new Date(),
420+
};
421+
files.set(path, entry);
422+
} catch (error) {
423+
cb(toErrno(error));
424+
return;
425+
}
426+
}
427+
if (size > entry.size) {
428+
if (!ensureCapacity(entry, size)) {
429+
cb(ERRNO.EFBIG);
430+
return;
431+
}
432+
entry.buf.fill(0, entry.size, size);
433+
}
434+
const previousSize = entry.size;
435+
entry.size = size;
436+
markDirty(entry, Math.min(previousSize, size), Math.max(previousSize, size));
437+
cb(0);
438+
};
439+
390440
const warnedOperations = new Set<string>();
391441
const notImplemented = (operation: string): NotImplementedOperation => {
392442
return (...args: unknown[]) => {
@@ -687,57 +737,11 @@ export function makeFUSEOps(vfs: NodeVirtualFileSystem, mountPoint = "/"): FuseO
687737
},
688738

689739
truncate(path, size, cb) {
690-
if (!exists(path)) {
691-
cb(ERRNO.ENOENT);
692-
return;
693-
}
694-
let entry = files.get(path);
695-
if (entry === undefined) {
696-
if (hasDirectWrites) {
697-
if (size > MAX_FILE_BYTES) {
698-
cb(ERRNO.EFBIG);
699-
return;
700-
}
701-
try {
702-
directWriteVfs.truncateFileSync?.(toVfs(path), size);
703-
cb(0);
704-
} catch (error) {
705-
cb(toErrno(error));
706-
}
707-
return;
708-
}
709-
try {
710-
const data = vfs.readFileSync(toVfs(path));
711-
entry = {
712-
buf: data,
713-
size: data.length,
714-
dirty: false,
715-
dirtyRanges: [],
716-
pendingCreate: false,
717-
mode: modeFromVfs(path),
718-
pendingMtime: new Date(),
719-
};
720-
files.set(path, entry);
721-
} catch (error) {
722-
cb(toErrno(error));
723-
return;
724-
}
725-
}
726-
if (size > entry.size) {
727-
if (!ensureCapacity(entry, size)) {
728-
cb(ERRNO.EFBIG);
729-
return;
730-
}
731-
entry.buf.fill(0, entry.size, size);
732-
}
733-
const previousSize = entry.size;
734-
entry.size = size;
735-
markDirty(entry, Math.min(previousSize, size), Math.max(previousSize, size));
736-
cb(0);
740+
truncatePath(path, size, cb);
737741
},
738742

739743
ftruncate(path, _fh, size, cb) {
740-
this.truncate(path, size, cb);
744+
truncatePath(path, size, cb);
741745
},
742746

743747
unlink(path, cb) {

0 commit comments

Comments
 (0)