Skip to content

Commit

Permalink
propagate timestamps to virtual file handles (#4618)
Browse files Browse the repository at this point in the history
  • Loading branch information
maminrayej authored Apr 29, 2024
2 parents a57cbb5 + 7beff7b commit b7d4747
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/arc_box_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ impl VirtualFile for ArcBoxFile {
let inner = self.inner.lock().unwrap();
inner.created_time()
}
fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
let mut inner = self.inner.lock().unwrap();
inner.set_times(atime, mtime)
}
fn size(&self) -> u64 {
let inner = self.inner.lock().unwrap();
inner.size()
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/arc_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ where
let inner = self.inner.lock().unwrap();
inner.created_time()
}
fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
let mut inner = self.inner.lock().unwrap();
inner.set_times(atime, mtime)
}
fn size(&self) -> u64 {
let inner = self.inner.lock().unwrap();
inner.size()
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/combine_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ impl VirtualFile for CombineFile {
self.tx.created_time()
}

fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
self.tx.set_times(atime, mtime)
}

fn size(&self) -> u64 {
self.rx.size()
}
Expand Down
10 changes: 10 additions & 0 deletions lib/virtual-fs/src/cow_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ impl VirtualFile for CopyOnWriteFile {
fn created_time(&self) -> u64 {
self.created_time
}
fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
if let Some(atime) = atime {
self.last_accessed = atime;
}
if let Some(mtime) = mtime {
self.last_modified = mtime;
}

Ok(())
}
fn size(&self) -> u64 {
match self.state.as_ref() {
Some(inner) => inner.size(),
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/dual_write_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ impl VirtualFile for DualWriteFile {
self.inner.created_time()
}

fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
self.inner.set_times(atime, mtime)
}

fn size(&self) -> u64 {
self.inner.size()
}
Expand Down
8 changes: 8 additions & 0 deletions lib/virtual-fs/src/host_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,14 @@ impl VirtualFile for File {
.unwrap_or(0)
}

fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
let atime = atime.map(|t| filetime::FileTime::from_unix_time(t as i64, 0));
let mtime = mtime.map(|t| filetime::FileTime::from_unix_time(t as i64, 0));

filetime::set_file_handle_times(&self.inner_std, atime, mtime)
.map_err(|_| crate::FsError::IOError)
}

fn size(&self) -> u64 {
self.metadata().len()
}
Expand Down
6 changes: 6 additions & 0 deletions lib/virtual-fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,12 @@ pub trait VirtualFile:
/// the time at which the file was created in nanoseconds as a UNIX timestamp
fn created_time(&self) -> u64;

#[allow(unused_variables)]
/// sets accessed and modified time
fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
Ok(())
}

/// the size of the file in bytes
fn size(&self) -> u64;

Expand Down
21 changes: 21 additions & 0 deletions lib/virtual-fs/src/mem_fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,27 @@ impl VirtualFile for FileHandle {
node.metadata().created
}

fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
let mut fs = match self.filesystem.inner.write() {
Ok(fs) => fs,
_ => return Err(crate::FsError::Lock),
};

let inode = fs.storage.get_mut(self.inode);
if let Some(node) = inode {
if let Some(atime) = atime {
node.metadata_mut().accessed = atime;
}
if let Some(mtime) = mtime {
node.metadata_mut().modified = mtime;
}

return Ok(());
}

Err(crate::FsError::UnknownError)
}

fn size(&self) -> u64 {
let fs = match self.filesystem.inner.read() {
Ok(fs) => fs,
Expand Down
5 changes: 5 additions & 0 deletions lib/virtual-fs/src/trace_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ impl VirtualFile for TraceFile {
self.file.created_time()
}

#[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))]
fn set_times(&mut self, atime: Option<u64>, mtime: Option<u64>) -> crate::Result<()> {
self.file.set_times(atime, mtime)
}

#[tracing::instrument(level = "trace", skip(self), fields(path=%self.path.display()))]
fn size(&self) -> u64 {
self.file.size()
Expand Down
13 changes: 13 additions & 0 deletions lib/wasix/src/fs/inode_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,19 @@ impl VirtualFile for WasiStateFileGuard {
}
}

fn set_times(
&mut self,
atime: Option<u64>,
mtime: Option<u64>,
) -> Result<(), virtual_fs::FsError> {
let mut guard = self.lock_write();
if let Some(file) = guard.as_mut() {
file.set_times(atime, mtime)
} else {
Err(crate::FsError::Lock)
}
}

fn size(&self) -> u64 {
let guard = self.lock_read();
if let Some(file) = guard.as_ref() {
Expand Down
17 changes: 17 additions & 0 deletions lib/wasix/src/syscalls/wasi/fd_filestat_set_times.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::borrow::BorrowMut;

use super::*;
use crate::syscalls::*;

Expand Down Expand Up @@ -59,13 +61,17 @@ pub(crate) fn fd_filestat_set_times_internal(

let inode = fd_entry.inode;

let mut atime = None;
let mut mtime = None;

if fst_flags.contains(Fstflags::SET_ATIM) || fst_flags.contains(Fstflags::SET_ATIM_NOW) {
let time_to_set = if fst_flags.contains(Fstflags::SET_ATIM) {
st_atim
} else {
get_current_time_in_nanos()?
};
inode.stat.write().unwrap().st_atim = time_to_set;
atime = Some(time_to_set);
}

if fst_flags.contains(Fstflags::SET_MTIM) || fst_flags.contains(Fstflags::SET_MTIM_NOW) {
Expand All @@ -75,6 +81,17 @@ pub(crate) fn fd_filestat_set_times_internal(
get_current_time_in_nanos()?
};
inode.stat.write().unwrap().st_mtim = time_to_set;
mtime = Some(time_to_set);
}

if let Kind::File {
handle: Some(handle),
..
} = inode.kind.write().unwrap().deref()
{
let mut handle = handle.write().unwrap();

handle.set_times(atime, mtime);
}

Ok(())
Expand Down

0 comments on commit b7d4747

Please sign in to comment.