Skip to content

Commit 0a42200

Browse files
committed
[WasmFS] Create public wasmfs_mount function
We already had `wasmfs_unmount` so it seems logical we should have this one too. This is designed to replace `wasmfs_create_directory` which has a rather misleading name. I have left `wasmfs_create_directory` around for now but is simply combination of `mkdir` + `mount` (which is essentially what is was doing already). This change ends up simplifying `doMkdir` which no longer needs to take a backend argument.
1 parent 8af2200 commit 0a42200

File tree

6 files changed

+51
-49
lines changed

6 files changed

+51
-49
lines changed

src/lib/libwasmfs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ addToLibrary({
348348
}
349349
#endif
350350
var backendPointer = type.createBackend(opts);
351-
return FS.handleError(withStackSave(() => __wasmfs_mount(stringToUTF8OnStack(mountpoint), backendPointer)));
351+
return FS.handleError(withStackSave(() => _wasmfs_mount(stringToUTF8OnStack(mountpoint), backendPointer)));
352352
},
353353
unmount: (mountpoint) => (
354354
FS.handleError(withStackSave(() => _wasmfs_unmount(stringToUTF8OnStack(mountpoint))))

system/include/emscripten/wasmfs.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ backend_t wasmfs_get_backend_by_fd(int fd);
2929
// TODO: Remove this function so that only directories can be mounted.
3030
int wasmfs_create_file(const char* pathname __attribute__((nonnull)), mode_t mode, backend_t backend);
3131

32-
// Creates a new directory using a specific backend.
33-
// Returns 0 on success like `mkdir`, or a negative value on error.
34-
// TODO: Add an alias with wasmfs_mount.
32+
// Legacy function. This function works like `mkdir` + `wasmfs_mount`.
3533
int wasmfs_create_directory(const char* path __attribute__((nonnull)), mode_t mode, backend_t backend);
3634

35+
// Mount a backend at a given location in the filesystem
36+
// `path` must be an existing directory.
37+
int wasmfs_mount(const char* path __attribute__((nonnull)), backend_t backend);
38+
3739
// Unmounts the directory (Which must be a valid mountpoint) at a specific path.
3840
// Returns 0 on success, or a negative value on error.
3941
int wasmfs_unmount(const char* path __attribute__((nonnull)));

system/lib/wasmfs/js_api.cpp

-15
Original file line numberDiff line numberDiff line change
@@ -277,21 +277,6 @@ int _wasmfs_lstat(const char* path, struct stat* statBuf) {
277277
return __syscall_lstat64((intptr_t)path, (intptr_t)statBuf);
278278
}
279279

280-
// The legacy JS API requires a mountpoint to already exist, so WasmFS will
281-
// attempt to remove the target directory if it exists before replacing it with
282-
// a mounted directory.
283-
int _wasmfs_mount(const char* path, ::backend_t created_backend) {
284-
int err = __syscall_rmdir((intptr_t)path);
285-
286-
// The legacy JS API mount requires the directory to already exist, but we
287-
// will also allow it to be missing.
288-
if (err && err != -ENOENT) {
289-
return err;
290-
}
291-
292-
return wasmfs_create_directory(path, 0777, created_backend);
293-
}
294-
295280
// Helper method that identifies what a path is:
296281
// ENOENT - if nothing exists there
297282
// EISDIR - if it is a directory

system/lib/wasmfs/syscalls.cpp

+43-28
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,7 @@ int __syscall_mknodat(int dirfd, intptr_t path, int mode, int dev) {
597597
OpenReturnMode::Nothing);
598598
}
599599

600-
static int
601-
doMkdir(path::ParsedParent parsed, int mode, backend_t backend = NullBackend) {
600+
static int doMkdir(path::ParsedParent parsed, int mode) {
602601
if (auto err = parsed.getError()) {
603602
return err;
604603
}
@@ -624,41 +623,57 @@ doMkdir(path::ParsedParent parsed, int mode, backend_t backend = NullBackend) {
624623
return -EACCES;
625624
}
626625

627-
// By default, the backend that the directory is created in is the same as
628-
// the parent directory. However, if a backend is passed as a parameter,
629-
// then that backend is used.
630-
if (!backend) {
631-
backend = parent->getBackend();
626+
if (!lockedParent.insertDirectory(childName, mode)) {
627+
// TODO Receive a specific error code, and report it here. For now, report
628+
// a generic error.
629+
return -EIO;
632630
}
633631

634-
if (backend == parent->getBackend()) {
635-
if (!lockedParent.insertDirectory(childName, mode)) {
636-
// TODO Receive a specific error code, and report it here. For now, report
637-
// a generic error.
638-
return -EIO;
639-
}
640-
} else {
641-
auto created = backend->createDirectory(mode);
642-
if (!created) {
643-
// TODO Receive a specific error code, and report it here. For now, report
644-
// a generic error.
645-
return -EIO;
646-
}
647-
[[maybe_unused]] bool mounted = lockedParent.mountChild(childName, created);
648-
assert(mounted);
632+
// TODO: Check that the insertion is successful.
633+
634+
return 0;
635+
}
636+
637+
int wasmfs_mount(const char* path, backend_t backend) {
638+
path::ParsedParent parsed = path::parseParent(path);
639+
if (auto err = parsed.getError()) {
640+
return err;
649641
}
642+
auto& [parent, childNameView] = parsed.getParentChild();
643+
auto lockedParent = parent->locked();
644+
std::string childName(childNameView);
650645

651-
// TODO: Check that the insertion is successful.
646+
// Child must exist and must be directory
647+
auto child = lockedParent.getChild(childName);
648+
if (!child) {
649+
return -EEXIST;
650+
}
651+
if (!child->dynCast<Directory>()) {
652+
return -ENOTDIR;
653+
}
654+
655+
auto created = backend->createDirectory(0777);
656+
if (!created) {
657+
// TODO Receive a specific error code, and report it here. For now, report
658+
// a generic error.
659+
return -EIO;
660+
}
661+
[[maybe_unused]] bool mounted = lockedParent.mountChild(childName, created);
662+
assert(mounted);
652663

653664
return 0;
654665
}
655666

656-
// This function is exposed to users and allows users to specify a particular
657-
// backend that a directory should be created within.
658-
int wasmfs_create_directory(char* path, int mode, backend_t backend) {
659-
static_assert(std::is_same_v<decltype(doMkdir(0, 0, 0)), int>,
667+
// Legacy function, use wasmfs_mount instead.
668+
int wasmfs_create_directory(const char* path, int mode, backend_t backend) {
669+
static_assert(std::is_same_v<decltype(doMkdir(0, 0)), int>,
660670
"unexpected conversion from result of doMkdir to int");
661-
return doMkdir(path::parseParent(path), mode, backend);
671+
int rtn = doMkdir(path::parseParent(path), mode);
672+
if (rtn != 0) {
673+
return rtn;
674+
}
675+
676+
return wasmfs_mount(path, backend);
662677
}
663678

664679
// TODO: Test this.

test/test_core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9650,7 +9650,7 @@ def setUp(self):
96509650

96519651
simd2 = make_run('simd2', emcc_args=['-O2', '-msimd128'])
96529652
bulkmem2 = make_run('bulkmem2', emcc_args=['-O2', '-mbulk-memory'])
9653-
wasmfs = make_run('wasmfs', emcc_args=['-O2', '-DWASMFS'], settings={'WASMFS': 1})
9653+
wasmfs = make_run('wasmfs', emcc_args=['-g', '-DWASMFS'], settings={'WASMFS': 1})
96549654

96559655
# SAFE_HEAP/STACK_OVERFLOW_CHECK
96569656
core0s = make_run('core2s', emcc_args=['-g'], settings={'SAFE_HEAP': 1})

tools/link.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ def phase_linker_setup(options, linker_args): # noqa: C901, PLR0912, PLR0915
12651265
'emscripten_builtin_memalign',
12661266
'wasmfs_create_file',
12671267
'wasmfs_unmount',
1268-
'_wasmfs_mount',
1268+
'wasmfs_mount',
12691269
'_wasmfs_read_file',
12701270
'_wasmfs_write_file',
12711271
'_wasmfs_open',

0 commit comments

Comments
 (0)