merge mksfs to fuse binutil

master
WangRunji 6 years ago
parent 62827eb7bb
commit ffa42fcc55

@ -4,4 +4,5 @@ members = [
"rcore-fs-sfs",
"rcore-fs-sefs",
"rcore-fs-fuse"
]
]
exclude = ["sefs-fuse"]

@ -12,5 +12,5 @@ fuse = "0.3"
structopt = "0.2"
env_logger = "0.3"
rcore-fs = { path = "../rcore-fs", features = ["std"] }
rcore-fs-sfs = { path = "../rcore-fs-sfs", features = ["std"] }
rcore-fs-sfs = { path = "../rcore-fs-sfs" }
rcore-fs-sefs = { path = "../rcore-fs-sefs", features = ["std"] }

@ -0,0 +1,222 @@
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, ReplyStatfs, Request};
use rcore_fs::vfs;
use std::collections::btree_map::BTreeMap;
use std::ffi::OsStr;
use std::sync::Arc;
//use log::*;
use time::Timespec;
const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
pub struct VfsFuse {
fs: Arc<vfs::FileSystem>,
inodes: BTreeMap<usize, Arc<vfs::INode>>,
}
impl VfsFuse {
pub fn new(fs: Arc<vfs::FileSystem>) -> Self {
let mut inodes = BTreeMap::new();
inodes.insert(1, fs.root_inode());
VfsFuse { fs, inodes }
}
fn trans_time(time: vfs::Timespec) -> Timespec {
Timespec {
sec: time.sec,
nsec: time.nsec,
}
}
fn trans_attr(info: vfs::Metadata) -> FileAttr {
FileAttr {
ino: info.inode as u64,
size: info.size as u64,
blocks: info.blocks as u64,
atime: Self::trans_time(info.atime),
mtime: Self::trans_time(info.mtime),
ctime: Self::trans_time(info.ctime),
crtime: Timespec { sec: 0, nsec: 0 },
kind: Self::trans_type(info.type_),
perm: info.mode,
nlink: info.nlinks as u32,
uid: info.uid as u32,
gid: info.gid as u32,
rdev: 0,
flags: 0,
}
}
fn trans_type(type_: vfs::FileType) -> FileType {
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,
vfs::FileType::NamedPipe => FileType::NamedPipe,
vfs::FileType::Socket => FileType::Socket,
}
}
fn trans_error(err: vfs::FsError) -> i32 {
use vfs::FsError::*;
use libc::*;
match err {
NotSupported => ENOSYS,
EntryNotFound => ENOENT,
EntryExist => EEXIST,
IsDir => EISDIR,
NotFile => EISDIR,
NotDir => ENOTDIR,
NotSameFs => EXDEV,
InvalidParam => EINVAL,
NoDeviceSpace => ENOSPC,
DirRemoved => ENOENT,
DirNotEmpty => ENOTEMPTY,
WrongFs => EINVAL,
_ => EINVAL,
}
}
fn get_inode(&self, ino: u64) -> vfs::Result<&Arc<vfs::INode>> {
self.inodes.get(&(ino as usize)).ok_or(vfs::FsError::EntryNotFound)
}
}
/// Helper macro to reply error when VFS operation fails
macro_rules! try_vfs {
($reply:expr, $expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
$reply.error(Self::trans_error(err));
return;
}
});
}
impl Filesystem for VfsFuse {
fn destroy(&mut self, _req: &Request) {
self.inodes.clear();
self.fs.sync().unwrap();
}
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.lookup(name.to_str().unwrap()));
let info = try_vfs!(reply, target.metadata());
self.inodes.insert(info.inode, target);
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.attr(&TTL, &attr);
}
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, mode));
let info = try_vfs!(reply, target.metadata());
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) {
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, mode));
let info = try_vfs!(reply, target.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn unlink(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
let name = name.to_str().unwrap();
let parent = try_vfs!(reply, self.get_inode(parent));
try_vfs!(reply, parent.unlink(name));
reply.ok();
}
fn rmdir(&mut self, req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
self.unlink(req, parent, name, reply);
}
fn rename(&mut self, _req: &Request, parent: u64, name: &OsStr, newparent: u64, newname: &OsStr, reply: ReplyEmpty) {
let name = name.to_str().unwrap();
let newname = newname.to_str().unwrap();
if parent == newparent {
let parent = try_vfs!(reply, self.get_inode(parent));
try_vfs!(reply, parent.rename(name, newname));
} else {
let parent = try_vfs!(reply, self.get_inode(parent));
let newparent = try_vfs!(reply, self.get_inode(newparent));
try_vfs!(reply, parent.move_(name, newparent, newname));
}
reply.ok();
}
fn link(&mut self, _req: &Request, ino: u64, newparent: u64, newname: &OsStr, reply: ReplyEntry) {
let newname = newname.to_str().unwrap();
let inode = try_vfs!(reply, self.get_inode(ino));
let newparent = try_vfs!(reply, self.get_inode(newparent));
try_vfs!(reply, newparent.link(newname, inode));
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, size: u32, reply: ReplyData) {
let inode = try_vfs!(reply, self.get_inode(ino));
let mut data = Vec::<u8>::new();
data.resize(size as usize, 0);
try_vfs!(reply, inode.read_at(offset as usize, data.as_mut_slice()));
reply.data(data.as_slice());
}
fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, data: &[u8], _flags: u32, reply: ReplyWrite) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let end = offset as usize + data.len();
if end > info.size {
try_vfs!(reply, inode.resize(end));
}
let len = try_vfs!(reply, inode.write_at(offset as usize, data));
reply.written(len as u32);
}
fn flush(&mut self, _req: &Request, ino: u64, _fh: u64, _lock_owner: u64, reply: ReplyEmpty) {
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn fsync(&mut self, _req: &Request, ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let count = info.size;
for i in offset as usize..count {
let name = inode.get_entry(i).unwrap();
let inode = try_vfs!(reply, inode.find(name.as_str()));
let info = try_vfs!(reply, inode.metadata());
let kind = Self::trans_type(info.type_);
let full = reply.add(info.inode as u64, i as i64 + 1, kind, name);
if full {
break;
}
}
reply.ok();
}
fn statfs(&mut self, _req: &Request, _ino: u64, reply: ReplyStatfs) {
let info = self.fs.info();
reply.statfs(info.blocks as u64, info.bfree as u64, info.bavail as u64,
info.files as u64, info.ffree as u64, info.bsize as u32,
info.namemax as u32, info.frsize as u32);
}
}

@ -1,222 +1,2 @@
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, ReplyStatfs, Request};
use rcore_fs::vfs;
use std::collections::btree_map::BTreeMap;
use std::ffi::OsStr;
use std::sync::Arc;
//use log::*;
use time::Timespec;
const TTL: Timespec = Timespec { sec: 1, nsec: 0 }; // 1 second
pub struct VfsFuse<T: vfs::FileSystem> {
fs: Arc<T>,
inodes: BTreeMap<usize, Arc<vfs::INode>>,
}
impl<T: vfs::FileSystem> VfsFuse<T> {
pub fn new(fs: Arc<T>) -> Self {
let mut inodes = BTreeMap::new();
inodes.insert(1, fs.root_inode());
VfsFuse { fs, inodes }
}
fn trans_time(time: vfs::Timespec) -> Timespec {
Timespec {
sec: time.sec,
nsec: time.nsec,
}
}
fn trans_attr(info: vfs::Metadata) -> FileAttr {
FileAttr {
ino: info.inode as u64,
size: info.size as u64,
blocks: info.blocks as u64,
atime: Self::trans_time(info.atime),
mtime: Self::trans_time(info.mtime),
ctime: Self::trans_time(info.ctime),
crtime: Timespec { sec: 0, nsec: 0 },
kind: Self::trans_type(info.type_),
perm: info.mode,
nlink: info.nlinks as u32,
uid: info.uid as u32,
gid: info.gid as u32,
rdev: 0,
flags: 0,
}
}
fn trans_type(type_: vfs::FileType) -> FileType {
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,
vfs::FileType::NamedPipe => FileType::NamedPipe,
vfs::FileType::Socket => FileType::Socket,
}
}
fn trans_error(err: vfs::FsError) -> i32 {
use vfs::FsError::*;
use libc::*;
match err {
NotSupported => ENOSYS,
EntryNotFound => ENOENT,
EntryExist => EEXIST,
IsDir => EISDIR,
NotFile => EISDIR,
NotDir => ENOTDIR,
NotSameFs => EXDEV,
InvalidParam => EINVAL,
NoDeviceSpace => ENOSPC,
DirRemoved => ENOENT,
DirNotEmpty => ENOTEMPTY,
WrongFs => EINVAL,
_ => EINVAL,
}
}
fn get_inode(&self, ino: u64) -> vfs::Result<&Arc<vfs::INode>> {
self.inodes.get(&(ino as usize)).ok_or(vfs::FsError::EntryNotFound)
}
}
/// Helper macro to reply error when VFS operation fails
macro_rules! try_vfs {
($reply:expr, $expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
$reply.error(Self::trans_error(err));
return;
}
});
}
impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
fn destroy(&mut self, _req: &Request) {
self.inodes.clear();
self.fs.sync().unwrap();
}
fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.lookup(name.to_str().unwrap()));
let info = try_vfs!(reply, target.metadata());
self.inodes.insert(info.inode, target);
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.attr(&TTL, &attr);
}
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, mode));
let info = try_vfs!(reply, target.metadata());
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) {
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, mode));
let info = try_vfs!(reply, target.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn unlink(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
let name = name.to_str().unwrap();
let parent = try_vfs!(reply, self.get_inode(parent));
try_vfs!(reply, parent.unlink(name));
reply.ok();
}
fn rmdir(&mut self, req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
self.unlink(req, parent, name, reply);
}
fn rename(&mut self, _req: &Request, parent: u64, name: &OsStr, newparent: u64, newname: &OsStr, reply: ReplyEmpty) {
let name = name.to_str().unwrap();
let newname = newname.to_str().unwrap();
if parent == newparent {
let parent = try_vfs!(reply, self.get_inode(parent));
try_vfs!(reply, parent.rename(name, newname));
} else {
let parent = try_vfs!(reply, self.get_inode(parent));
let newparent = try_vfs!(reply, self.get_inode(newparent));
try_vfs!(reply, parent.move_(name, newparent, newname));
}
reply.ok();
}
fn link(&mut self, _req: &Request, ino: u64, newparent: u64, newname: &OsStr, reply: ReplyEntry) {
let newname = newname.to_str().unwrap();
let inode = try_vfs!(reply, self.get_inode(ino));
let newparent = try_vfs!(reply, self.get_inode(newparent));
try_vfs!(reply, newparent.link(newname, inode));
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, size: u32, reply: ReplyData) {
let inode = try_vfs!(reply, self.get_inode(ino));
let mut data = Vec::<u8>::new();
data.resize(size as usize, 0);
try_vfs!(reply, inode.read_at(offset as usize, data.as_mut_slice()));
reply.data(data.as_slice());
}
fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, data: &[u8], _flags: u32, reply: ReplyWrite) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let end = offset as usize + data.len();
if end > info.size {
try_vfs!(reply, inode.resize(end));
}
let len = try_vfs!(reply, inode.write_at(offset as usize, data));
reply.written(len as u32);
}
fn flush(&mut self, _req: &Request, ino: u64, _fh: u64, _lock_owner: u64, reply: ReplyEmpty) {
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn fsync(&mut self, _req: &Request, ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
let inode = try_vfs!(reply, self.get_inode(ino));
let info = try_vfs!(reply, inode.metadata());
let count = info.size;
for i in offset as usize..count {
let name = inode.get_entry(i).unwrap();
let inode = try_vfs!(reply, inode.find(name.as_str()));
let info = try_vfs!(reply, inode.metadata());
let kind = Self::trans_type(info.type_);
let full = reply.add(info.inode as u64, i as i64 + 1, kind, name);
if full {
break;
}
}
reply.ok();
}
fn statfs(&mut self, _req: &Request, _ino: u64, reply: ReplyStatfs) {
let info = self.fs.info();
reply.statfs(info.blocks as u64, info.bfree as u64, info.bavail as u64,
info.files as u64, info.ffree as u64, info.bsize as u32,
info.namemax as u32, info.frsize as u32);
}
}
pub mod fuse;
pub mod zip;

@ -1,38 +1,104 @@
use std::fs::OpenOptions;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use structopt::StructOpt;
use rcore_fs::dev::std_impl::StdTimeProvider;
use rcore_fs::vfs::FileSystem;
use rcore_fs_fuse::fuse::VfsFuse;
use rcore_fs_fuse::zip::{unzip_dir, zip_dir};
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 {
/// Command
#[structopt(subcommand)]
cmd: Cmd,
/// Image file
#[structopt(parse(from_os_str))]
image: PathBuf,
/// Mount point
/// Target directory
#[structopt(parse(from_os_str))]
mount_point: PathBuf,
dir: PathBuf,
/// File system: [sfs | sefs]
#[structopt(short = "f", long = "fs", default_value = "sfs")]
fs: String,
}
#[derive(Debug, StructOpt)]
enum Cmd {
/// Create a new <image> for <dir>
#[structopt(name = "zip")]
Zip,
/// Unzip data from given <image> to <dir>
#[structopt(name = "unzip")]
Unzip,
/// Mount <image> to <dir>
#[structopt(name = "mount")]
Mount,
}
fn main() {
env_logger::init().unwrap();
let opt = Opt::from_args();
// let img = OpenOptions::new().read(true).write(true).open(&opt.image)
// .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), &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), &StdTimeProvider)
.expect("failed to create sefs")
// open or create
let create = match opt.cmd {
Cmd::Mount => !opt.image.is_dir() && !opt.image.is_file(),
Cmd::Zip => true,
Cmd::Unzip => false,
};
let fs: Arc<FileSystem> = match opt.fs.as_str() {
"sfs" => {
let file = OpenOptions::new().read(true).write(true).create(true)
.open(&opt.image)
.expect("failed to open image");
let device = Mutex::new(file);
const MAX_SPACE: usize = 0x1000 * 0x1000 * 8; // 128MB (4K bitmap)
match create {
true => sfs::SimpleFileSystem::create(Box::new(device), MAX_SPACE),
false => sfs::SimpleFileSystem::open(Box::new(device))
.expect("failed to open sfs"),
}
}
"sefs" => {
std::fs::create_dir_all(&opt.image).unwrap();
let device = sefs::dev::StdStorage::new(&opt.image);
match create {
true => {
sefs::SEFS::create(Box::new(device), &StdTimeProvider)
.expect("failed to create sefs")
}
false => {
sefs::SEFS::open(Box::new(device), &StdTimeProvider)
.expect("failed to open sefs")
}
}
}
_ => panic!("unsupported file system"),
};
fuse::mount(VfsFuse::new(sfs), &opt.mount_point, &[])
.expect("failed to mount fs");
match opt.cmd {
Cmd::Mount => {
fuse::mount(VfsFuse::new(fs), &opt.dir, &[])
.expect("failed to mount fs");
}
Cmd::Zip => {
zip_dir(&opt.dir, fs.root_inode())
.expect("failed to zip fs");
}
Cmd::Unzip => {
std::fs::create_dir(&opt.dir)
.expect("failed to create dir");
unzip_dir(&opt.dir, fs.root_inode())
.expect("failed to unzip fs");
}
}
}

@ -1,41 +1,14 @@
use std::env;
use std::fs;
use std::io::{Read, Write, Result};
use std::path::Path;
use std::io::{Read, Result, Write};
use std::mem::uninitialized;
use std::sync::{Arc, Mutex};
use std::path::Path;
use std::sync::Arc;
use rcore_fs::vfs::*;
use rcore_fs_sfs::SimpleFileSystem;
const DEFAULT_MODE: u32 = 0o664;
fn main() -> Result<()> {
let args: Vec<_> = env::args().collect();
let cmd = &args[1];
let dir_path = Path::new(&args[2]);
let img_path = Path::new(&args[3]);
match cmd.as_str() {
"zip" => zip(dir_path, img_path),
"unzip" => unzip(dir_path, img_path),
_ => {
println!("USAGE: <zip|unzip> <PATH> <IMG>");
panic!("Invalid command: {}", cmd);
}
}
}
fn zip(path: &Path, img_path: &Path) -> Result<()> {
let img = fs::OpenOptions::new().read(true).write(true).create(true).open(img_path)?;
let img = Mutex::new(img);
let sfs = SimpleFileSystem::create(Box::new(img), 0x1000000);
let inode = sfs.root_inode();
zip_dir(path, inode)?;
sfs.sync().expect("Failed to sync");
Ok(())
}
fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
pub fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
let dir = fs::read_dir(path).expect("Failed to open dir");
for entry in dir {
let entry = entry?;
@ -62,16 +35,7 @@ fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
Ok(())
}
fn unzip(path: &Path, img_path: &Path) -> Result<()> {
let img = fs::File::open(img_path)?;
let img = Mutex::new(img);
let sfs = SimpleFileSystem::open(Box::new(img)).expect("Failed to open sfs");
let inode = sfs.root_inode();
fs::create_dir(&path)?;
unzip_dir(path, inode)
}
fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
pub fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
let files = inode.list().expect("Failed to list files from INode");
for name in files.iter().skip(2) {
let inode = inode.lookup(name.as_str()).expect("Failed to lookup");
@ -98,4 +62,4 @@ fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
}
}
Ok(())
}
}

@ -4,11 +4,6 @@ version = "0.1.0"
authors = ["WangRunji <wangrunji0408@163.com>"]
edition = "2018"
[[bin]]
name = "mksfs"
path = "src/bin/mksfs.rs"
required-features = ["std"]
[dependencies]
rcore-fs = { path = "../rcore-fs" }
static_assertions = "0.3"
@ -19,6 +14,3 @@ log = "0.4"
version = "0.9"
default-features = false
features = ["alloc"]
[features]
std = ["rcore-fs/std"]

@ -1,4 +1,3 @@
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![feature(alloc)]
#![feature(const_str_len)]

@ -30,21 +30,43 @@ use std::path::PathBuf;
use structopt::StructOpt;
use rcore_fs_fuse::VfsFuse;
use rcore_fs_fuse::fuse::VfsFuse;
use rcore_fs_fuse::zip::{zip_dir, unzip_dir};
use rcore_fs_sefs as sefs;
use rcore_fs::dev::std_impl::StdTimeProvider;
use rcore_fs::vfs::FileSystem;
mod sgx_dev;
mod enclave;
#[derive(Debug, StructOpt)]
struct Opt {
/// Command
#[structopt(subcommand)]
cmd: Cmd,
/// Image file
#[structopt(parse(from_os_str))]
image: PathBuf,
/// Mount point
/// Target directory
#[structopt(parse(from_os_str))]
mount_point: PathBuf,
dir: PathBuf,
}
#[derive(Debug, StructOpt)]
enum Cmd {
/// Create a new <image> for <dir>
#[structopt(name = "zip")]
Zip,
/// Unzip data from given <image> to <dir>
#[structopt(name = "unzip")]
Unzip,
/// Mount <image> to <dir>
#[structopt(name = "mount")]
Mount,
}
fn main() {
@ -63,16 +85,40 @@ 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), &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), &StdTimeProvider)
.expect("failed to create sefs")
// open or create
let create = match opt.cmd {
Cmd::Mount => !opt.image.is_dir(),
Cmd::Zip => true,
Cmd::Unzip => false,
};
let device = sgx_dev::SgxStorage::new(enclave.geteid(), &opt.image);
let fs = match create {
true => {
std::fs::create_dir(&opt.image)
.expect("failed to create dir for SEFS");
sefs::SEFS::create(Box::new(device), &StdTimeProvider)
.expect("failed to create sefs")
}
false => {
sefs::SEFS::open(Box::new(device), &StdTimeProvider)
.expect("failed to open sefs")
}
};
fuse::mount(VfsFuse::new(sfs), &opt.mount_point, &[])
.expect("failed to mount fs");
match opt.cmd {
Cmd::Mount => {
fuse::mount(VfsFuse::new(fs), &opt.dir, &[])
.expect("failed to mount fs");
}
Cmd::Zip => {
zip_dir(&opt.dir, fs.root_inode())
.expect("failed to zip fs");
}
Cmd::Unzip => {
std::fs::create_dir(&opt.dir)
.expect("failed to create dir");
unzip_dir(&opt.dir, fs.root_inode())
.expect("failed to unzip fs");
}
}
}

Loading…
Cancel
Save