Implement symlink for sfs

master
Jiajie Chen 6 years ago
parent 38dab25178
commit 4f035a05db

@ -4,6 +4,7 @@ use std::mem::uninitialized;
use std::path::Path;
use std::sync::Arc;
use std::error::Error;
use std::os::unix::ffi::OsStrExt;
use rcore_fs::vfs::{INode, FileType};
@ -32,6 +33,12 @@ pub fn zip_dir(path: &Path, inode: Arc<INode>) -> Result<(), Box<Error>> {
} else if type_.is_dir() {
let inode = inode.create(name, FileType::Dir, DEFAULT_MODE)?;
zip_dir(entry.path().as_path(), inode)?;
} else if type_.is_symlink() {
let target = fs::read_link(entry.path())?;
let inode = inode.create(name, FileType::SymLink, DEFAULT_MODE)?;
let data = target.as_os_str().as_bytes();
inode.resize(data.len())?;
inode.write_at(0, data)?;
}
}
Ok(())

@ -199,7 +199,7 @@ impl INodeImpl {
let disk_inode = self.disk_inode.read();
match disk_inode.type_ {
FileType::Dir => disk_inode.blocks as usize * BLKSIZE,
FileType::File => disk_inode.size as usize,
FileType::File | FileType::Link => disk_inode.size as usize,
_ => panic!("Unknown file type"),
}
}
@ -209,7 +209,7 @@ impl INodeImpl {
let mut disk_inode = self.disk_inode.write();
disk_inode.size = match disk_inode.type_ {
FileType::Dir => disk_inode.blocks as usize * DIRENT_SIZE,
FileType::File => len,
FileType::File | FileType::Link => len,
_ => panic!("Unknown file type"),
} as u32
}
@ -265,14 +265,14 @@ impl INodeImpl {
impl vfs::INode for INodeImpl {
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
if self.disk_inode.read().type_!=FileType::File {
if self.disk_inode.read().type_ != FileType::File && self.disk_inode.read().type_ != FileType::Link {
return Err(FsError::NotFile);
}
self._read_at(offset, buf)
}
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
let DiskINode { type_, size, .. } = **self.disk_inode.read();
if type_ != FileType::File {
if type_ != FileType::File && type_ != FileType::Link {
return Err(FsError::NotFile);
}
// resize if not large enough
@ -289,7 +289,7 @@ impl vfs::INode for INodeImpl {
dev: 0,
inode: self.id,
size: match disk_inode.type_ {
FileType::File => disk_inode.size as usize,
FileType::File | FileType::Link => disk_inode.size as usize,
FileType::Dir => disk_inode.blocks as usize,
_ => panic!("Unknown file type"),
},
@ -317,7 +317,7 @@ impl vfs::INode for INodeImpl {
self.sync_all()
}
fn resize(&self, len: usize) -> vfs::Result<()> {
if self.disk_inode.read().type_!=FileType::File {
if self.disk_inode.read().type_ != FileType::File && self.disk_inode.read().type_ != FileType::Link {
return Err(FsError::NotFile);
}
self._resize(len)
@ -338,7 +338,7 @@ impl vfs::INode for INodeImpl {
// Create new INode
let inode = match type_ {
vfs::FileType::File => self.fs.new_inode_file()?,
vfs::FileType::File | vfs::FileType::SymLink => self.fs.new_inode_file()?,
vfs::FileType::Dir => self.fs.new_inode_dir(self.id)?,
_ => return Err(vfs::FsError::InvalidParam),
};
@ -761,6 +761,7 @@ impl From<FileType> for vfs::FileType {
fn from(t: FileType) -> Self {
match t {
FileType::File => vfs::FileType::File,
FileType::Link => vfs::FileType::SymLink,
FileType::Dir => vfs::FileType::Dir,
_ => panic!("unknown file type"),
}

@ -123,6 +123,17 @@ impl DiskINode {
db_indirect: 0,
}
}
pub const fn new_symlink() -> Self {
DiskINode {
size: 0,
type_: FileType::File,
nlinks: 0,
blocks: 0,
direct: [0; NDIRECT],
indirect: 0,
db_indirect: 0,
}
}
pub const fn new_dir() -> Self {
DiskINode {
size: 0,

Loading…
Cancel
Save