Commit a6af6a92 authored by Jeremy Soller's avatar Jeremy Soller

Merge branch 'add-atime' into 'master'

Add tracking of access times

See merge request !48
parents 3191d7d1 d2256b3e
Pipeline #6852 failed with stages
in 3 minutes and 33 seconds
......@@ -97,7 +97,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redoxfs"
version = "0.3.7"
version = "0.4.0"
dependencies = [
"fuse 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
......
......@@ -2,7 +2,7 @@
name = "redoxfs"
description = "The Redox Filesystem"
repository = "https://gitlab.redox-os.org/redox-os/redoxfs"
version = "0.3.7"
version = "0.4.0"
license-file = "LICENSE"
readme = "README.md"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
......
use std::cmp::min;
use std::time::{SystemTime, UNIX_EPOCH};
use syscall::error::{Result, Error, EEXIST, EISDIR, EINVAL, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY};
......@@ -428,6 +429,7 @@ impl<D: Disk> FileSystem<D> {
}
pub fn read_node(&mut self, block: u64, offset: u64, buf: &mut [u8]) -> Result<usize> {
let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let block_offset = offset / BLOCK_SIZE;
let mut byte_offset = (offset % BLOCK_SIZE) as usize;
......@@ -483,6 +485,20 @@ impl<D: Disk> FileSystem<D> {
assert_eq!(block, extent.block + (extent.length + BLOCK_SIZE - 1)/BLOCK_SIZE);
}
if i > 0 {
let atime_nsec = atime.subsec_nanos();
let atime = atime.as_secs();
let mut node = self.node(block)?;
if atime > node.1.atime || (atime == node.1.atime && atime_nsec > node.1.atime_nsec) {
let is_old = atime - node.1.atime > 3600; // Last read was more than a day ago
node.1.atime = atime;
node.1.atime_nsec = atime_nsec;
if is_old {
self.write_at(node.0, &node.1)?;
}
}
}
Ok(i)
}
......
#![crate_name="redoxfs"]
#![crate_type="lib"]
#![crate_name = "redoxfs"]
#![crate_type = "lib"]
extern crate syscall;
extern crate uuid;
......@@ -8,7 +8,7 @@ use std::sync::atomic::AtomicUsize;
pub const BLOCK_SIZE: u64 = 4096;
pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0";
pub const VERSION: u64 = 3;
pub const VERSION: u64 = 4;
pub static IS_UMT: AtomicUsize = AtomicUsize::new(0);
pub use self::archive::{archive, archive_at};
......
......@@ -117,7 +117,7 @@ impl<D: Disk> Filesystem for Fuse<D> {
fn setattr(&mut self, _req: &Request, block: u64, mode: Option<u32>,
uid: Option<u32>, gid: Option<u32>, size: Option<u64>,
_atime: Option<Timespec>, mtime: Option<Timespec>, _fh: Option<u64>,
atime: Option<Timespec>, mtime: Option<Timespec>, _fh: Option<u64>,
_crtime: Option<Timespec>, _chgtime: Option<Timespec>, _bkuptime: Option<Timespec>,
_flags: Option<u32>, reply: ReplyAttr) {
if let Some(mode) = mode {
......@@ -176,11 +176,20 @@ impl<D: Disk> Filesystem for Fuse<D> {
}
}
if let Some(mtime) = mtime {
let need_update = atime.is_some() || mtime.is_some();
if need_update {
match self.fs.node(block) {
Ok(mut node) => {
node.1.mtime = mtime.sec as u64;
node.1.mtime_nsec = mtime.nsec as u32;
if let Some(atime) = atime {
node.1.atime = atime.sec as u64;
node.1.atime_nsec = atime.nsec as u32;
}
if let Some(mtime) = mtime {
node.1.mtime = mtime.sec as u64;
node.1.mtime_nsec = mtime.nsec as u32;
}
if let Err(err) = self.fs.write_at(node.0, &node.1) {
reply.error(err.errno as i32);
return;
......
......@@ -165,6 +165,8 @@ impl<D: Disk> Resource<D> for DirResource {
st_size: fs.node_len(self.block)?,
st_mtime: node.1.mtime,
st_mtime_nsec: node.1.mtime_nsec,
st_atime: node.1.atime,
st_atime_nsec: node.1.atime_nsec,
st_ctime: node.1.ctime,
st_ctime_nsec: node.1.ctime_nsec,
..Default::default()
......@@ -426,6 +428,8 @@ impl<D: Disk> Resource<D> for FileResource {
st_size: fs.node_len(self.block)?,
st_mtime: node.1.mtime,
st_mtime_nsec: node.1.mtime_nsec,
st_atime: node.1.atime,
st_atime_nsec: node.1.atime_nsec,
st_ctime: node.1.ctime,
st_ctime_nsec: node.1.ctime_nsec,
..Default::default()
......@@ -455,17 +459,16 @@ impl<D: Disk> Resource<D> for FileResource {
let mut node = fs.node(self.block)?;
if node.1.uid == self.uid || self.uid == 0 {
if let Some(mtime) = times.get(1) {
if let &[atime, mtime] = times {
node.1.mtime = mtime.tv_sec as u64;
node.1.mtime_nsec = mtime.tv_nsec as u32;
node.1.atime = atime.tv_sec as u64;
node.1.atime_nsec = atime.tv_nsec as u32;
fs.write_at(node.0, &node.1)?;
Ok(0)
} else {
Ok(0)
}
Ok(0)
} else {
Err(Error::new(EPERM))
}
......
......@@ -14,10 +14,12 @@ pub struct Node {
pub ctime_nsec: u32,
pub mtime: u64,
pub mtime_nsec: u32,
pub name: [u8; 222],
pub atime: u64,
pub atime_nsec: u32,
pub name: [u8; 226],
pub parent: u64,
pub next: u64,
pub extents: [Extent; (BLOCK_SIZE as usize - 272)/16],
pub extents: [Extent; (BLOCK_SIZE as usize - 288)/16],
}
impl Node {
......@@ -40,15 +42,17 @@ impl Node {
ctime_nsec: 0,
mtime: 0,
mtime_nsec: 0,
name: [0; 222],
atime: 0,
atime_nsec: 0,
name: [0; 226],
parent: 0,
next: 0,
extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16],
extents: [Extent::default(); (BLOCK_SIZE as usize - 288)/16],
}
}
pub fn new(mode: u16, name: &str, parent: u64, ctime: u64, ctime_nsec: u32) -> syscall::Result<Node> {
let mut bytes = [0; 222];
let mut bytes = [0; 226];
if name.len() > bytes.len() {
return Err(syscall::Error::new(syscall::ENAMETOOLONG));
}
......@@ -64,10 +68,12 @@ impl Node {
ctime_nsec: ctime_nsec,
mtime: ctime,
mtime_nsec: ctime_nsec,
atime: ctime,
atime_nsec: ctime_nsec,
name: bytes,
parent: parent,
next: 0,
extents: [Extent::default(); (BLOCK_SIZE as usize - 272)/16],
extents: [Extent::default(); (BLOCK_SIZE as usize - 288)/16],
})
}
......@@ -85,7 +91,7 @@ impl Node {
}
pub fn set_name(&mut self, name: &str) -> syscall::Result<()> {
let mut bytes = [0; 222];
let mut bytes = [0; 226];
if name.len() > bytes.len() {
return Err(syscall::Error::new(syscall::ENAMETOOLONG));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment