Skip to content

Commit 9d706c7

Browse files
authored
WasmFS JS API: Implement allocate (#19602)
Also change the type of the __syscall_fallocate to use int64_t instead of uint64_t so that negative numbers would correctly throw error handling. With uint64_t setSize() would abort without an error code, since it was interpreting negative numbers incorrectly. Now, the syscall correctly returns an error code if either offset or length is negative.
1 parent b67283d commit 9d706c7

File tree

6 files changed

+64
-16
lines changed

6 files changed

+64
-16
lines changed

emcc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,7 @@ def phase_linker_setup(options, state, newargs):
23262326
'_wasmfs_read_file',
23272327
'_wasmfs_write_file',
23282328
'_wasmfs_open',
2329+
'_wasmfs_allocate',
23292330
'_wasmfs_close',
23302331
'_wasmfs_write',
23312332
'_wasmfs_pwrite',

src/library_wasmfs.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ FS.createPreloadedFile = FS_createPreloadedFile;
177177

178178
return bytesRead;
179179
},
180-
// TODO: allocate
180+
allocate: (stream, offset, length) => {
181+
return FS.handleError(__wasmfs_allocate(stream.fd, {{{ splitI64('offset') }}}, {{{ splitI64('length') }}}));
182+
},
181183
// TODO: mmap
182184
// TODO: msync
183185
// TODO: munmap

system/lib/libc/musl/arch/emscripten/syscall_arch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ int __syscall_fchmodat(int dirfd, intptr_t path, int mode, ...);
9696
int __syscall_faccessat(int dirfd, intptr_t path, int amode, int flags);
9797
int __syscall_pselect6(int nfds, intptr_t readfds, intptr_t writefds, intptr_t exceptfds, intptr_t timeout, intptr_t sigmaks);
9898
int __syscall_utimensat(int dirfd, intptr_t path, intptr_t times, int flags);
99-
int __syscall_fallocate(int fd, int mode, uint64_t off, uint64_t len);
99+
int __syscall_fallocate(int fd, int mode, int64_t off, int64_t len);
100100
int __syscall_dup3(int fd, int suggestfd, int flags);
101101
int __syscall_pipe2(intptr_t fds, int flags);
102102
int __syscall_recvmmsg(int sockfd, intptr_t msgvec, size_t vlen, int flags, ...);

system/lib/wasmfs/js_api.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ int _wasmfs_open(char* path, int flags, mode_t mode) {
129129
return __syscall_openat(AT_FDCWD, (intptr_t)path, flags, mode);
130130
}
131131

132+
int _wasmfs_allocate(int fd, int64_t off, int64_t len) {
133+
return __syscall_fallocate(fd, 0, off, len);
134+
}
135+
132136
int _wasmfs_mknod(char* path, mode_t mode, dev_t dev) {
133137
return __syscall_mknodat(AT_FDCWD, (intptr_t)path, mode, dev);
134138
}

system/lib/wasmfs/syscalls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ int __syscall_poll(intptr_t fds_, int nfds, int timeout) {
13581358
return nonzero;
13591359
}
13601360

1361-
int __syscall_fallocate(int fd, int mode, uint64_t off, uint64_t len) {
1361+
int __syscall_fallocate(int fd, int mode, int64_t off, int64_t len) {
13621362
assert(mode == 0); // TODO, but other modes were never supported in the old FS
13631363

13641364
auto fileTable = wasmFS.getFileTable().locked();

test/fs/test_fs_js_api.c

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,46 @@
44
#include <assert.h>
55
#include <fcntl.h>
66

7+
void test_fs_allocate() {
8+
EM_ASM(
9+
FS.writeFile("allocatetestfile", 'a=1\nb=2\n');
10+
);
11+
struct stat allocateStat;
12+
stat("allocatetestfile", &allocateStat);
13+
assert(allocateStat.st_size == 8);
14+
15+
EM_ASM(
16+
// Allocate more space at the very end.
17+
var stream = FS.open("allocatetestfile", "w");
18+
FS.allocate(stream, 8, 10);
19+
);
20+
stat("allocatetestfile", &allocateStat);
21+
assert(allocateStat.st_size == 18);
22+
23+
EM_ASM(
24+
// Reduce allocated space at the very start.
25+
var stream = FS.open("allocatetestfile", "w");
26+
FS.allocate(stream, 0, 4);
27+
);
28+
stat("allocatetestfile", &allocateStat);
29+
assert(allocateStat.st_size == 4);
30+
31+
EM_ASM(
32+
var stream = FS.open("allocatetestfile", "w");
33+
34+
var ex;
35+
try {
36+
// Attempt to allocate negative length.
37+
FS.allocate(stream, 0, -1);
38+
} catch (err) {
39+
ex = err;
40+
}
41+
assert(ex.name === "ErrnoError" && ex.errno === 28 /* EINVAL */);
42+
);
43+
44+
remove("allocatetestfile");
45+
}
46+
747
void test_fs_truncate() {
848
EM_ASM(
949
FS.writeFile('truncatetest', 'a=1\nb=2\n');
@@ -182,12 +222,11 @@ int main() {
182222
FS.mkdir('/dir2');
183223
);
184224

185-
struct stat s;
186-
stat("/dir1", &s);
187-
assert(S_ISDIR(s.st_mode));
188-
stat("/dir2", &s);
189-
assert(S_ISDIR(s.st_mode));
190-
225+
struct stat rmdirStat;
226+
stat("/dir1", &rmdirStat);
227+
assert(S_ISDIR(rmdirStat.st_mode));
228+
stat("/dir2", &rmdirStat);
229+
assert(S_ISDIR(rmdirStat.st_mode));
191230

192231
EM_ASM(
193232
// Remove the multiple directories
@@ -255,15 +294,17 @@ int main() {
255294

256295
FS.create("createtest", 0400); /* S_IRUSR */
257296
);
258-
struct stat stats;
259-
stat("mknodtest", &stats);
297+
struct stat mknodStats;
298+
stat("mknodtest", &mknodStats);
299+
300+
assert(S_ISREG(mknodStats.st_mode));
301+
assert(mknodStats.st_mode & 0777);
260302

261-
assert(S_ISREG(stats.st_mode));
262-
assert(stats.st_mode & 0777);
303+
stat("createtest", &mknodStats);
304+
assert(S_ISREG(mknodStats.st_mode));
305+
assert(mknodStats.st_mode & 0400);
263306

264-
stat("createtest", &stats);
265-
assert(S_ISREG(stats.st_mode));
266-
assert(stats.st_mode & 0400);
307+
test_fs_allocate();
267308

268309
test_fs_truncate();
269310

0 commit comments

Comments
 (0)