From 5265b8e36f46b5e1bf15bbdb84bd1f33bd8b0bd4 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Tue, 19 Feb 2019 23:13:51 +0800 Subject: [PATCH] impl mode & time in create --- rcore-fs-fuse/src/lib.rs | 11 ++++-- rcore-fs-fuse/src/main.rs | 5 ++- rcore-fs-sefs/src/dev/sgx_impl.rs | 21 +++++++++- rcore-fs-sefs/src/lib.rs | 65 ++++++++++++++++++------------- rcore-fs-sefs/src/structs.rs | 31 +-------------- rcore-fs-sfs/src/lib.rs | 3 +- rcore-fs/src/dev/mod.rs | 8 +++- rcore-fs/src/dev/std_impl.rs | 17 +++++++- rcore-fs/src/vfs.rs | 5 ++- sefs-fuse/app/Cargo.toml | 1 + sefs-fuse/app/src/main.rs | 5 ++- 11 files changed, 102 insertions(+), 70 deletions(-) diff --git a/rcore-fs-fuse/src/lib.rs b/rcore-fs-fuse/src/lib.rs index 1a80de5..d3267f9 100644 --- a/rcore-fs-fuse/src/lib.rs +++ b/rcore-fs-fuse/src/lib.rs @@ -47,6 +47,9 @@ impl VfsFuse { match type_ { vfs::FileType::File => FileType::RegularFile, vfs::FileType::Dir => FileType::Directory, + vfs::FileType::SymLink => FileType::Symlink, + vfs::FileType::CharDevice => FileType::CharDevice, + vfs::FileType::BlockDevice => FileType::BlockDevice, } } fn trans_error(err: vfs::FsError) -> i32 { @@ -106,20 +109,20 @@ impl Filesystem for VfsFuse { reply.attr(&TTL, &attr); } - fn mknod(&mut self, _req: &Request, parent: u64, name: &OsStr, _mode: u32, _rdev: u32, reply: ReplyEntry) { + fn mknod(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, _rdev: u32, reply: ReplyEntry) { let name = name.to_str().unwrap(); let inode = try_vfs!(reply, self.get_inode(parent)); - let target = try_vfs!(reply, inode.create(name, vfs::FileType::File)); + let target = try_vfs!(reply, inode.create(name, vfs::FileType::File, mode)); let info = try_vfs!(reply, target.info()); self.inodes.insert(info.inode, target); let attr = Self::trans_attr(info); reply.entry(&TTL, &attr, 0); } - fn mkdir(&mut self, _req: &Request, parent: u64, name: &OsStr, _mode: u32, reply: ReplyEntry) { + fn mkdir(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, reply: ReplyEntry) { let name = name.to_str().unwrap(); let inode = try_vfs!(reply, self.get_inode(parent)); - let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir)); + let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir, mode)); let info = try_vfs!(reply, target.info()); let attr = Self::trans_attr(info); reply.entry(&TTL, &attr, 0); diff --git a/rcore-fs-fuse/src/main.rs b/rcore-fs-fuse/src/main.rs index c8b1bc8..d96dd9d 100644 --- a/rcore-fs-fuse/src/main.rs +++ b/rcore-fs-fuse/src/main.rs @@ -6,6 +6,7 @@ use structopt::StructOpt; use rcore_fs_sefs as sefs; use rcore_fs_sfs as sfs; use rcore_fs_fuse::VfsFuse; +use rcore_fs::dev::std_impl::StdTimeProvider; #[derive(Debug, StructOpt)] struct Opt { @@ -24,12 +25,12 @@ fn main() { // .expect("failed to open image"); let sfs = if opt.image.is_dir() { let img = sefs::dev::StdStorage::new(&opt.image); - sefs::SEFS::open(Box::new(img)) + sefs::SEFS::open(Box::new(img), &StdTimeProvider) .expect("failed to open sefs") } else { std::fs::create_dir_all(&opt.image).unwrap(); let img = sefs::dev::StdStorage::new(&opt.image); - sefs::SEFS::create(Box::new(img)) + sefs::SEFS::create(Box::new(img), &StdTimeProvider) .expect("failed to create sefs") }; fuse::mount(VfsFuse::new(sfs), &opt.mount_point, &[]) diff --git a/rcore-fs-sefs/src/dev/sgx_impl.rs b/rcore-fs-sefs/src/dev/sgx_impl.rs index 03a846c..2d441f6 100644 --- a/rcore-fs-sefs/src/dev/sgx_impl.rs +++ b/rcore-fs-sefs/src/dev/sgx_impl.rs @@ -1,10 +1,15 @@ #![cfg(feature = "sgx")] use std::boxed::Box; +use std::io::{Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; -use std::sgxfs::{SgxFile as File, OpenOptions, remove}; -use std::io::{Read, Write, Seek, SeekFrom}; +use std::sgxfs::{OpenOptions, remove, SgxFile as File}; use std::sync::SgxMutex as Mutex; +use std::time::{SystemTime, UNIX_EPOCH}; + +use rcore_fs::dev::TimeProvider; +use rcore_fs::vfs::Timespec; + use super::{DeviceError, DevResult}; pub struct StdStorage { @@ -88,3 +93,15 @@ impl super::File for LockedFile { Ok(()) } } + +pub struct SgxTimeProvider; + +impl TimeProvider for StdTimeProvider { + fn current_time(&self) -> Timespec { + let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + Timespec { + sec: duration.as_secs() as i64, + nsec: duration.subsec_nanos() as i32, + } + } +} diff --git a/rcore-fs-sefs/src/lib.rs b/rcore-fs-sefs/src/lib.rs index a5197e0..6004d54 100644 --- a/rcore-fs-sefs/src/lib.rs +++ b/rcore-fs-sefs/src/lib.rs @@ -2,7 +2,6 @@ #![feature(alloc)] extern crate alloc; - #[cfg(feature = "sgx")] #[macro_use] extern crate sgx_tstd as std; @@ -13,11 +12,11 @@ use core::fmt::{Debug, Error, Formatter}; use core::mem::uninitialized; use bitvec::BitVec; -//use log::*; -use spin::RwLock; - +use rcore_fs::dev::TimeProvider; use rcore_fs::dirty::Dirty; use rcore_fs::vfs::{self, FileSystem, FsError, INode, Timespec}; +//use log::*; +use spin::RwLock; use self::dev::*; use self::structs::*; @@ -153,7 +152,7 @@ impl vfs::INode for INodeImpl { FileType::Dir => disk_inode.blocks as usize, _ => panic!("Unknown file type"), }, - mode: 0o777, + mode: disk_inode.mode, type_: vfs::FileType::from(disk_inode.type_.clone()), blocks: disk_inode.blocks as usize, atime: Timespec { sec: disk_inode.atime as i64, nsec: 0 }, @@ -180,7 +179,12 @@ impl vfs::INode for INodeImpl { self.disk_inode.write().size = len as u32; Ok(()) } - fn create(&self, name: &str, type_: vfs::FileType) -> vfs::Result> { + fn create(&self, name: &str, type_: vfs::FileType, mode: u32) -> vfs::Result> { + let type_ = match type_ { + vfs::FileType::File => FileType::File, + vfs::FileType::Dir => FileType::Dir, + _ => return Err(vfs::FsError::InvalidParam), + }; let info = self.info()?; if info.type_ != vfs::FileType::Dir { return Err(FsError::NotDir); @@ -195,10 +199,10 @@ impl vfs::INode for INodeImpl { } // Create new INode - let inode = match type_ { - vfs::FileType::File => self.fs.new_inode_file()?, - vfs::FileType::Dir => self.fs.new_inode_dir(self.id)?, - }; + let inode = self.fs.new_inode(type_, mode as u16)?; + if type_ == FileType::Dir { + inode.dirent_init(self.id)?; + } // Write new entry let entry = DiskEntry { @@ -207,7 +211,7 @@ impl vfs::INode for INodeImpl { }; self.dirent_append(&entry)?; inode.nlinks_inc(); - if type_ == vfs::FileType::Dir { + if type_ == FileType::Dir { inode.nlinks_inc(); //for . self.nlinks_inc(); //for .. } @@ -404,13 +408,15 @@ pub struct SEFS { device: Box, /// metadata file meta_file: Box, + /// Time provider + time_provider: &'static TimeProvider, /// Pointer to self, used by INodes self_ptr: Weak, } impl SEFS { /// Load SEFS - pub fn open(device: Box) -> vfs::Result> { + pub fn open(device: Box, time_provider: &'static TimeProvider) -> vfs::Result> { let meta_file = device.open(0)?; let super_block = meta_file.load_struct::(BLKN_SUPER)?; if !super_block.check() { @@ -424,22 +430,23 @@ impl SEFS { inodes: RwLock::new(BTreeMap::new()), device, meta_file, + time_provider, self_ptr: Weak::default(), }.wrap()) } /// Create a new SEFS - pub fn create(device: Box) -> vfs::Result> { + pub fn create(device: Box, time_provider: &'static TimeProvider) -> vfs::Result> { let blocks = BLKBITS; let super_block = SuperBlock { magic: MAGIC, blocks: blocks as u32, - unused_blocks: blocks as u32 - 3, + unused_blocks: blocks as u32 - 2, }; let free_map = { let mut bitset = BitVec::with_capacity(BLKBITS); bitset.extend(core::iter::repeat(false).take(BLKBITS)); - for i in 3..blocks { + for i in 2..blocks { bitset.set(i, true); } bitset @@ -453,11 +460,13 @@ impl SEFS { inodes: RwLock::new(BTreeMap::new()), device, meta_file, + time_provider, self_ptr: Weak::default(), }.wrap(); // Init root INode - let root = sefs._new_inode(BLKN_ROOT, Dirty::new_dirty(DiskINode::new_dir()), true); + let root = sefs.new_inode(FileType::Dir, 0o777)?; + assert_eq!(root.id, BLKN_ROOT); root.dirent_init(BLKN_ROOT)?; root.nlinks_inc(); //for . root.nlinks_inc(); //for ..(root's parent is itself) @@ -530,19 +539,23 @@ impl SEFS { self._new_inode(id, disk_inode, false) } /// Create a new INode file - fn new_inode_file(&self) -> vfs::Result> { + fn new_inode(&self, type_: FileType, mode: u16) -> vfs::Result> { let id = self.alloc_block().ok_or(FsError::NoDeviceSpace)?; - let disk_inode = Dirty::new_dirty(DiskINode::new_file()); + let time = self.time_provider.current_time().sec as u32; + let disk_inode = Dirty::new_dirty(DiskINode { + size: 0, + type_, + mode, + nlinks: 0, + blocks: 0, + uid: 0, + gid: 0, + atime: time, + mtime: time, + ctime: time, + }); Ok(self._new_inode(id, disk_inode, true)) } - /// Create a new INode dir - fn new_inode_dir(&self, parent: INodeId) -> vfs::Result> { - let id = self.alloc_block().ok_or(FsError::NoDeviceSpace)?; - let disk_inode = Dirty::new_dirty(DiskINode::new_dir()); - let inode = self._new_inode(id, disk_inode, true); - inode.dirent_init(parent)?; - Ok(inode) - } fn flush_weak_inodes(&self) { let mut inodes = self.inodes.write(); let remove_ids: Vec<_> = inodes.iter().filter(|(_, inode)| { diff --git a/rcore-fs-sefs/src/structs.rs b/rcore-fs-sefs/src/structs.rs index 69e2e64..a2b54dd 100644 --- a/rcore-fs-sefs/src/structs.rs +++ b/rcore-fs-sefs/src/structs.rs @@ -26,6 +26,8 @@ pub struct DiskINode { pub size: u32, /// one of SYS_TYPE_* above pub type_: FileType, + /// permission + pub mode: u16, /// number of hard links to this file /// Note: "." and ".." is counted in this nlinks pub nlinks: u16, @@ -79,35 +81,6 @@ impl SuperBlock { } } -impl DiskINode { - pub const fn new_file() -> Self { - DiskINode { - size: 0, - type_: FileType::File, - nlinks: 0, - blocks: 0, - uid: 0, - gid: 0, - atime: 0, - mtime: 0, - ctime: 0 - } - } - pub const fn new_dir() -> Self { - DiskINode { - size: 0, - type_: FileType::Dir, - nlinks: 0, - blocks: 0, - uid: 0, - gid: 0, - atime: 0, - mtime: 0, - ctime: 0 - } - } -} - /// Convert structs to [u8] slice pub trait AsBuf { fn as_buf(&self) -> &[u8] { diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 4ebef13..7880884 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -310,7 +310,7 @@ impl vfs::INode for INodeImpl { } self._resize(len) } - fn create(&self, name: &str, type_: vfs::FileType) -> vfs::Result> { + fn create(&self, name: &str, type_: vfs::FileType, _mode: u32) -> vfs::Result> { let info = self.info()?; if info.type_!=vfs::FileType::Dir { return Err(FsError::NotDir); @@ -328,6 +328,7 @@ impl vfs::INode for INodeImpl { let inode = match type_ { vfs::FileType::File => self.fs.new_inode_file()?, vfs::FileType::Dir => self.fs.new_inode_dir(self.id)?, + _ => return Err(vfs::FsError::InvalidParam), }; // Write new entry diff --git a/rcore-fs/src/dev/mod.rs b/rcore-fs/src/dev/mod.rs index a871423..343adb6 100644 --- a/rcore-fs/src/dev/mod.rs +++ b/rcore-fs/src/dev/mod.rs @@ -1,6 +1,12 @@ use crate::util::*; +use crate::vfs::Timespec; -mod std_impl; +pub mod std_impl; + +/// A current time provider +pub trait TimeProvider: Send + Sync { + fn current_time(&self) -> Timespec; +} /// Interface for FS to read & write /// TODO: use std::io::{Read, Write} diff --git a/rcore-fs/src/dev/std_impl.rs b/rcore-fs/src/dev/std_impl.rs index d58e628..43c0009 100644 --- a/rcore-fs/src/dev/std_impl.rs +++ b/rcore-fs/src/dev/std_impl.rs @@ -3,8 +3,9 @@ use std::fs::File; use std::io::{Read, Seek, SeekFrom, Write}; use std::sync::Mutex; +use std::time::{SystemTime, UNIX_EPOCH}; -use super::Device; +use super::*; impl Device for Mutex { fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option { @@ -24,4 +25,16 @@ impl Device for Mutex { _ => None, } } -} \ No newline at end of file +} + +pub struct StdTimeProvider; + +impl TimeProvider for StdTimeProvider { + fn current_time(&self) -> Timespec { + let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + Timespec { + sec: duration.as_secs() as i64, + nsec: duration.subsec_nanos() as i32, + } + } +} diff --git a/rcore-fs/src/vfs.rs b/rcore-fs/src/vfs.rs index 22456f2..5310b0b 100644 --- a/rcore-fs/src/vfs.rs +++ b/rcore-fs/src/vfs.rs @@ -9,7 +9,7 @@ pub trait INode: Any + Sync + Send { fn info(&self) -> Result; fn sync(&self) -> Result<()>; fn resize(&self, len: usize) -> Result<()>; - fn create(&self, name: &str, type_: FileType) -> Result>; + fn create(&self, name: &str, type_: FileType, mode: u32) -> Result>; fn unlink(&self, name: &str) -> Result<()>; /// user of the vfs api should call borrow_mut by itself fn link(&self, name: &str, other: &Arc) -> Result<()>; @@ -113,6 +113,9 @@ pub struct Timespec { pub enum FileType { File, Dir, + SymLink, + CharDevice, + BlockDevice, } #[derive(Debug)] diff --git a/sefs-fuse/app/Cargo.toml b/sefs-fuse/app/Cargo.toml index e9a0c93..c6a2bb4 100644 --- a/sefs-fuse/app/Cargo.toml +++ b/sefs-fuse/app/Cargo.toml @@ -14,3 +14,4 @@ structopt = "0.2" env_logger = "0.3" rcore-fs-fuse = { path = "../../rcore-fs-fuse" } rcore-fs-sefs = { path = "../../rcore-fs-sefs" } +rcore-fs = { path = "../../rcore-fs", features = ["std"] } diff --git a/sefs-fuse/app/src/main.rs b/sefs-fuse/app/src/main.rs index 741f07c..a789f8a 100644 --- a/sefs-fuse/app/src/main.rs +++ b/sefs-fuse/app/src/main.rs @@ -32,6 +32,7 @@ use structopt::StructOpt; use rcore_fs_fuse::VfsFuse; use rcore_fs_sefs as sefs; +use rcore_fs::dev::std_impl::StdTimeProvider; mod sgx_dev; mod enclave; @@ -64,12 +65,12 @@ fn main() { let sfs = if opt.image.is_dir() { let img = sgx_dev::SgxStorage::new(enclave.geteid(), &opt.image); - sefs::SEFS::open(Box::new(img)) + sefs::SEFS::open(Box::new(img), &StdTimeProvider) .expect("failed to open sefs") } else { std::fs::create_dir_all(&opt.image).unwrap(); let img = sgx_dev::SgxStorage::new(enclave.geteid(), &opt.image); - sefs::SEFS::create(Box::new(img)) + sefs::SEFS::create(Box::new(img), &StdTimeProvider) .expect("failed to create sefs") }; fuse::mount(VfsFuse::new(sfs), &opt.mount_point, &[])