Skip to content

WasmFS: Add nanosecond support to WasmFS #19629

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

Merged
merged 27 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fe411a3
implement utime and test, need to clarify details
jameshu15869 Jun 2, 2023
af6d66e
debug comments
jameshu15869 Jun 5, 2023
9a05071
add nanosecond support in wasmfs
jameshu15869 Jun 8, 2023
fbf1c46
fix comment
jameshu15869 Jun 8, 2023
15472d4
Merge branch 'main' into library-wasmfs-utime
jameshu15869 Jun 8, 2023
a958cb8
fix merge conflict
jameshu15869 Jun 9, 2023
bcf6630
refactor test_fs_js_api
jameshu15869 Jun 9, 2023
e9b362f
clean up and combine getters/setters
jameshu15869 Jun 9, 2023
04d816c
Merge branch 'main' into library-wasmfs-utime
jameshu15869 Jun 12, 2023
9bb61f9
change times to timespec
jameshu15869 Jun 12, 2023
d5cbd35
Merge branch 'library-wasmfs-utime' of https://github.com/jameshu1586…
jameshu15869 Jun 12, 2023
86843e5
Merge branch 'main' into library-wasmfs-utime
jameshu15869 Jun 12, 2023
f2670fb
update metadce files
jameshu15869 Jun 12, 2023
3ceae4c
Merge branch 'main' into library-wasmfs-utime
jameshu15869 Jun 13, 2023
261d52c
update metadata
jameshu15869 Jun 13, 2023
45db5be
add update to current time methods
jameshu15869 Jun 13, 2023
8148d76
fix merge conflicts
jameshu15869 Jun 13, 2023
0bfe926
fix merge conflicts
jameshu15869 Jun 14, 2023
0a10680
fix merge conflicts
jameshu15869 Jun 14, 2023
e406056
fix merge conflicts
jameshu15869 Jun 14, 2023
8b19a73
clean up whitespace
jameshu15869 Jun 14, 2023
83dd598
clean up:
jameshu15869 Jun 14, 2023
f00e4ad
fix merge conflicts
jameshu15869 Jun 16, 2023
637a150
bring back ns test
jameshu15869 Jun 16, 2023
5fea440
remove todo
jameshu15869 Jun 20, 2023
738b3ba
fix merge conflicts
jameshu15869 Jun 20, 2023
a0058d9
Merge branch 'main' into library-wasmfs-utime-ns
kripken Jun 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions system/lib/wasmfs/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Directory::Handle::insertDataFile(const std::string& name, mode_t mode) {
return nullptr;
}
cacheChild(name, child, DCacheKind::Normal);
setMTime(time(NULL));
updateMTime();
return child;
}

Expand All @@ -115,7 +115,7 @@ Directory::Handle::insertDirectory(const std::string& name, mode_t mode) {
return nullptr;
}
cacheChild(name, child, DCacheKind::Normal);
setMTime(time(NULL));
updateMTime();
return child;
}

Expand All @@ -131,7 +131,7 @@ Directory::Handle::insertSymlink(const std::string& name,
return nullptr;
}
cacheChild(name, child, DCacheKind::Normal);
setMTime(time(NULL));
updateMTime();
return child;
}

Expand Down Expand Up @@ -181,9 +181,8 @@ int Directory::Handle::insertMove(const std::string& name,
file->locked().setParent(getDir());

// TODO: Moving mount points probably shouldn't update the mtime.
auto now = time(NULL);
oldParent->locked().setMTime(now);
setMTime(now);
oldParent->locked().updateMTime();
updateMTime();

return 0;
}
Expand All @@ -204,7 +203,7 @@ int Directory::Handle::removeChild(const std::string& name) {
entry->second.file->locked().setParent(nullptr);
dcache.erase(entry);
}
setMTime(time(NULL));
updateMTime();
return 0;
}

Expand Down
53 changes: 43 additions & 10 deletions system/lib/wasmfs/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <variant>
#include <vector>
#include <wasi/api.h>
#include <time.h>

namespace wasmfs {

Expand Down Expand Up @@ -96,7 +97,9 @@ class File : public std::enable_shared_from_this<File> {
protected:
File(FileKind kind, mode_t mode, backend_t backend)
: kind(kind), mode(mode), backend(backend) {
atime = mtime = ctime = time(NULL);
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
atime = mtime = ctime = ts;
}

// A mutex is needed for multiple accesses to the same file.
Expand All @@ -108,9 +111,9 @@ class File : public std::enable_shared_from_this<File> {

mode_t mode = 0; // User and group mode bits for access permission.

time_t atime = 0; // Time when the content was last accessed.
time_t mtime = 0; // Time when the file content was last modified.
time_t ctime = 0; // Time when the file node was last modified.
struct timespec atime; // Time when the content was last accessed.
struct timespec mtime; // Time when the file content was last modified.
struct timespec ctime; // Time when the file node was last modified.

// Reference to parent of current file node. This can be used to
// traverse up the directory tree. A weak_ptr ensures that the ref
Expand Down Expand Up @@ -314,12 +317,42 @@ class File::Handle {
// directory, for example).
file->mode = (file->mode & S_IFMT) | (mode & ~S_IFMT);
}
time_t getCTime() { return file->ctime; }
void setCTime(time_t time) { file->ctime = time; }
time_t getMTime() { return file->mtime; }
void setMTime(time_t time) { file->mtime = time; }
time_t getATime() { return file->atime; }
void setATime(time_t time) { file->atime = time; }
struct timespec getCTime() {
return file->ctime;
}
void setCTime(struct timespec time) {
file->ctime = time;
}
// updateCTime() updates the ctime to the current time.
void updateCTime() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
file->ctime = ts;
}
struct timespec getMTime() {
return file->mtime;
}
void setMTime(struct timespec time) {
file->mtime = time;
}
// updateMTime() updates the mtime to the current time.
void updateMTime() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
file->mtime = ts;
}
struct timespec getATime() {
return file->atime;
}
void setATime(struct timespec time) {
file->atime = time;
}
// updateATime() updates the atime to the current time.
void updateATime() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
file->atime = ts;
}

// Note: parent.lock() creates a new shared_ptr to the same Directory
// specified by the parent weak_ptr.
Expand Down
31 changes: 17 additions & 14 deletions system/lib/wasmfs/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <utility>
#include <vector>
#include <wasi/api.h>
#include <time.h>

#include "backend.h"
#include "file.h"
Expand Down Expand Up @@ -167,7 +168,7 @@ static __wasi_errno_t writeAtOffset(OffsetHandling setOffset,
lockedOpenFile.setPosition(offset + bytesWritten);
}
if (bytesWritten) {
lockedFile.setMTime(time(NULL));
lockedFile.updateMTime();
}
return __WASI_ERRNO_SUCCESS;
}
Expand Down Expand Up @@ -383,9 +384,9 @@ int __syscall_newfstatat(int dirfd, intptr_t path, intptr_t buf, int flags) {
buffer->st_blocks = (buffer->st_size + 511) / 512;
// Specifies the preferred blocksize for efficient disk I/O.
buffer->st_blksize = 4096;
buffer->st_atim.tv_sec = lockedFile.getATime();
buffer->st_mtim.tv_sec = lockedFile.getMTime();
buffer->st_ctim.tv_sec = lockedFile.getCTime();
buffer->st_atim = lockedFile.getATime();
buffer->st_mtim = lockedFile.getMTime();
buffer->st_ctim = lockedFile.getCTime();
return __WASI_ERRNO_SUCCESS;
}

Expand Down Expand Up @@ -1093,21 +1094,23 @@ int __syscall_utimensat(int dirFD, intptr_t path_, intptr_t times_, int flags) {
return err;
}

// TODO: Set tv_nsec (nanoseconds) as well.
// TODO: Handle tv_nsec being UTIME_NOW or UTIME_OMIT.
// TODO: Check for write access to the file (see man page for specifics).
time_t aSeconds, mSeconds;
struct timespec aTime, mTime;

if (times == NULL) {
aSeconds = time(NULL);
mSeconds = aSeconds;
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
aTime = ts;
mTime = ts;
} else {
aSeconds = times[0].tv_sec;
mSeconds = times[1].tv_sec;
aTime = times[0];
mTime = times[1];
}

auto locked = parsed.getFile()->locked();
locked.setATime(aSeconds);
locked.setMTime(mSeconds);
locked.setATime(aTime);
locked.setMTime(mTime);

return 0;
}
Expand All @@ -1131,7 +1134,7 @@ int __syscall_fchmodat(int dirfd, intptr_t path, int mode, ...) {
auto lockedFile = parsed.getFile()->locked();
lockedFile.setMode(mode);
// On POSIX, ctime is updated on metadata changes, like chmod.
lockedFile.setCTime(time(NULL));
lockedFile.updateCTime();
return 0;
}

Expand All @@ -1146,7 +1149,7 @@ int __syscall_fchmod(int fd, int mode) {
}
auto lockedFile = openFile->locked().getFile()->locked();
lockedFile.setMode(mode);
lockedFile.setCTime(time(NULL));
lockedFile.updateCTime();
return 0;
}

Expand Down
5 changes: 4 additions & 1 deletion test/fs/test_fs_js_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,11 @@ void test_fs_utime() {
assert(utimeStats.st_atime == 10);
assert(utimeStats.st_atim.tv_sec == 10);

// WasmFS correctly sets both times, but the legacy API sets both times to the max of atime and mtime.
// WasmFS correctly sets both times, but the legacy API sets both times to the max of atime and mtime
// and does not correctly handle nanseconds.
#if WASMFS
assert(utimeStats.st_atim.tv_nsec == 500000000);

assert(utimeStats.st_mtime == 8);
assert(utimeStats.st_mtim.tv_sec == 8);
#else
Expand Down
1 change: 1 addition & 0 deletions test/other/metadce/test_metadce_cxx_wasmfs.imports
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
env.__cxa_throw
env._emscripten_get_now_is_monotonic
env._wasmfs_copy_preloaded_file_data
env._wasmfs_get_num_preloaded_dirs
env._wasmfs_get_num_preloaded_files
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
12363
12507
2 changes: 2 additions & 0 deletions test/other/metadce/test_metadce_cxx_wasmfs.sent
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
__cxa_throw
_emscripten_get_now_is_monotonic
_wasmfs_copy_preloaded_file_data
_wasmfs_get_num_preloaded_dirs
_wasmfs_get_num_preloaded_files
Expand All @@ -11,6 +12,7 @@ abort
emscripten_console_error
emscripten_date_now
emscripten_err
emscripten_get_now
emscripten_memcpy_big
emscripten_out
emscripten_resize_heap
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_cxx_wasmfs.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
164024
164449
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_files_wasmfs.exports
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
q
r
s
t
u
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_files_wasmfs.funcs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
$__clock_gettime
$__cxx_global_array_dtor
$__cxx_global_array_dtor.1
$__cxx_global_array_dtor.2
Expand Down Expand Up @@ -27,7 +28,6 @@ $__pthread_mutex_lock
$__stdio_close
$__stdio_seek
$__stdio_write
$__time
$__unlockfile
$__wasi_fd_close
$__wasi_fd_write
Expand Down
1 change: 1 addition & 0 deletions test/other/metadce/test_metadce_files_wasmfs.imports
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ a.m
a.n
a.o
a.p
a.q
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_files_wasmfs.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6830
6902
1 change: 1 addition & 0 deletions test/other/metadce/test_metadce_files_wasmfs.sent
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ m
n
o
p
q
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_files_wasmfs.size
Original file line number Diff line number Diff line change
@@ -1 +1 @@
51954
52403