split sync to sync_all and sync_data. merge rename to move.

master
WangRunji 7 years ago
parent 0eba40886d
commit 38dab25178

@ -144,14 +144,9 @@ impl Filesystem for VfsFuse {
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));
}
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();
}
@ -181,13 +176,17 @@ impl Filesystem for VfsFuse {
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());
try_vfs!(reply, inode.sync_data());
reply.ok();
}
fn fsync(&mut self, _req: &Request, ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
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());
if datasync {
try_vfs!(reply, inode.sync_data());
} else {
try_vfs!(reply, inode.sync_all());
}
reply.ok();
}

@ -5,7 +5,7 @@ use std::path::Path;
use std::sync::Arc;
use std::error::Error;
use rcore_fs::vfs::{INode, FileType, FsError};
use rcore_fs::vfs::{INode, FileType};
const DEFAULT_MODE: u32 = 0o664;
const BUF_SIZE: usize = 0x1000;

@ -165,7 +165,7 @@ impl vfs::INode for INodeImpl {
blk_size: 0x1000,
})
}
fn sync(&self) -> vfs::Result<()> {
fn sync_all(&self) -> vfs::Result<()> {
let mut disk_inode = self.disk_inode.write();
if disk_inode.dirty() {
self.fs.meta_file.write_block(self.id, disk_inode.as_buf())?;
@ -173,6 +173,9 @@ impl vfs::INode for INodeImpl {
}
Ok(())
}
fn sync_data(&self) -> vfs::Result<()> {
self.sync_all()
}
fn resize(&self, len: usize) -> vfs::Result<()> {
if self.disk_inode.read().type_ != FileType::File {
return Err(FsError::NotFile);
@ -281,80 +284,60 @@ impl vfs::INode for INodeImpl {
child.nlinks_inc();
Ok(())
}
fn rename(&self, old_name: &str, new_name: &str) -> vfs::Result<()> {
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
}
if info.nlinks <= 0 {
return Err(FsError::DirRemoved)
}
if old_name == "." {
return Err(FsError::IsDir)
}
if old_name == ".." {
return Err(FsError::IsDir)
}
if !self.get_file_inode_id(new_name).is_none() {
return Err(FsError::EntryExist);
}
let (inode_id, entry_id) = self.get_file_inode_and_entry_id(old_name)
.ok_or(FsError::EntryNotFound)?;
// in place modify name
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
self.file.write_direntry(entry_id, &entry)?;
Ok(())
}
fn move_(&self, old_name: &str, target: &Arc<INode>, new_name: &str) -> vfs::Result<()> {
let info = self.metadata()?;
if info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
return Err(FsError::DirRemoved)
return Err(FsError::DirRemoved);
}
if old_name == "." {
return Err(FsError::IsDir)
return Err(FsError::IsDir);
}
if old_name == ".." {
return Err(FsError::IsDir)
return Err(FsError::IsDir);
}
let dest = target.downcast_ref::<INodeImpl>().ok_or(FsError::NotSameFs)?;
let dest_info = dest.metadata()?;
if !Arc::ptr_eq(&self.fs, &dest.fs) {
return Err(FsError::NotSameFs);
}
if dest.metadata()?.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
if dest_info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if dest.metadata()?.nlinks <= 0 {
return Err(FsError::DirRemoved)
if dest_info.nlinks <= 0 {
return Err(FsError::DirRemoved);
}
if !self.get_file_inode_id(new_name).is_none() {
if dest.get_file_inode_id(new_name).is_some() {
return Err(FsError::EntryExist);
}
let (inode_id, entry_id) = self.get_file_inode_and_entry_id(old_name).ok_or(FsError::EntryNotFound)?;
let inode = self.fs.get_inode(inode_id);
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
dest.dirent_append(&entry)?;
self.dirent_remove(entry_id)?;
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
let (inode_id, entry_id) = self.get_file_inode_and_entry_id(old_name)
.ok_or(FsError::EntryNotFound)?;
if info.inode == dest_info.inode {
// rename: in place modify name
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
self.file.write_direntry(entry_id, &entry)?;
} else {
// move
let inode = self.fs.get_inode(inode_id);
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
dest.dirent_append(&entry)?;
self.dirent_remove(entry_id)?;
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
}
}
Ok(())
@ -388,7 +371,7 @@ impl vfs::INode for INodeImpl {
impl Drop for INodeImpl {
/// Auto sync when drop
fn drop(&mut self) {
self.sync().expect("Failed to sync when dropping the SEFS Inode");
self.sync_all().expect("Failed to sync when dropping the SEFS Inode");
if self.disk_inode.read().nlinks <= 0 {
self.disk_inode.write().sync();
self.fs.free_block(self.id);
@ -472,7 +455,7 @@ impl SEFS {
root.dirent_init(BLKN_ROOT)?;
root.nlinks_inc(); //for .
root.nlinks_inc(); //for ..(root's parent is itself)
root.sync()?;
root.sync_all()?;
Ok(sefs)
}
@ -585,7 +568,7 @@ impl vfs::FileSystem for SEFS {
self.flush_weak_inodes();
for inode in self.inodes.read().values() {
if let Some(inode) = inode.upgrade() {
inode.sync()?;
inode.sync_all()?;
}
}
Ok(())

@ -305,7 +305,7 @@ impl vfs::INode for INodeImpl {
blk_size: BLKSIZE,
})
}
fn sync(&self) -> vfs::Result<()> {
fn sync_all(&self) -> vfs::Result<()> {
let mut disk_inode = self.disk_inode.write();
if disk_inode.dirty() {
self.fs.device.write_block(self.id, 0, disk_inode.as_buf())?;
@ -313,6 +313,9 @@ impl vfs::INode for INodeImpl {
}
Ok(())
}
fn sync_data(&self) -> vfs::Result<()> {
self.sync_all()
}
fn resize(&self, len: usize) -> vfs::Result<()> {
if self.disk_inode.read().type_!=FileType::File {
return Err(FsError::NotFile);
@ -419,82 +422,63 @@ impl vfs::INode for INodeImpl {
child.nlinks_inc();
Ok(())
}
fn rename(&self, old_name: &str, new_name: &str) -> vfs::Result<()> {
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
}
if info.nlinks <= 0 {
return Err(FsError::DirRemoved)
}
if old_name == "." {
return Err(FsError::IsDir)
}
if old_name == ".." {
return Err(FsError::IsDir)
}
if !self.get_file_inode_id(new_name).is_none() {
return Err(FsError::EntryExist);
}
let (_, entry_id) = self.get_file_inode_and_entry_id(old_name).ok_or(FsError::EntryNotFound)?;
// in place modify name
let mut entry: DiskEntry = unsafe { uninitialized() };
let entry_pos = entry_id as usize * BLKSIZE;
self._read_at(entry_pos, entry.as_buf_mut()).unwrap();
entry.name = Str256::from(new_name);
self._write_at(entry_pos, entry.as_buf()).unwrap();
Ok(())
}
fn move_(&self, old_name: &str, target: &Arc<INode>, new_name: &str) -> vfs::Result<()> {
let info = self.metadata()?;
if info.type_!=vfs::FileType::Dir {
return Err(FsError::NotDir)
return Err(FsError::NotDir);
}
if info.nlinks <= 0 {
return Err(FsError::DirRemoved)
return Err(FsError::DirRemoved);
}
if old_name == "." {
return Err(FsError::IsDir)
return Err(FsError::IsDir);
}
if old_name == ".." {
return Err(FsError::IsDir)
return Err(FsError::IsDir);
}
let dest = target.downcast_ref::<INodeImpl>().ok_or(FsError::NotSameFs)?;
let dest_info = dest.metadata()?;
if !Arc::ptr_eq(&self.fs, &dest.fs) {
return Err(FsError::NotSameFs);
}
if dest.metadata()?.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir)
if dest_info.type_ != vfs::FileType::Dir {
return Err(FsError::NotDir);
}
if dest.metadata()?.nlinks <= 0 {
return Err(FsError::DirRemoved)
if dest_info.nlinks <= 0 {
return Err(FsError::DirRemoved);
}
if !self.get_file_inode_id(new_name).is_none() {
if dest.get_file_inode_id(new_name).is_some() {
return Err(FsError::EntryExist);
}
let (inode_id, entry_id) = self.get_file_inode_and_entry_id(old_name).ok_or(FsError::EntryNotFound)?;
let inode = self.fs.get_inode(inode_id);
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
let old_size = dest._size();
dest._resize(old_size + BLKSIZE)?;
dest._write_at(old_size, entry.as_buf()).unwrap();
self.remove_dirent_page(entry_id)?;
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
let (inode_id, entry_id) = self.get_file_inode_and_entry_id(old_name)
.ok_or(FsError::EntryNotFound)?;
if info.inode == dest_info.inode {
// rename: in place modify name
let mut entry: DiskEntry = unsafe { uninitialized() };
let entry_pos = entry_id as usize * BLKSIZE;
self._read_at(entry_pos, entry.as_buf_mut()).unwrap();
entry.name = Str256::from(new_name);
self._write_at(entry_pos, entry.as_buf()).unwrap();
} else {
// move
let inode = self.fs.get_inode(inode_id);
let entry = DiskEntry {
id: inode_id as u32,
name: Str256::from(new_name),
};
let old_size = dest._size();
dest._resize(old_size + BLKSIZE)?;
dest._write_at(old_size, entry.as_buf()).unwrap();
self.remove_dirent_page(entry_id)?;
if inode.metadata()?.type_ == vfs::FileType::Dir {
self.nlinks_dec();
dest.nlinks_inc();
}
}
Ok(())
@ -529,7 +513,7 @@ impl vfs::INode for INodeImpl {
impl Drop for INodeImpl {
/// Auto sync when drop
fn drop(&mut self) {
self.sync().expect("Failed to sync when dropping the SimpleFileSystem Inode");
self.sync_all().expect("Failed to sync when dropping the SimpleFileSystem Inode");
if self.disk_inode.read().nlinks <= 0 {
self._resize(0).unwrap();
self.disk_inode.write().sync();
@ -608,7 +592,7 @@ impl SimpleFileSystem {
root.init_dir_entry(BLKN_ROOT).unwrap();
root.nlinks_inc(); //for .
root.nlinks_inc(); //for ..(root's parent is itself)
root.sync().unwrap();
root.sync_all().unwrap();
sfs
}
@ -715,7 +699,7 @@ impl vfs::FileSystem for SimpleFileSystem {
self.flush_weak_inodes();
for inode in self.inodes.read().values() {
if let Some(inode) = inode.upgrade() {
inode.sync()?;
inode.sync_all()?;
}
}
Ok(())

@ -8,14 +8,17 @@ 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 metadata(&self) -> Result<Metadata>;
fn sync(&self) -> Result<()>;
/// Sync all data and metadata
fn sync_all(&self) -> Result<()>;
/// Sync data (not include metadata)
fn sync_data(&self) -> Result<()>;
fn resize(&self, len: usize) -> Result<()>;
fn create(&self, name: &str, type_: FileType, mode: u32) -> Result<Arc<INode>>;
fn unlink(&self, name: &str) -> Result<()>;
/// user of the vfs api should call borrow_mut by itself
fn link(&self, name: &str, other: &Arc<INode>) -> Result<()>;
fn rename(&self, old_name: &str, new_name: &str) -> Result<()>;
// when self==target use rename instead since it's not possible to have two mut_ref at the same time.
/// Move INode `self/old_name` to `target/new_name`.
/// If `target` equals `self`, do rename.
fn move_(&self, old_name: &str, target: &Arc<INode>, new_name: &str) -> Result<()>;
/// lookup with only one layer
fn find(&self, name: &str) -> Result<Arc<INode>>;

Loading…
Cancel
Save