Skip to content

Commit

Permalink
Merge pull request #36 from YdrMaster/master
Browse files Browse the repository at this point in the history
feat(rcore-fs-hostfs): 实现设置宿主文件系统上文件最后访问时间和最后修改时间
  • Loading branch information
chyyuu authored Mar 28, 2022
2 parents 1ec3cdc + ee10a2b commit 1a3246b
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 117 deletions.
6 changes: 6 additions & 0 deletions rcore-fs-devfs/src/special/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ impl NullINode {
}
}

impl Default for NullINode {
fn default() -> Self {
Self::new()
}
}

impl INode for NullINode {
fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {
// read nothing
Expand Down
6 changes: 6 additions & 0 deletions rcore-fs-devfs/src/special/zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ impl ZeroINode {
}
}

impl Default for ZeroINode {
fn default() -> Self {
Self::new()
}
}

impl INode for ZeroINode {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
// read zeros
Expand Down
18 changes: 8 additions & 10 deletions rcore-fs-ext2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,8 @@ struct Ext2Error {
}

impl core::convert::From<Ext2Error> for vfs::FsError {
fn from(err: Ext2Error) -> Self {
match err.inner {
_ => vfs::FsError::DeviceError,
}
fn from(_err: Ext2Error) -> Self {
vfs::FsError::DeviceError
}
}

Expand Down Expand Up @@ -91,10 +89,10 @@ impl Volume<u8, Size512> for Ext2Volume {
unimplemented!()
}

unsafe fn slice_unchecked<'a>(
&'a self,
unsafe fn slice_unchecked(
&self,
range: Range<Address<Size512>>,
) -> VolumeSlice<'a, u8, Size512> {
) -> VolumeSlice<'_, u8, Size512> {
let index = range.start;
let len = range.end - range.start;
let mut vec = vec![0; len.into_index() as usize];
Expand All @@ -104,10 +102,10 @@ impl Volume<u8, Size512> for Ext2Volume {
VolumeSlice::new_owned(vec, index)
}

fn slice<'a>(
&'a self,
fn slice(
&self,
range: Range<Address<Size512>>,
) -> Result<VolumeSlice<'a, u8, Size512>, Self::Error> {
) -> Result<VolumeSlice<'_, u8, Size512>, Self::Error> {
let index = range.start;
let len = range.end - range.start;
let mut vec = vec![0; len.into_index() as usize];
Expand Down
12 changes: 7 additions & 5 deletions rcore-fs-fuse/src/zip.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use std::error::Error;
use std::fs;
use std::io::{Read, Write};
use std::mem::MaybeUninit;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::str;
use std::sync::Arc;

use rcore_fs::vfs::{FileType, INode};
use rcore_fs::{
util::uninit_memory,
vfs::{FileType, INode},
};

const DEFAULT_MODE: u32 = 0o664;
const BUF_SIZE: usize = 0x1000;
Expand All @@ -24,7 +26,7 @@ pub fn zip_dir(path: &Path, inode: Arc<dyn INode>) -> Result<(), Box<dyn Error>>
let inode = inode.create(name, FileType::File, DEFAULT_MODE)?;
let mut file = fs::File::open(entry.path())?;
inode.resize(file.metadata()?.len() as usize)?;
let mut buf: [u8; BUF_SIZE] = unsafe { MaybeUninit::uninit().assume_init() };
let mut buf: [u8; BUF_SIZE] = unsafe { uninit_memory() };
let mut offset = 0usize;
let mut len = BUF_SIZE;
while len == BUF_SIZE {
Expand Down Expand Up @@ -59,7 +61,7 @@ pub fn unzip_dir(path: &Path, inode: Arc<dyn INode>) -> Result<(), Box<dyn Error
match info.type_ {
FileType::File => {
let mut file = fs::File::create(&path)?;
let mut buf: [u8; BUF_SIZE] = unsafe { MaybeUninit::uninit().assume_init() };
let mut buf: [u8; BUF_SIZE] = unsafe { uninit_memory() };
let mut offset = 0usize;
let mut len = BUF_SIZE;
while len == BUF_SIZE {
Expand All @@ -73,7 +75,7 @@ pub fn unzip_dir(path: &Path, inode: Arc<dyn INode>) -> Result<(), Box<dyn Error
unzip_dir(path.as_path(), inode)?;
}
FileType::SymLink => {
let mut buf: [u8; BUF_SIZE] = unsafe { MaybeUninit::uninit().assume_init() };
let mut buf: [u8; BUF_SIZE] = unsafe { uninit_memory() };
let len = inode.read_at(0, buf.as_mut())?;
#[cfg(unix)]
std::os::unix::fs::symlink(str::from_utf8(&buf[..len]).unwrap(), path)?;
Expand Down
72 changes: 44 additions & 28 deletions rcore-fs-hostfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,29 +102,43 @@ impl INode for HNode {
Ok(metadata.into())
}

fn set_metadata(&self, _metadata: &Metadata) -> Result<()> {
warn!("HostFS: set_metadata() is unimplemented");
Ok(())
fn set_metadata(&self, metadata: &Metadata) -> Result<()> {
// TODO 仅修改了文件的最后访问时间和最后修改时间
use nix::{
libc::{timespec, AT_FDCWD},
sys::{
stat::{utimensat, UtimensatFlags::FollowSymlink},
time::TimeSpec,
},
};
utimensat(
Some(AT_FDCWD),
&self.path,
&TimeSpec::from_timespec(timespec {
tv_sec: metadata.atime.sec,
tv_nsec: metadata.atime.nsec as _,
}),
&TimeSpec::from_timespec(timespec {
tv_sec: metadata.mtime.sec,
tv_nsec: metadata.mtime.nsec as _,
}),
FollowSymlink,
)
.map_err(|_| FsError::InvalidParam)
}

fn sync_all(&self) -> Result<()> {
let mut guard = self.open_file()?;
let file = guard.as_mut().unwrap();
file.sync_all()?;
self.open_file()?.as_mut().unwrap().sync_all()?;
Ok(())
}

fn sync_data(&self) -> Result<()> {
let mut guard = self.open_file()?;
let file = guard.as_mut().unwrap();
file.sync_data()?;
self.open_file()?.as_mut().unwrap().sync_data()?;
Ok(())
}

fn resize(&self, len: usize) -> Result<()> {
let mut guard = self.open_file()?;
let file = guard.as_mut().unwrap();
file.set_len(len as u64)?;
self.open_file()?.as_mut().unwrap().set_len(len as u64)?;
Ok(())
}

Expand Down Expand Up @@ -177,27 +191,29 @@ impl INode for HNode {

fn find(&self, name: &str) -> Result<Arc<dyn INode>> {
let new_path = self.path.join(name);
if !new_path.exists() {
return Err(FsError::EntryNotFound);
if new_path.exists() {
Ok(Arc::new(HNode {
path: new_path,
file: Mutex::new(None),
fs: self.fs.clone(),
}))
} else {
Err(FsError::EntryNotFound)
}
Ok(Arc::new(HNode {
path: new_path,
file: Mutex::new(None),
fs: self.fs.clone(),
}))
}

fn get_entry(&self, id: usize) -> Result<String> {
if !self.path.is_dir() {
return Err(FsError::NotDir);
if self.path.is_dir() {
self.path
.read_dir()?
.nth(id)
.ok_or(FsError::EntryNotFound)??
.file_name()
.into_string()
.map_err(|_| FsError::InvalidParam)
} else {
Err(FsError::NotDir)
}
self.path
.read_dir()?
.nth(id)
.ok_or(FsError::EntryNotFound)??
.file_name()
.into_string()
.map_err(|_| FsError::InvalidParam)
}

fn io_control(&self, _cmd: u32, _data: usize) -> Result<usize> {
Expand Down
2 changes: 1 addition & 1 deletion rcore-fs-ramfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl INode for LockedINode {
return Err(FsError::DirNotEmpty);
}
let other = file.children.get(name).ok_or(FsError::EntryNotFound)?;
if other.0.read().children.len() > 0 {
if !other.0.read().children.is_empty() {
return Err(FsError::DirNotEmpty);
}
other.0.write().extra.nlinks -= 1;
Expand Down
38 changes: 20 additions & 18 deletions rcore-fs-sefs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ use alloc::{
};
use core::any::Any;
use core::fmt::{Debug, Error, Formatter};
use core::mem::MaybeUninit;

use bitvec::prelude::*;
use rcore_fs::dev::TimeProvider;
use rcore_fs::dirty::Dirty;
use rcore_fs::vfs::{self, FileSystem, FsError, INode, MMapArea, Timespec};
use rcore_fs::{
dev::TimeProvider,
dirty::Dirty,
util::uninit_memory,
vfs::{self, FileSystem, FsError, INode, MMapArea, Timespec},
};
use spin::RwLock;

use self::dev::*;
use self::structs::*;
use dev::*;
use structs::*;

pub mod dev;
mod structs;
Expand All @@ -36,7 +38,7 @@ impl dyn File {
self.write_all_at(buf, id * BLKSIZE)
}
fn read_direntry(&self, id: usize) -> DevResult<DiskEntry> {
let mut direntry: DiskEntry = unsafe { MaybeUninit::uninit().assume_init() };
let mut direntry: DiskEntry = unsafe { uninit_memory() };
self.read_exact_at(direntry.as_buf_mut(), DIRENT_SIZE * id)?;
Ok(direntry)
}
Expand All @@ -45,7 +47,7 @@ impl dyn File {
}
/// Load struct `T` from given block in device
fn load_struct<T: AsBuf>(&self, id: BlockId) -> DevResult<T> {
let mut s: T = unsafe { MaybeUninit::uninit().assume_init() };
let mut s: T = unsafe { uninit_memory() };
self.read_block(id, s.as_buf_mut())?;
Ok(s)
}
Expand Down Expand Up @@ -179,7 +181,7 @@ impl vfs::INode for INodeImpl {
_ => panic!("Unknown file type"),
},
mode: disk_inode.mode,
type_: vfs::FileType::from(disk_inode.type_.clone()),
type_: vfs::FileType::from(disk_inode.type_),
blocks: disk_inode.blocks as usize,
atime: Timespec {
sec: disk_inode.atime as i64,
Expand Down Expand Up @@ -250,12 +252,12 @@ impl vfs::INode for INodeImpl {
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
if info.nlinks == 0 {
return Err(FsError::DirRemoved);
}

// Ensure the name is not exist
if !self.get_file_inode_id(name).is_none() {
if self.get_file_inode_id(name).is_some() {
return Err(FsError::EntryExist);
}

Expand Down Expand Up @@ -284,7 +286,7 @@ impl vfs::INode for INodeImpl {
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
if info.nlinks == 0 {
return Err(FsError::DirRemoved);
}
if name == "." {
Expand Down Expand Up @@ -321,10 +323,10 @@ impl vfs::INode for INodeImpl {
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
if info.nlinks == 0 {
return Err(FsError::DirRemoved);
}
if !self.get_file_inode_id(name).is_none() {
if self.get_file_inode_id(name).is_some() {
return Err(FsError::EntryExist);
}
let child = other
Expand All @@ -349,7 +351,7 @@ impl vfs::INode for INodeImpl {
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
if info.nlinks == 0 {
return Err(FsError::DirRemoved);
}
if old_name == "." {
Expand All @@ -369,7 +371,7 @@ impl vfs::INode for INodeImpl {
if dest_info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if dest_info.nlinks <= 0 {
if dest_info.nlinks == 0 {
return Err(FsError::DirRemoved);
}
if dest.get_file_inode_id(new_name).is_some() {
Expand Down Expand Up @@ -442,7 +444,7 @@ impl Drop for INodeImpl {
fn drop(&mut self) {
self.sync_all()
.expect("Failed to sync when dropping the SEFS Inode");
if self.disk_inode.read().nlinks <= 0 {
if self.disk_inode.read().nlinks == 0 {
self.disk_inode.write().sync();
self.fs.free_block(self.id);
self.fs.device.remove(self.id).unwrap();
Expand Down Expand Up @@ -654,7 +656,7 @@ impl SEFS {
.map(|(&id, _)| id)
.collect();
for id in remove_ids.iter() {
inodes.remove(&id);
inodes.remove(id);
}
}
fn get_freemap_block_id_of_group(group_id: usize) -> usize {
Expand Down
Loading

0 comments on commit 1a3246b

Please sign in to comment.