impl more INode operations

master
WangRunji 6 years ago
parent 1eb25f7422
commit 066cd14cce

@ -4,11 +4,11 @@ use std::fs::OpenOptions;
use std::path::PathBuf;
use std::sync::Arc;
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, Request};
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, Request};
use libc;
use log::*;
use structopt::StructOpt;
use time::Timespec;
use log::*;
use simple_filesystem::{sfs, vfs};
@ -49,6 +49,25 @@ impl<T: vfs::FileSystem> VfsWrapper<T> {
vfs::FileType::Dir => FileType::Directory,
}
}
fn trans_error(err: vfs::FsError) -> i32 {
use vfs::FsError::*;
use libc::*;
match err {
NotSupported => ENOSYS,
EntryNotFound => ENOENT,
EntryExist => EEXIST,
IsDir => EISDIR,
NotFile => EISDIR,
NotDir => ENOTDIR,
NotSameFs => EXDEV,
InvalidParam => EINVAL,
NoDeviceSpace => ENOSPC,
DirRemoved => ENOENT,
DirNotEmpty => ENOTEMPTY,
WrongFs => EINVAL,
_ => EINVAL,
}
}
fn get_inode(&self, ino: u64) -> vfs::Result<&Arc<vfs::INode>> {
self.inodes.get(&(ino as usize)).ok_or(vfs::FsError::EntryNotFound)
}
@ -58,11 +77,7 @@ macro_rules! try_vfs {
($reply:expr, $expr:expr) => (match $expr {
Ok(val) => val,
Err(err) => {
let error_code = match err {
vfs::FsError::EntryNotFound => libc::ENOENT,
_ => libc::EINVAL,
};
$reply.error(error_code);
$reply.error(Self::trans_error(err));
return;
}
});
@ -87,6 +102,66 @@ impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
reply.attr(&TTL, &attr);
}
fn mknod(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, _rdev: u32, reply: ReplyEntry) {
let name = name.to_str().unwrap();
info!("mknod parent={} name={} mode={}", parent, name, mode);
let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.create(name, vfs::FileType::File));
let info = try_vfs!(reply, target.info());
self.inodes.insert(info.inode, target);
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn mkdir(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, reply: ReplyEntry) {
let name = name.to_str().unwrap();
info!("mkdir parent={} name={} mode={}", parent, name, mode);
let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir));
let info = try_vfs!(reply, target.info());
let attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn unlink(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
let name = name.to_str().unwrap();
info!("unlink parent={} name={}", parent, name);
let parent = try_vfs!(reply, self.get_inode(parent));
try_vfs!(reply, parent.unlink(name));
reply.ok();
}
fn rmdir(&mut self, req: &Request, parent: u64, name: &OsStr, reply: ReplyEmpty) {
info!("rmdir -> unlink");
self.unlink(req, parent, name, reply);
}
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();
info!("rename parent={} name={} newparent={} newname={}", parent, name, newparent, newname);
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));
}
reply.ok();
}
fn link(&mut self, _req: &Request, ino: u64, newparent: u64, newname: &OsStr, reply: ReplyEntry) {
let newname = newname.to_str().unwrap();
info!("link ino={} newparent={} newname={}", ino, newparent, newname);
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 attr = Self::trans_attr(info);
reply.entry(&TTL, &attr, 0);
}
fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, size: u32, reply: ReplyData) {
info!("read ino={} offset={} size={}", ino, offset, size);
let inode = try_vfs!(reply, self.get_inode(ino));
@ -96,6 +171,27 @@ impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
reply.data(data.as_slice());
}
fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, data: &[u8], flags: u32, reply: ReplyWrite) {
info!("write ino={} offset={} size={} flags={}", ino, offset, data.len(), flags);
let inode = try_vfs!(reply, self.get_inode(ino));
let len = try_vfs!(reply, inode.write_at(offset as usize, data));
reply.written(len as u32);
}
fn flush(&mut self, _req: &Request, ino: u64, _fh: u64, _lock_owner: u64, reply: ReplyEmpty) {
info!("flush ino={}", ino);
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn fsync(&mut self, _req: &Request, ino: u64, _fh: u64, _datasync: bool, reply: ReplyEmpty) {
info!("fsync ino={}", ino);
let inode = try_vfs!(reply, self.get_inode(ino));
try_vfs!(reply, inode.sync());
reply.ok();
}
fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, mut reply: ReplyDirectory) {
info!("readdir ino={}, offset={}", ino, offset);
let inode = try_vfs!(reply, self.get_inode(ino));

Loading…
Cancel
Save