|
|
@ -42,7 +42,8 @@ mod ucore {
|
|
|
|
pub fn kmalloc(size: usize) -> *mut u8;
|
|
|
|
pub fn kmalloc(size: usize) -> *mut u8;
|
|
|
|
pub fn kfree(ptr: *mut u8);
|
|
|
|
pub fn kfree(ptr: *mut u8);
|
|
|
|
pub fn inode_kill(inode: &mut INode);
|
|
|
|
pub fn inode_kill(inode: &mut INode);
|
|
|
|
pub fn create_inode_for_sfs(ops: &INodeOps, fs: &mut Fs) -> *mut INode;
|
|
|
|
pub fn inode_get_fs(inode: *mut INode) -> *mut Fs;
|
|
|
|
|
|
|
|
pub fn create_inode_for_sfs(ops: &INodeOps, fs: *mut Fs) -> *mut INode;
|
|
|
|
pub fn create_fs_for_sfs(ops: &FsOps) -> *mut Fs;
|
|
|
|
pub fn create_fs_for_sfs(ops: &FsOps) -> *mut Fs;
|
|
|
|
pub fn __panic(file: *const u8, line: i32, fmt: *const u8, ...);
|
|
|
|
pub fn __panic(file: *const u8, line: i32, fmt: *const u8, ...);
|
|
|
|
pub fn cprintf(fmt: *const u8, ...);
|
|
|
|
pub fn cprintf(fmt: *const u8, ...);
|
|
|
@ -67,6 +68,14 @@ mod macros {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mod libc {
|
|
|
|
|
|
|
|
pub unsafe fn from_cstr(s: *const u8) -> &'static str {
|
|
|
|
|
|
|
|
use core::{str, slice};
|
|
|
|
|
|
|
|
let len = (0usize..).find(|&i| *s.offset(i as isize) == 0).unwrap();
|
|
|
|
|
|
|
|
str::from_utf8(slice::from_raw_parts(s, len)).unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Exports for ucore
|
|
|
|
// Exports for ucore
|
|
|
|
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
#[no_mangle]
|
|
|
@ -179,17 +188,17 @@ struct Stat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// mask for type of file
|
|
|
|
/// mask for type of file
|
|
|
|
const S_IFMT: u32 = 070000;
|
|
|
|
const S_IFMT: u32 = 0o70000;
|
|
|
|
/// ordinary regular file
|
|
|
|
/// ordinary regular file
|
|
|
|
const S_IFREG: u32 = 010000;
|
|
|
|
const S_IFREG: u32 = 0o10000;
|
|
|
|
/// directory
|
|
|
|
/// directory
|
|
|
|
const S_IFDIR: u32 = 020000;
|
|
|
|
const S_IFDIR: u32 = 0o20000;
|
|
|
|
/// symbolic link
|
|
|
|
/// symbolic link
|
|
|
|
const S_IFLNK: u32 = 030000;
|
|
|
|
const S_IFLNK: u32 = 0o30000;
|
|
|
|
/// character device
|
|
|
|
/// character device
|
|
|
|
const S_IFCHR: u32 = 040000;
|
|
|
|
const S_IFCHR: u32 = 0o40000;
|
|
|
|
/// block device
|
|
|
|
/// block device
|
|
|
|
const S_IFBLK: u32 = 050000;
|
|
|
|
const S_IFBLK: u32 = 0o50000;
|
|
|
|
|
|
|
|
|
|
|
|
/// Abstract operations on a inode.
|
|
|
|
/// Abstract operations on a inode.
|
|
|
|
///
|
|
|
|
///
|
|
|
@ -210,9 +219,9 @@ pub struct INodeOps {
|
|
|
|
gettype: extern fn(&mut INode, type_store: &mut u32) -> ErrorCode,
|
|
|
|
gettype: extern fn(&mut INode, type_store: &mut u32) -> ErrorCode,
|
|
|
|
tryseek: extern fn(&mut INode, pos: i32) -> ErrorCode,
|
|
|
|
tryseek: extern fn(&mut INode, pos: i32) -> ErrorCode,
|
|
|
|
truncate: extern fn(&mut INode, len: i32) -> ErrorCode,
|
|
|
|
truncate: extern fn(&mut INode, len: i32) -> ErrorCode,
|
|
|
|
create: extern fn(&mut INode, name: *const u8, excl: bool, inode_store: &mut &mut INode) -> ErrorCode,
|
|
|
|
create: extern fn(&mut INode, name: *const u8, excl: bool, inode_store: &mut *mut INode) -> ErrorCode,
|
|
|
|
lookup: extern fn(&mut INode, path: &mut u8, inode_store: &mut &mut INode) -> ErrorCode,
|
|
|
|
lookup: extern fn(&mut INode, path: *mut u8, inode_store: &mut *mut INode) -> ErrorCode,
|
|
|
|
ioctl: extern fn(&mut INode, op: i32, data: &mut u8) -> ErrorCode,
|
|
|
|
ioctl: extern fn(&mut INode, op: i32, data: *mut u8) -> ErrorCode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[repr(i32)]
|
|
|
|
#[repr(i32)]
|
|
|
@ -259,7 +268,7 @@ pub enum ErrorCode {
|
|
|
|
/// Cross Device-Link
|
|
|
|
/// Cross Device-Link
|
|
|
|
XDEV = -19,
|
|
|
|
XDEV = -19,
|
|
|
|
/// Unimplemented Feature
|
|
|
|
/// Unimplemented Feature
|
|
|
|
UNIMP = -20,
|
|
|
|
Unimplemented = -20,
|
|
|
|
/// Illegal Seek
|
|
|
|
/// Illegal Seek
|
|
|
|
SEEK = -21,
|
|
|
|
SEEK = -21,
|
|
|
|
/// Too Many Files are Open
|
|
|
|
/// Too Many Files are Open
|
|
|
@ -356,7 +365,7 @@ impl Device {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl INode {
|
|
|
|
impl INode {
|
|
|
|
fn get_or_create(vfs_inode: vfs::INodePtr, fs: &mut Fs) -> *mut Self {
|
|
|
|
fn get_or_create(vfs_inode: vfs::INodePtr, fs: *mut Fs) -> *mut Self {
|
|
|
|
static mut MAPPER: *mut BTreeMap<usize, *mut INode> = ptr::null_mut();
|
|
|
|
static mut MAPPER: *mut BTreeMap<usize, *mut INode> = ptr::null_mut();
|
|
|
|
|
|
|
|
|
|
|
|
unsafe {if MAPPER.is_null() {
|
|
|
|
unsafe {if MAPPER.is_null() {
|
|
|
@ -404,10 +413,12 @@ static INODE_OPS: INodeOps = {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern fn open(inode: &mut INode, flags: u32) -> ErrorCode {
|
|
|
|
extern fn open(inode: &mut INode, flags: u32) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
println!("inode.open");
|
|
|
|
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn close(inode: &mut INode) -> ErrorCode {
|
|
|
|
extern fn close(inode: &mut INode) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
println!("inode.close");
|
|
|
|
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn read(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
|
|
|
|
extern fn read(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
|
|
|
|
println!("inode.read");
|
|
|
|
println!("inode.read");
|
|
|
@ -422,11 +433,13 @@ static INODE_OPS: INodeOps = {
|
|
|
|
ErrorCode::Ok
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn fstat(inode: &mut INode, stat: &mut Stat) -> ErrorCode {
|
|
|
|
extern fn fstat(inode: &mut INode, stat: &mut Stat) -> ErrorCode {
|
|
|
|
|
|
|
|
println!("inode.fstst {:?}", inode.borrow());
|
|
|
|
let info = inode.borrow().info().unwrap();
|
|
|
|
let info = inode.borrow().info().unwrap();
|
|
|
|
*stat = Stat::from(info);
|
|
|
|
*stat = Stat::from(info);
|
|
|
|
ErrorCode::Ok
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn fsync(inode: &mut INode) -> ErrorCode {
|
|
|
|
extern fn fsync(inode: &mut INode) -> ErrorCode {
|
|
|
|
|
|
|
|
println!("inode.fsync {:?}", inode.borrow());
|
|
|
|
inode.borrow_mut().sync().unwrap();
|
|
|
|
inode.borrow_mut().sync().unwrap();
|
|
|
|
ErrorCode::Ok
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -435,7 +448,7 @@ static INODE_OPS: INodeOps = {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn getdirentry(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
|
|
|
|
extern fn getdirentry(inode: &mut INode, buf: &mut IoBuf) -> ErrorCode {
|
|
|
|
const ENTRY_SIZE: usize = 256;
|
|
|
|
const ENTRY_SIZE: usize = 256;
|
|
|
|
println!("{:#x?}", buf);
|
|
|
|
println!("inode.getdirentry {:#x?}", buf);
|
|
|
|
if inode.borrow().info().unwrap().type_ != vfs::FileType::Dir {
|
|
|
|
if inode.borrow().info().unwrap().type_ != vfs::FileType::Dir {
|
|
|
|
return ErrorCode::NotDir;
|
|
|
|
return ErrorCode::NotDir;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -444,7 +457,6 @@ static INODE_OPS: INodeOps = {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let id = buf.offset as usize / ENTRY_SIZE;
|
|
|
|
let id = buf.offset as usize / ENTRY_SIZE;
|
|
|
|
let names = inode.borrow().list().unwrap();
|
|
|
|
let names = inode.borrow().list().unwrap();
|
|
|
|
println!("offset = {}", buf.offset);
|
|
|
|
|
|
|
|
if id >= names.len() {
|
|
|
|
if id >= names.len() {
|
|
|
|
return ErrorCode::NoEntry;
|
|
|
|
return ErrorCode::NoEntry;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -456,23 +468,43 @@ static INODE_OPS: INodeOps = {
|
|
|
|
ErrorCode::Ok
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn gettype(inode: &mut INode, type_store: &mut u32) -> ErrorCode {
|
|
|
|
extern fn gettype(inode: &mut INode, type_store: &mut u32) -> ErrorCode {
|
|
|
|
|
|
|
|
println!("inode.gettype: {:?}", inode.borrow());
|
|
|
|
let info = inode.borrow().info().unwrap();
|
|
|
|
let info = inode.borrow().info().unwrap();
|
|
|
|
*type_store = info.type_ as u32;
|
|
|
|
// Inconsistent docs in ucore !
|
|
|
|
|
|
|
|
*type_store = match info.type_ {
|
|
|
|
|
|
|
|
vfs::FileType::File => S_IFREG,
|
|
|
|
|
|
|
|
vfs::FileType::Dir => S_IFDIR,
|
|
|
|
|
|
|
|
};
|
|
|
|
ErrorCode::Ok
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn tryseek(inode: &mut INode, pos: i32) -> ErrorCode {
|
|
|
|
extern fn tryseek(inode: &mut INode, pos: i32) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
println!("inode.tryseek({:?}) at {:?}", pos, inode.borrow());
|
|
|
|
|
|
|
|
let fs = inode.borrow().fs().upgrade().unwrap();
|
|
|
|
|
|
|
|
if pos < 0 || pos as usize >= fs.info().max_file_size {
|
|
|
|
|
|
|
|
return ErrorCode::Invalid;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let pos = pos as usize;
|
|
|
|
|
|
|
|
let info = inode.borrow().info().unwrap();
|
|
|
|
|
|
|
|
if pos > info.size {
|
|
|
|
|
|
|
|
inode.borrow_mut().resize(pos);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return ErrorCode::Ok;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn truncate(inode: &mut INode, len: i32) -> ErrorCode {
|
|
|
|
extern fn truncate(inode: &mut INode, len: i32) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn create(inode: &mut INode, name: *const u8, excl: bool, inode_store: &mut &mut INode) -> ErrorCode {
|
|
|
|
extern fn create(inode: &mut INode, name: *const u8, excl: bool, inode_store: &mut *mut INode) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn lookup(inode: &mut INode, path: &mut u8, inode_store: &mut &mut INode) -> ErrorCode {
|
|
|
|
extern fn lookup(inode: &mut INode, path: *mut u8, inode_store: &mut *mut INode) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
let path = unsafe{ libc::from_cstr(path) };
|
|
|
|
|
|
|
|
println!("inode.lookup({:?}) at {:?}", path, inode.borrow());
|
|
|
|
|
|
|
|
let target = inode.borrow().lookup(path).unwrap();
|
|
|
|
|
|
|
|
let fs = unsafe{ ucore::inode_get_fs(inode) };
|
|
|
|
|
|
|
|
*inode_store = INode::get_or_create(target, fs);
|
|
|
|
|
|
|
|
ErrorCode::Ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
extern fn ioctl(inode: &mut INode, op: i32, data: &mut u8) -> ErrorCode {
|
|
|
|
extern fn ioctl(inode: &mut INode, op: i32, data: *mut u8) -> ErrorCode {
|
|
|
|
unimplemented!();
|
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
INodeOps {
|
|
|
|
INodeOps {
|
|
|
@ -515,7 +547,7 @@ pub struct UcoreAllocator;
|
|
|
|
|
|
|
|
|
|
|
|
unsafe impl<'a> Alloc for &'a UcoreAllocator {
|
|
|
|
unsafe impl<'a> Alloc for &'a UcoreAllocator {
|
|
|
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
|
|
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
|
|
|
cprintf!("alloc %d\n", layout.size());
|
|
|
|
// cprintf!("alloc %d\n", layout.size());
|
|
|
|
const NULL: *mut u8 = 0 as *mut u8;
|
|
|
|
const NULL: *mut u8 = 0 as *mut u8;
|
|
|
|
match ucore::kmalloc(layout.size()) {
|
|
|
|
match ucore::kmalloc(layout.size()) {
|
|
|
|
NULL => Err(AllocErr::Exhausted { request: layout }),
|
|
|
|
NULL => Err(AllocErr::Exhausted { request: layout }),
|
|
|
@ -523,7 +555,7 @@ unsafe impl<'a> Alloc for &'a UcoreAllocator {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
|
|
|
|
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
|
|
|
|
cprintf!("free %d\n", layout.size());
|
|
|
|
// cprintf!("free %d\n", layout.size());
|
|
|
|
ucore::kfree(ptr);
|
|
|
|
ucore::kfree(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|