From 4f035a05dbe027138bdc103c931e98461f071e25 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 23 Mar 2019 10:26:25 +0800 Subject: [PATCH] Implement symlink for sfs --- rcore-fs-fuse/src/zip.rs | 7 +++++++ rcore-fs-sfs/src/lib.rs | 15 ++++++++------- rcore-fs-sfs/src/structs.rs | 11 +++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/rcore-fs-fuse/src/zip.rs b/rcore-fs-fuse/src/zip.rs index 32376de..c1f2420 100644 --- a/rcore-fs-fuse/src/zip.rs +++ b/rcore-fs-fuse/src/zip.rs @@ -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) -> Result<(), Box> { } 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(()) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 240dd04..d405710 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -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 { - 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 { 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 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"), } diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index 5770f8b..2a96d21 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -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,