Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WasmFS JS API: Implement allocate #19602

Merged
merged 13 commits into from
Jun 14, 2023
1 change: 1 addition & 0 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2326,6 +2326,7 @@ def phase_linker_setup(options, state, newargs):
'_wasmfs_read_file',
'_wasmfs_write_file',
'_wasmfs_open',
'_wasmfs_allocate',
'_wasmfs_close',
'_wasmfs_write',
'_wasmfs_pwrite',
Expand Down
4 changes: 3 additions & 1 deletion src/library_wasmfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ FS.createPreloadedFile = FS_createPreloadedFile;

return bytesRead;
},
// TODO: allocate
allocate: (stream, offset, length) => {
return FS.handleError(__wasmfs_allocate(stream.fd, {{{ splitI64('offset') }}}, {{{ splitI64('length') }}}));
},
// TODO: mmap
// TODO: msync
// TODO: munmap
Expand Down
2 changes: 1 addition & 1 deletion system/lib/libc/musl/arch/emscripten/syscall_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ int __syscall_fchmodat(int dirfd, intptr_t path, int mode, ...);
int __syscall_faccessat(int dirfd, intptr_t path, int amode, int flags);
int __syscall_pselect6(int nfds, intptr_t readfds, intptr_t writefds, intptr_t exceptfds, intptr_t timeout, intptr_t sigmaks);
int __syscall_utimensat(int dirfd, intptr_t path, intptr_t times, int flags);
int __syscall_fallocate(int fd, int mode, uint64_t off, uint64_t len);
int __syscall_fallocate(int fd, int mode, int64_t off, int64_t len);
int __syscall_dup3(int fd, int suggestfd, int flags);
int __syscall_pipe2(intptr_t fds, int flags);
int __syscall_recvmmsg(int sockfd, intptr_t msgvec, size_t vlen, int flags, ...);
Expand Down
4 changes: 4 additions & 0 deletions system/lib/wasmfs/js_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ int _wasmfs_open(char* path, int flags, mode_t mode) {
return __syscall_openat(AT_FDCWD, (intptr_t)path, flags, mode);
}

int _wasmfs_allocate(int fd, int64_t off, int64_t len) {
return __syscall_fallocate(fd, 0, off, len);
}

int _wasmfs_mknod(char* path, mode_t mode, dev_t dev) {
return __syscall_mknodat(AT_FDCWD, (intptr_t)path, mode, dev);
}
Expand Down
2 changes: 1 addition & 1 deletion system/lib/wasmfs/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,7 +1358,7 @@ int __syscall_poll(intptr_t fds_, int nfds, int timeout) {
return nonzero;
}

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

auto fileTable = wasmFS.getFileTable().locked();
Expand Down
67 changes: 54 additions & 13 deletions test/fs/test_fs_js_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@
#include <assert.h>
#include <fcntl.h>

void test_fs_allocate() {
EM_ASM(
FS.writeFile("allocatetestfile", 'a=1\nb=2\n');
);
struct stat allocateStat;
stat("allocatetestfile", &allocateStat);
assert(allocateStat.st_size == 8);

EM_ASM(
jameshu15869 marked this conversation as resolved.
Show resolved Hide resolved
// Allocate more space at the very end.
var stream = FS.open("allocatetestfile", "w");
FS.allocate(stream, 8, 10);
);
stat("allocatetestfile", &allocateStat);
assert(allocateStat.st_size == 18);

EM_ASM(
// Reduce allocated space at the very start.
var stream = FS.open("allocatetestfile", "w");
FS.allocate(stream, 0, 4);
);
stat("allocatetestfile", &allocateStat);
assert(allocateStat.st_size == 4);

EM_ASM(
var stream = FS.open("allocatetestfile", "w");

var ex;
try {
// Attempt to allocate negative length.
FS.allocate(stream, 0, -1);
} catch (err) {
ex = err;
}
assert(ex.name === "ErrnoError" && ex.errno === 28 /* EINVAL */);
);

remove("allocatetestfile");
}

void test_fs_truncate() {
EM_ASM(
FS.writeFile('truncatetest', 'a=1\nb=2\n');
Expand Down Expand Up @@ -182,12 +222,11 @@ int main() {
FS.mkdir('/dir2');
);

struct stat s;
stat("/dir1", &s);
assert(S_ISDIR(s.st_mode));
stat("/dir2", &s);
assert(S_ISDIR(s.st_mode));

struct stat rmdirStat;
stat("/dir1", &rmdirStat);
assert(S_ISDIR(rmdirStat.st_mode));
stat("/dir2", &rmdirStat);
assert(S_ISDIR(rmdirStat.st_mode));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the reason for the name change is to avoid a collision, another option is to add a scope,

{
   struct stat s;
  ..
}

But the more explicit name also seems good by itself, either sgtm.

Or, it might be nice to split up the tests into their own functions, as the new test here.

Copy link
Contributor Author

@jameshu15869 jameshu15869 Jun 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was some collision after merging in the other tests, but I did move each test to its own function in the utime PR after a suggestion from Sam, so the collision should be fixed (#19561). I was originally planning on changing the names back to struct stat s after the tests as individual functions are merged in.


EM_ASM(
// Remove the multiple directories
Expand Down Expand Up @@ -255,15 +294,17 @@ int main() {

FS.create("createtest", 0400); /* S_IRUSR */
);
struct stat stats;
stat("mknodtest", &stats);
struct stat mknodStats;
stat("mknodtest", &mknodStats);

assert(S_ISREG(mknodStats.st_mode));
assert(mknodStats.st_mode & 0777);

assert(S_ISREG(stats.st_mode));
assert(stats.st_mode & 0777);
stat("createtest", &mknodStats);
assert(S_ISREG(mknodStats.st_mode));
assert(mknodStats.st_mode & 0400);

stat("createtest", &stats);
assert(S_ISREG(stats.st_mode));
assert(stats.st_mode & 0400);
test_fs_allocate();

test_fs_truncate();

Expand Down