impl mode & time in create

master
WangRunji 6 years ago
parent da42736223
commit 5265b8e36f

@ -47,6 +47,9 @@ impl<T: vfs::FileSystem> VfsFuse<T> {
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<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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);

@ -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, &[])

@ -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,
}
}
}

@ -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<Arc<vfs::INode>> {
fn create(&self, name: &str, type_: vfs::FileType, mode: u32) -> vfs::Result<Arc<vfs::INode>> {
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<Storage>,
/// metadata file
meta_file: Box<File>,
/// Time provider
time_provider: &'static TimeProvider,
/// Pointer to self, used by INodes
self_ptr: Weak<SEFS>,
}
impl SEFS {
/// Load SEFS
pub fn open(device: Box<Storage>) -> vfs::Result<Arc<Self>> {
pub fn open(device: Box<Storage>, time_provider: &'static TimeProvider) -> vfs::Result<Arc<Self>> {
let meta_file = device.open(0)?;
let super_block = meta_file.load_struct::<SuperBlock>(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<Storage>) -> vfs::Result<Arc<Self>> {
pub fn create(device: Box<Storage>, time_provider: &'static TimeProvider) -> vfs::Result<Arc<Self>> {
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<Arc<INodeImpl>> {
fn new_inode(&self, type_: FileType, mode: u16) -> vfs::Result<Arc<INodeImpl>> {
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<Arc<INodeImpl>> {
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)| {

@ -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] {

@ -310,7 +310,7 @@ impl vfs::INode for INodeImpl {
}
self._resize(len)
}
fn create(&self, name: &str, type_: vfs::FileType) -> vfs::Result<Arc<vfs::INode>> {
fn create(&self, name: &str, type_: vfs::FileType, _mode: u32) -> vfs::Result<Arc<vfs::INode>> {
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

@ -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}

@ -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<File> {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Option<usize> {
@ -24,4 +25,16 @@ impl Device for Mutex<File> {
_ => None,
}
}
}
}
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,
}
}
}

@ -9,7 +9,7 @@ pub trait INode: Any + Sync + Send {
fn info(&self) -> Result<FileInfo>;
fn sync(&self) -> Result<()>;
fn resize(&self, len: usize) -> Result<()>;
fn create(&self, name: &str, type_: FileType) -> Result<Arc<INode>>;
fn create(&self, name: &str, type_: FileType, mode: u32) -> Result<Arc<INode>>;
fn unlink(&self, name: &str) -> Result<()>;
/// user of the vfs api should call borrow_mut by itself
fn link(&self, name: &str, other: &Arc<INode>) -> Result<()>;
@ -113,6 +113,9 @@ pub struct Timespec {
pub enum FileType {
File,
Dir,
SymLink,
CharDevice,
BlockDevice,
}
#[derive(Debug)]

@ -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"] }

@ -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, &[])

Loading…
Cancel
Save