Skip to content

Commit d2ba94e

Browse files
committed
fix utime
1 parent 2306156 commit d2ba94e

File tree

4 files changed

+125
-79
lines changed

4 files changed

+125
-79
lines changed

api/src/fd/fs.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ impl FileLike for File {
5252
size: metadata.size(),
5353
blocks: metadata.blocks(),
5454
blksize: 512,
55+
atime: metadata.atime(),
56+
mtime: metadata.mtime(),
5557
..Default::default()
5658
})
5759
}
@@ -70,6 +72,14 @@ impl FileLike for File {
7072
fn set_nonblocking(&self, _nonblocking: bool) -> LinuxResult {
7173
Ok(())
7274
}
75+
76+
fn set_atime(&self, atime: usize) -> LinuxResult {
77+
Ok(self.inner.lock().set_atime(atime)?)
78+
}
79+
80+
fn set_mtime(&self, mtime: usize) -> LinuxResult {
81+
Ok(self.inner.lock().set_mtime(mtime)?)
82+
}
7383
}
7484

7585
/// Directory wrapper for `axfs::fops::Directory`.

api/src/fd/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use axerrno::{LinuxError, LinuxResult};
1010
use axio::PollState;
1111
use axns::{ResArc, def_resource};
1212
use flatten_objects::FlattenObjects;
13-
use linux_raw_sys::general::{stat, statx};
13+
use linux_raw_sys::general::{stat, statx, statx_timestamp};
1414
use spin::RwLock;
1515

1616
pub use self::{
@@ -31,6 +31,8 @@ pub struct Kstat {
3131
size: u64,
3232
blocks: u64,
3333
blksize: u32,
34+
atime: usize,
35+
mtime: usize,
3436
}
3537

3638
impl Default for Kstat {
@@ -44,6 +46,8 @@ impl Default for Kstat {
4446
size: 0,
4547
blocks: 0,
4648
blksize: 4096,
49+
atime: 0,
50+
mtime: 0,
4751
}
4852
}
4953
}
@@ -60,6 +64,8 @@ impl From<Kstat> for stat {
6064
stat.st_size = value.size as _;
6165
stat.st_blksize = value.blksize as _;
6266
stat.st_blocks = value.blocks as _;
67+
stat.st_atime = value.atime as _;
68+
stat.st_mtime = value.mtime as _;
6369

6470
stat
6571
}
@@ -78,6 +84,16 @@ impl From<Kstat> for statx {
7884
statx.stx_ino = value.ino as _;
7985
statx.stx_size = value.size as _;
8086
statx.stx_blocks = value.blocks as _;
87+
statx.stx_atime = statx_timestamp {
88+
tv_sec: value.atime as _,
89+
tv_nsec: 0,
90+
__reserved: 0,
91+
};
92+
statx.stx_mtime = statx_timestamp {
93+
tv_sec: value.mtime as _,
94+
tv_nsec: 0,
95+
__reserved: 0,
96+
};
8197

8298
statx
8399
}
@@ -108,6 +124,12 @@ pub trait FileLike: Send + Sync {
108124
{
109125
add_file_like(Arc::new(self))
110126
}
127+
fn set_atime(&self, _atime: usize) -> LinuxResult {
128+
unimplemented!("set_atime of FileLike")
129+
}
130+
fn set_mtime(&self, _mtime: usize) -> LinuxResult {
131+
unimplemented!("set_mtime of FileLike")
132+
}
111133
}
112134

113135
def_resource! {

api/src/imp/fs/ctl.rs

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use core::ffi::{c_char, c_int, c_void};
22

33
use alloc::ffi::CString;
44
use axerrno::{LinuxError, LinuxResult};
5-
use linux_raw_sys::general::{__kernel_ino_t, __kernel_off_t, AT_FDCWD, AT_REMOVEDIR};
5+
use linux_raw_sys::general::{__kernel_ino_t, __kernel_off_t, AT_FDCWD, AT_REMOVEDIR, timespec};
66

77
use crate::{
8-
fd::{Directory, FileLike},
8+
fd::{Directory, FileLike, get_file_like},
99
path::{HARDLINK_MANAGER, handle_file_path},
1010
ptr::{UserConstPtr, UserPtr, nullable},
1111
};
@@ -318,72 +318,72 @@ pub const UTIME_NOW: usize = 0x3fffffff;
318318
/// when nsec is UTIME_OMIT,donot modify time
319319
pub const UTIME_OMIT: usize = 0x3ffffffe;
320320

321-
// / Modify the timestamp of file or dir
322-
// / if fir_fd < 0, it determines the file together with path
323-
// / if fir_fd >=0, it is the fd of the file
324-
// / nsec is omited except for special values now
325-
// pub fn sys_utimensat(
326-
// dir_fd: i32,
327-
// path: UserConstPtr<c_char>,
328-
// times: UserConstPtr<timespec>,
329-
// _flags: i32,
330-
// ) -> LinuxResult<isize> {
331-
// if dir_fd != AT_FDCWD as _ && (dir_fd as isize) < 0 {
332-
// return Err(LinuxError::EBADF); // wrong dir_fd
333-
// }
334-
335-
// let times = times.get_as_array(2)?;
336-
// let (atime, mtime): (timespec, timespec) = unsafe { (*times, *(times.add(1))) };
337-
// // FIXME: this is time elapsed since system boot, but not timestamp now
338-
// let current_s = axhal::time::monotonic_time_nanos() as i64 / 1000 / 1000;
339-
// let now = current_s as usize;
340-
// info!(
341-
// "sys_utimensat: dir_fd={}; atime=({}, {}); mtime=({}, {}); now={}",
342-
// dir_fd, atime.tv_sec, atime.tv_nsec, mtime.tv_sec, mtime.tv_nsec, now
343-
// );
344-
// // TODO: simplify the code
345-
// if (dir_fd as isize) > 0 {
346-
// let file = get_file_like(dir_fd as _)?;
347-
// match atime.tv_nsec as _ {
348-
// UTIME_NOW => {
349-
// _ = file.set_atime(now);
350-
// }
351-
// UTIME_OMIT => {}
352-
// _ => {
353-
// _ = file.set_atime(atime.tv_sec as _);
354-
// }
355-
// };
356-
// match mtime.tv_nsec as _ {
357-
// UTIME_NOW => {
358-
// _ = file.set_mtime(now);
359-
// }
360-
// UTIME_OMIT => {}
361-
// _ => {
362-
// _ = file.set_mtime(mtime.tv_sec as _);
363-
// }
364-
// };
365-
// } else {
366-
// let file = axfs::fops::File::open(path.get_as_str()?, &axfs::fops::OpenOptions::new())
367-
// .map_err(|_| LinuxError::ENOTDIR)?;
368-
// match atime.tv_nsec as _ {
369-
// UTIME_NOW => {
370-
// _ = file.set_atime(now);
371-
// }
372-
// UTIME_OMIT => {}
373-
// _ => {
374-
// _ = file.set_atime(atime.tv_sec as _);
375-
// }
376-
// };
377-
// match mtime.tv_nsec as _ {
378-
// UTIME_NOW => {
379-
// _ = file.set_mtime(now);
380-
// }
381-
// UTIME_OMIT => {}
382-
// _ => {
383-
// _ = file.set_mtime(mtime.tv_sec as _);
384-
// }
385-
// };
386-
// };
387-
388-
// Ok(0)
389-
// }
321+
/// Modify the timestamp of file or dir
322+
/// if fir_fd < 0, it determines the file together with path
323+
/// if fir_fd >=0, it is the fd of the file
324+
/// nsec is omited except for special values now
325+
pub fn sys_utimensat(
326+
dir_fd: i32,
327+
path: UserConstPtr<c_char>,
328+
times: UserConstPtr<timespec>,
329+
_flags: i32,
330+
) -> LinuxResult<isize> {
331+
if dir_fd != AT_FDCWD as _ && (dir_fd as isize) < 0 {
332+
return Err(LinuxError::EBADF); // wrong dir_fd
333+
}
334+
335+
let times = times.get_as_slice(2)?;
336+
let (atime, mtime): (timespec, timespec) = (times[0], times[1]);
337+
// FIXME: this is time elapsed since system boot, but not timestamp now
338+
let current_s = axhal::time::monotonic_time_nanos() as i64 / 1000 / 1000;
339+
let now = current_s as usize;
340+
info!(
341+
"sys_utimensat: dir_fd={}; atime=({}, {}); mtime=({}, {}); now={}",
342+
dir_fd, atime.tv_sec, atime.tv_nsec, mtime.tv_sec, mtime.tv_nsec, now
343+
);
344+
// TODO: simplify the code
345+
if (dir_fd as isize) > 0 {
346+
let file = get_file_like(dir_fd as _)?;
347+
match atime.tv_nsec as _ {
348+
UTIME_NOW => {
349+
_ = file.set_atime(now);
350+
}
351+
UTIME_OMIT => {}
352+
_ => {
353+
_ = file.set_atime(atime.tv_sec as _);
354+
}
355+
};
356+
match mtime.tv_nsec as _ {
357+
UTIME_NOW => {
358+
_ = file.set_mtime(now);
359+
}
360+
UTIME_OMIT => {}
361+
_ => {
362+
_ = file.set_mtime(mtime.tv_sec as _);
363+
}
364+
};
365+
} else {
366+
let file = axfs::fops::File::open(path.get_as_str()?, &axfs::fops::OpenOptions::new())
367+
.map_err(|_| LinuxError::ENOTDIR)?;
368+
match atime.tv_nsec as _ {
369+
UTIME_NOW => {
370+
_ = file.set_atime(now);
371+
}
372+
UTIME_OMIT => {}
373+
_ => {
374+
_ = file.set_atime(atime.tv_sec as _);
375+
}
376+
};
377+
match mtime.tv_nsec as _ {
378+
UTIME_NOW => {
379+
_ = file.set_mtime(now);
380+
}
381+
UTIME_OMIT => {}
382+
_ => {
383+
_ = file.set_mtime(mtime.tv_sec as _);
384+
}
385+
};
386+
};
387+
388+
Ok(0)
389+
}

src/syscall.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,22 @@ fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
1919
time_stat_from_user_to_kernel();
2020
let result = match sysno {
2121
Sysno::read => sys_read(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
22+
Sysno::readv => sys_readv(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
2223
Sysno::write => sys_write(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
24+
Sysno::writev => sys_writev(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
25+
Sysno::pread64 => sys_pread64(
26+
tf.arg0() as _,
27+
tf.arg1().into(),
28+
tf.arg2() as _,
29+
tf.arg3() as _,
30+
),
31+
Sysno::sendfile => sys_sendfile(
32+
tf.arg0() as _,
33+
tf.arg1() as _,
34+
tf.arg2().into(),
35+
tf.arg3() as _,
36+
),
37+
2338
Sysno::mmap => sys_mmap(
2439
tf.arg0().into(),
2540
tf.arg1() as _,
@@ -29,7 +44,6 @@ fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
2944
tf.arg5() as _,
3045
),
3146
Sysno::ioctl => sys_ioctl(tf.arg0() as _, tf.arg1() as _, tf.arg2().into()),
32-
Sysno::writev => sys_writev(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
3347
Sysno::sched_yield => sys_sched_yield(),
3448
Sysno::nanosleep => sys_nanosleep(tf.arg0().into(), tf.arg1().into()),
3549
Sysno::getpid => sys_getpid(),
@@ -87,12 +101,12 @@ fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
87101
tf.arg4().into(),
88102
) as _,
89103
Sysno::umount2 => sys_umount2(tf.arg0().into(), tf.arg1() as _) as _,
90-
// Sysno::utimensat => sys_utimensat(
91-
// tf.arg0() as _,
92-
// tf.arg1().into(),
93-
// tf.arg2().into(),
94-
// tf.arg3() as _,
95-
// ),
104+
Sysno::utimensat => sys_utimensat(
105+
tf.arg0() as _,
106+
tf.arg1().into(),
107+
tf.arg2().into(),
108+
tf.arg3() as _,
109+
),
96110
#[cfg(target_arch = "x86_64")]
97111
Sysno::newfstatat => sys_fstatat(
98112
tf.arg0() as _,

0 commit comments

Comments
 (0)