rename FileInfo to Metadata. complete FsInfo

master
WangRunji 7 years ago
parent 9b8f730e8e
commit 6e6b33f6fc

@ -0,0 +1,7 @@
[workspace]
members = [
"rcore-fs",
"rcore-fs-sfs",
"rcore-fs-sefs",
"rcore-fs-fuse"
]

@ -1,4 +1,4 @@
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, Request};
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;
@ -25,7 +25,7 @@ impl<T: vfs::FileSystem> VfsFuse<T> {
nsec: time.nsec,
}
}
fn trans_attr(info: vfs::FileInfo) -> FileAttr {
fn trans_attr(info: vfs::Metadata) -> FileAttr {
FileAttr {
ino: info.inode as u64,
size: info.size as u64,
@ -50,6 +50,8 @@ impl<T: vfs::FileSystem> VfsFuse<T> {
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 {
@ -96,7 +98,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, target.metadata());
self.inodes.insert(info.inode, target);
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
@ -104,7 +106,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.attr(&TTL, &attr);
}
@ -113,7 +115,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, target.metadata());
self.inodes.insert(info.inode, target);
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
@ -123,7 +125,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, target.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
@ -158,7 +160,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, inode.metadata());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
@ -173,7 +175,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
let info = try_vfs!(reply, inode.metadata());
let end = offset as usize + data.len();
if end > info.size {
try_vfs!(reply, inode.resize(end));
@ -196,12 +198,12 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
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.info());
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.info());
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 {
@ -210,4 +212,11 @@ impl<T: vfs::FileSystem> Filesystem for VfsFuse<T> {
}
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);
}
}

@ -143,9 +143,10 @@ impl vfs::INode for INodeImpl {
Ok(len)
}
/// the size returned here is logical size(entry num for directory), not the disk space used.
fn info(&self) -> vfs::Result<vfs::FileInfo> {
fn metadata(&self) -> vfs::Result<vfs::Metadata> {
let disk_inode = self.disk_inode.read();
Ok(vfs::FileInfo {
Ok(vfs::Metadata {
dev: 0,
inode: self.id,
size: match disk_inode.type_ {
FileType::File => disk_inode.size as usize,
@ -161,6 +162,7 @@ impl vfs::INode for INodeImpl {
nlinks: disk_inode.nlinks as usize,
uid: disk_inode.uid as usize,
gid: disk_inode.gid as usize,
blk_size: 0x1000,
})
}
fn sync(&self) -> vfs::Result<()> {
@ -185,7 +187,7 @@ impl vfs::INode for INodeImpl {
vfs::FileType::Dir => FileType::Dir,
_ => return Err(vfs::FsError::InvalidParam),
};
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
@ -219,7 +221,7 @@ impl vfs::INode for INodeImpl {
Ok(inode)
}
fn unlink(&self, name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -254,7 +256,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn link(&self, name: &str, other: &Arc<INode>) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -268,7 +270,7 @@ impl vfs::INode for INodeImpl {
if !Arc::ptr_eq(&self.fs, &child.fs) {
return Err(FsError::NotSameFs);
}
if child.info()?.type_ == vfs::FileType::Dir {
if child.metadata()?.type_ == vfs::FileType::Dir {
return Err(FsError::IsDir);
}
let entry = DiskEntry {
@ -280,7 +282,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn rename(&self, old_name: &str, new_name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -311,7 +313,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn move_(&self, old_name: &str, target: &Arc<INode>, new_name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -329,10 +331,10 @@ impl vfs::INode for INodeImpl {
if !Arc::ptr_eq(&self.fs, &dest.fs) {
return Err(FsError::NotSameFs);
}
if dest.info()?.type_ != vfs::FileType::Dir {
if dest.metadata()?.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
if dest.info()?.nlinks <= 0 {
if dest.metadata()?.nlinks <= 0 {
return Err(FsError::DirRemoved)
}
@ -350,7 +352,7 @@ impl vfs::INode for INodeImpl {
dest.dirent_append(&entry)?;
self.dirent_remove(entry_id)?;
if inode.info()?.type_ == vfs::FileType::Dir {
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
}
@ -358,7 +360,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn find(&self, name: &str) -> vfs::Result<Arc<vfs::INode>> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -593,11 +595,18 @@ impl vfs::FileSystem for SEFS {
self.get_inode(BLKN_ROOT)
}
fn info(&self) -> &'static vfs::FsInfo {
static INFO: vfs::FsInfo = vfs::FsInfo {
max_file_size: MAX_FILE_SIZE,
};
&INFO
fn info(&self) -> vfs::FsInfo {
let sb = self.super_block.read();
vfs::FsInfo {
bsize: BLKSIZE,
frsize: BLKSIZE,
blocks: sb.blocks as usize,
bfree: sb.unused_blocks as usize,
bavail: sb.unused_blocks as usize,
files: sb.blocks as usize, // inaccurate
ffree: sb.unused_blocks as usize, // inaccurate
namemax: MAX_FNAME_LEN,
}
}
}

@ -8,6 +8,8 @@ use std::sync::{Arc, Mutex};
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];
@ -41,7 +43,7 @@ fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
let name = name_.to_str().unwrap();
let type_ = entry.file_type()?;
if type_.is_file() {
let inode = inode.create(name, FileType::File).expect("Failed to create INode");
let inode = inode.create(name, FileType::File, DEFAULT_MODE).expect("Failed to create INode");
let mut file = fs::File::open(entry.path())?;
inode.resize(file.metadata().unwrap().len() as usize).expect("Failed to resize INode");
let mut buf: [u8; 4096] = unsafe { uninitialized() };
@ -53,7 +55,7 @@ fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
offset += len;
}
} else if type_.is_dir() {
let inode = inode.create(name, FileType::Dir).expect("Failed to create INode");
let inode = inode.create(name, FileType::Dir, DEFAULT_MODE).expect("Failed to create INode");
zip_dir(entry.path().as_path(), inode)?;
}
}
@ -75,7 +77,7 @@ fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
let inode = inode.lookup(name.as_str()).expect("Failed to lookup");
let mut path = path.to_path_buf();
path.push(name);
let info = inode.info().expect("Failed to get file info");
let info = inode.metadata().expect("Failed to get file info");
match info.type_ {
FileType::File => {
let mut file = fs::File::create(&path)?;
@ -92,6 +94,7 @@ fn unzip_dir(path: &Path, inode: Arc<INode>) -> Result<()> {
fs::create_dir(&path)?;
unzip_dir(path.as_path(), inode)?;
}
_ => panic!("unsupported file type"),
}
}
Ok(())

@ -276,9 +276,10 @@ impl vfs::INode for INodeImpl {
self._write_at(offset, buf)
}
/// the size returned here is logical size(entry num for directory), not the disk space used.
fn info(&self) -> vfs::Result<vfs::FileInfo> {
fn metadata(&self) -> vfs::Result<vfs::Metadata> {
let disk_inode = self.disk_inode.read();
Ok(vfs::FileInfo {
Ok(vfs::Metadata {
dev: 0,
inode: self.id,
size: match disk_inode.type_ {
FileType::File => disk_inode.size as usize,
@ -294,6 +295,7 @@ impl vfs::INode for INodeImpl {
nlinks: disk_inode.nlinks as usize,
uid: 0,
gid: 0,
blk_size: BLKSIZE,
})
}
fn sync(&self) -> vfs::Result<()> {
@ -311,7 +313,7 @@ impl vfs::INode for INodeImpl {
self._resize(len)
}
fn create(&self, name: &str, type_: vfs::FileType, _mode: u32) -> vfs::Result<Arc<vfs::INode>> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir);
}
@ -348,7 +350,7 @@ impl vfs::INode for INodeImpl {
Ok(inode)
}
fn unlink(&self, name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -383,7 +385,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn link(&self, name: &str, other: &Arc<INode>) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -397,7 +399,7 @@ impl vfs::INode for INodeImpl {
if !Arc::ptr_eq(&self.fs, &child.fs) {
return Err(FsError::NotSameFs);
}
if child.info()?.type_ == vfs::FileType::Dir {
if child.metadata()?.type_ == vfs::FileType::Dir {
return Err(FsError::IsDir);
}
let entry = DiskEntry {
@ -411,7 +413,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn rename(&self, old_name: &str, new_name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -441,7 +443,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn move_(&self, old_name: &str, target: &Arc<INode>, new_name: &str) -> vfs::Result<()> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -459,10 +461,10 @@ impl vfs::INode for INodeImpl {
if !Arc::ptr_eq(&self.fs, &dest.fs) {
return Err(FsError::NotSameFs);
}
if dest.info()?.type_ != vfs::FileType::Dir {
if dest.metadata()?.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
if dest.info()?.nlinks <= 0 {
if dest.metadata()?.nlinks <= 0 {
return Err(FsError::DirRemoved)
}
@ -483,7 +485,7 @@ impl vfs::INode for INodeImpl {
self.remove_dirent_page(entry_id)?;
if inode.info()?.type_ == vfs::FileType::Dir {
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
}
@ -491,7 +493,7 @@ impl vfs::INode for INodeImpl {
Ok(())
}
fn find(&self, name: &str) -> vfs::Result<Arc<vfs::INode>> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
@ -716,11 +718,18 @@ impl vfs::FileSystem for SimpleFileSystem {
self.get_inode(BLKN_ROOT)
}
fn info(&self) -> &'static vfs::FsInfo {
static INFO: vfs::FsInfo = vfs::FsInfo {
max_file_size: MAX_FILE_SIZE,
};
&INFO
fn info(&self) -> vfs::FsInfo {
let sb = self.super_block.read();
vfs::FsInfo {
bsize: BLKSIZE,
frsize: BLKSIZE,
blocks: sb.blocks as usize,
bfree: sb.unused_blocks as usize,
bavail: sb.unused_blocks as usize,
files: sb.blocks as usize, // inaccurate
ffree: sb.unused_blocks as usize, // inaccurate
namemax: MAX_FNAME_LEN,
}
}
}

@ -1,4 +1,4 @@
use crate::vfs::{INode, Result, FileInfo};
use crate::vfs::{INode, Result, Metadata};
use alloc::{sync::Arc, string::String};
pub struct File {
@ -27,8 +27,8 @@ impl File {
Ok(len)
}
pub fn info(&self) -> Result<FileInfo> {
self.inode.info()
pub fn info(&self) -> Result<Metadata> {
self.inode.metadata()
}
pub fn get_entry(&self, id: usize) -> Result<String> {

@ -38,7 +38,7 @@ fn create_file() -> Result<()> {
let root = sfs.root_inode();
let file1 = root.create("file1", FileType::File)?;
assert_eq!(file1.info()?, FileInfo {
assert_eq!(file1.info()?, Metadata {
inode: 5,
size: 0,
type_: FileType::File,

@ -6,7 +6,7 @@ use core::result;
pub trait INode: Any + Sync + Send {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize>;
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize>;
fn info(&self) -> Result<FileInfo>;
fn metadata(&self) -> Result<Metadata>;
fn sync(&self) -> Result<()>;
fn resize(&self, len: usize) -> Result<()>;
fn create(&self, name: &str, type_: FileType, mode: u32) -> Result<Arc<INode>>;
@ -33,7 +33,7 @@ impl INode {
self.as_any_ref().downcast_ref::<T>()
}
pub fn list(&self) -> Result<Vec<String>> {
let info = self.info()?;
let info = self.metadata()?;
if info.type_ != FileType::Dir {
return Err(FsError::NotDir);
}
@ -42,13 +42,13 @@ impl INode {
}).collect()
}
pub fn lookup(&self, path: &str) -> Result<Arc<INode>> {
if self.info()?.type_ != FileType::Dir {
if self.metadata()?.type_ != FileType::Dir {
return Err(FsError::NotDir);
}
let mut result = self.find(".")?;
let mut rest_path = path;
while rest_path != "" {
if result.info()?.type_!= FileType::Dir {
if result.metadata()?.type_!= FileType::Dir {
return Err(FsError::NotDir);
}
let name;
@ -71,8 +71,13 @@ impl INode {
}
}
/// Metadata of INode
///
/// Ref: [http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/stat.h.html]
#[derive(Debug, Eq, PartialEq)]
pub struct FileInfo {
pub struct Metadata {
/// Device ID
pub dev: usize,
/// Inode number
pub inode: usize,
/// Size in bytes
@ -80,6 +85,9 @@ pub struct FileInfo {
/// SFS Note: for normal file size is the actuate file size
/// for directory this is count of dirent.
pub size: usize,
/// A file system-specific preferred I/O block size for this object.
/// In some file system types, this may vary from file to file.
pub blk_size: usize,
/// Size in blocks
pub blocks: usize,
/// Time of last access
@ -97,9 +105,9 @@ pub struct FileInfo {
/// SFS Note: different from linux, "." and ".." count in nlinks
/// this is same as original ucore.
pub nlinks: usize,
/// User id
/// User ID
pub uid: usize,
/// Group id
/// Group ID
pub gid: usize,
}
@ -116,11 +124,31 @@ pub enum FileType {
SymLink,
CharDevice,
BlockDevice,
NamedPipe,
Socket,
}
/// Metadata of FileSystem
///
/// Ref: [http://pubs.opengroup.org/onlinepubs/9699919799/]
#[derive(Debug)]
pub struct FsInfo {
pub max_file_size: usize,
/// File system block size
pub bsize: usize,
/// Fundamental file system block size
pub frsize: usize,
/// Total number of blocks on file system in units of `frsize`
pub blocks: usize,
/// Total number of free blocks
pub bfree: usize,
/// Number of free blocks available to non-privileged process
pub bavail: usize,
/// Total number of file serial numbers
pub files: usize,
/// Total number of free file serial numbers
pub ffree: usize,
/// Maximum filename length
pub namemax: usize,
}
// Note: IOError/NoMemory always lead to a panic since it's hard to recover from it.
@ -148,5 +176,5 @@ pub type Result<T> = result::Result<T,FsError>;
pub trait FileSystem: Sync {
fn sync(&self) -> Result<()>;
fn root_inode(&self) -> Arc<INode>;
fn info(&self) -> &'static FsInfo;
fn info(&self) -> FsInfo;
}

Loading…
Cancel
Save