Переглянути джерело

feat(vfs): update {a, m, c}time accordingly when we modify the inodes

greatbridf 7 місяців тому
батько
коміт
b212bc8ca2
4 змінених файлів з 82 додано та 17 видалено
  1. 8 1
      src/fs/procfs.rs
  2. 24 0
      src/fs/tmpfs.rs
  3. 36 0
      src/kernel/timer.rs
  4. 14 16
      src/kernel/vfs/inode.rs

+ 8 - 1
src/fs/procfs.rs

@@ -1,4 +1,5 @@
 use crate::kernel::constants::{EACCES, ENOTDIR};
+use crate::kernel::timer::Instant;
 use crate::{
     io::Buffer,
     kernel::{
@@ -76,13 +77,16 @@ impl FileInode {
             mode |= 0o200;
         }
 
-        let inode = Self {
+        let mut inode = Self {
             idata: InodeData::new(ino, vfs),
             file,
         };
 
         inode.idata.mode.store(mode, Ordering::Relaxed);
         inode.idata.nlink.store(1, Ordering::Relaxed);
+        *inode.ctime.get_mut() = Instant::now();
+        *inode.mtime.get_mut() = Instant::now();
+        *inode.atime.get_mut() = Instant::now();
 
         Arc::new(inode)
     }
@@ -121,6 +125,9 @@ impl DirInode {
             addr_of_mut_field!(inode, entries).write(Locked::new(vec![], rwsem));
             addr_of_mut_field!(&mut *inode, mode).write((S_IFDIR | 0o755).into());
             addr_of_mut_field!(&mut *inode, nlink).write(1.into());
+            addr_of_mut_field!(&mut *inode, ctime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, mtime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, atime).write(Spin::new(Instant::now()));
         })
     }
 }

+ 24 - 0
src/fs/tmpfs.rs

@@ -1,5 +1,6 @@
 use crate::io::Stream;
 use crate::kernel::constants::{EINVAL, EIO, EISDIR};
+use crate::kernel::timer::Instant;
 use crate::{
     io::Buffer,
     kernel::constants::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFREG},
@@ -42,6 +43,9 @@ impl NodeInode {
 
             addr_of_mut_field!(&mut *inode, mode).write(mode.into());
             addr_of_mut_field!(&mut *inode, nlink).write(1.into());
+            addr_of_mut_field!(&mut *inode, ctime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, mtime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, atime).write(Spin::new(Instant::now()));
         })
     }
 }
@@ -67,6 +71,9 @@ impl DirectoryInode {
             addr_of_mut_field!(&mut *inode, size).write(1.into());
             addr_of_mut_field!(&mut *inode, mode).write((S_IFDIR | (mode & 0o777)).into());
             addr_of_mut_field!(&mut *inode, nlink).write(1.into()); // link from `.` to itself
+            addr_of_mut_field!(&mut *inode, ctime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, mtime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, atime).write(Spin::new(Instant::now()));
         })
     }
 
@@ -77,6 +84,7 @@ impl DirectoryInode {
 
         // SAFETY: `rwsem` has done the synchronization
         self.size.fetch_add(1, Ordering::Relaxed);
+        *self.mtime.lock() = Instant::now();
 
         self.entries.access_mut(dlock).push((name, file.ino));
     }
@@ -182,6 +190,8 @@ impl Inode for DirectoryInode {
             self.size.fetch_sub(1, Ordering::Relaxed) - 1
         );
 
+        *self.mtime.lock() = Instant::now();
+
         // SAFETY: `flock` has done the synchronization
         let file_nlink = file.nlink.fetch_sub(1, Ordering::Relaxed) - 1;
 
@@ -213,6 +223,8 @@ impl Inode for DirectoryInode {
         let old = self.mode.load(Ordering::Relaxed);
         self.mode
             .store((old & !0o777) | (mode & 0o777), Ordering::Relaxed);
+        *self.ctime.lock() = Instant::now();
+
         Ok(())
     }
 }
@@ -231,6 +243,9 @@ impl SymlinkInode {
 
             addr_of_mut_field!(&mut *inode, mode).write((S_IFLNK | 0o777).into());
             addr_of_mut_field!(&mut *inode, size).write((len as u64).into());
+            addr_of_mut_field!(&mut *inode, ctime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, mtime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, atime).write(Spin::new(Instant::now()));
         })
     }
 }
@@ -260,6 +275,9 @@ impl FileInode {
 
             addr_of_mut_field!(&mut *inode, mode).write((S_IFREG | (mode & 0o777)).into());
             addr_of_mut_field!(&mut *inode, nlink).write(1.into());
+            addr_of_mut_field!(&mut *inode, ctime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, mtime).write(Spin::new(Instant::now()));
+            addr_of_mut_field!(&mut *inode, atime).write(Spin::new(Instant::now()));
         })
     }
 }
@@ -310,6 +328,8 @@ impl Inode for FileInode {
 
         // SAFETY: `lock` has done the synchronization
         self.size.store(pos as u64, Ordering::Relaxed);
+        *self.mtime.lock() = Instant::now();
+
         Ok(pos - offset)
     }
 
@@ -320,6 +340,8 @@ impl Inode for FileInode {
 
         // SAFETY: `lock` has done the synchronization
         self.size.store(length as u64, Ordering::Relaxed);
+        *self.mtime.lock() = Instant::now();
+
         filedata.resize(length, 0);
 
         Ok(())
@@ -333,6 +355,8 @@ impl Inode for FileInode {
         let old = self.mode.load(Ordering::Relaxed);
         self.mode
             .store((old & !0o777) | (mode & 0o777), Ordering::Relaxed);
+        *self.ctime.lock() = Instant::now();
+
         Ok(())
     }
 }

+ 36 - 0
src/kernel/timer.rs

@@ -9,6 +9,7 @@ use core::{
 };
 use eonix_hal::processor::CPU;
 use eonix_sync::{Spin, SpinIrq as _};
+use posix_types::stat::{StatXTimestamp, TimeSpec, TimeVal};
 
 static TICKS: AtomicUsize = AtomicUsize::new(0);
 static WAKEUP_TICK: AtomicUsize = AtomicUsize::new(usize::MAX);
@@ -17,6 +18,7 @@ static SLEEPERS_LIST: Spin<BinaryHeap<Reverse<Sleepers>>> = Spin::new(BinaryHeap
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
 pub struct Ticks(usize);
 
+#[derive(Default, Clone, Copy)]
 pub struct Instant {
     secs_since_epoch: u64,
     nsecs_within: u32,
@@ -74,6 +76,13 @@ impl Ticks {
 }
 
 impl Instant {
+    pub const fn default() -> Self {
+        Instant {
+            secs_since_epoch: 0,
+            nsecs_within: 0,
+        }
+    }
+
     pub fn new(secs_since_epoch: u64, nsecs_within: u32) -> Self {
         Instant {
             secs_since_epoch,
@@ -102,6 +111,33 @@ impl Instant {
     }
 }
 
+impl From<Instant> for TimeSpec {
+    fn from(value: Instant) -> Self {
+        Self {
+            tv_sec: value.secs_since_epoch,
+            tv_nsec: value.nsecs_within,
+        }
+    }
+}
+
+impl From<Instant> for TimeVal {
+    fn from(value: Instant) -> Self {
+        Self {
+            tv_sec: value.secs_since_epoch,
+            tv_usec: value.nsecs_within / 1_000,
+        }
+    }
+}
+
+impl From<Instant> for StatXTimestamp {
+    fn from(value: Instant) -> Self {
+        Self {
+            tv_sec: value.secs_since_epoch,
+            tv_nsec: value.nsecs_within,
+        }
+    }
+}
+
 impl Add for Ticks {
     type Output = Ticks;
 

+ 14 - 16
src/kernel/vfs/inode.rs

@@ -1,9 +1,10 @@
-use super::{dentry::Dentry, s_isblk, s_ischr, vfs::Vfs, DevId, TimeSpec};
+use super::{dentry::Dentry, s_isblk, s_ischr, vfs::Vfs, DevId};
 use crate::io::Stream;
 use crate::kernel::constants::{
     EINVAL, EISDIR, ENOTDIR, EPERM, STATX_ATIME, STATX_BLOCKS, STATX_CTIME, STATX_GID, STATX_INO,
     STATX_MODE, STATX_MTIME, STATX_NLINK, STATX_SIZE, STATX_TYPE, STATX_UID, S_IFDIR, S_IFMT,
 };
+use crate::kernel::timer::Instant;
 use crate::{io::Buffer, prelude::*};
 use alloc::sync::{Arc, Weak};
 use core::{
@@ -42,9 +43,9 @@ pub struct InodeData {
     pub gid: AtomicGid,
     pub mode: AtomicMode,
 
-    pub atime: Spin<TimeSpec>,
-    pub ctime: Spin<TimeSpec>,
-    pub mtime: Spin<TimeSpec>,
+    pub atime: Spin<Instant>,
+    pub ctime: Spin<Instant>,
+    pub mtime: Spin<Instant>,
 
     pub rwsem: RwLock<()>,
 
@@ -56,9 +57,9 @@ impl InodeData {
         Self {
             ino,
             vfs,
-            atime: Spin::new(TimeSpec::default()),
-            ctime: Spin::new(TimeSpec::default()),
-            mtime: Spin::new(TimeSpec::default()),
+            atime: Spin::new(Instant::default()),
+            ctime: Spin::new(Instant::default()),
+            mtime: Spin::new(Instant::default()),
             rwsem: RwLock::new(()),
             size: AtomicU64::new(0),
             nlink: AtomicNlink::new(0),
@@ -161,23 +162,20 @@ pub trait Inode: Send + Sync + InodeInner {
         }
 
         if mask & STATX_ATIME != 0 {
-            let atime = self.atime.lock();
-            stat.stx_atime.tv_nsec = atime.nsec as _;
-            stat.stx_atime.tv_sec = atime.sec as _;
+            let atime = *self.atime.lock();
+            stat.stx_atime = atime.into();
             stat.stx_mask |= STATX_ATIME;
         }
 
         if mask & STATX_MTIME != 0 {
-            let mtime = self.mtime.lock();
-            stat.stx_mtime.tv_nsec = mtime.nsec as _;
-            stat.stx_mtime.tv_sec = mtime.sec as _;
+            let mtime = *self.mtime.lock();
+            stat.stx_mtime = mtime.into();
             stat.stx_mask |= STATX_MTIME;
         }
 
         if mask & STATX_CTIME != 0 {
-            let ctime = self.ctime.lock();
-            stat.stx_ctime.tv_nsec = ctime.nsec as _;
-            stat.stx_ctime.tv_sec = ctime.sec as _;
+            let ctime = *self.ctime.lock();
+            stat.stx_ctime = ctime.into();
             stat.stx_mask |= STATX_CTIME;
         }