Fixes to fuse, allow filesystem offset

This commit is contained in:
Jeremy Soller
2016-04-13 15:23:52 -06:00
parent d13d926d7b
commit 94c36fa34d
7 changed files with 73 additions and 68 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#!/bin/bash
rm -f ../../filesystem/etc/redoxfs.bin
rm -f test.bin
cargo run --bin redoxfs-utility ../../filesystem/etc/redoxfs.bin << "EOF"
cargo run --bin redoxfs-utility test.bin << "EOF"
mk a_file
mkdir a_directory
+15 -35
View File
@@ -21,23 +21,12 @@ struct RedoxFS {
fs: redoxfs::FileSystem,
}
impl RedoxFS {
fn inode_block(&self, ino: u64) -> u64 {
self.fs.header.1.root + ino - 1
}
fn block_inode(&self, block: u64) -> u64 {
block + 1 - self.fs.header.1.root
}
}
impl Filesystem for RedoxFS {
fn lookup(&mut self, _req: &Request, ino: u64, name: &Path, reply: ReplyEntry) {
let parent_block = self.inode_block(ino);
fn lookup(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEntry) {
match self.fs.find_node(name.to_str().unwrap(), parent_block) {
Ok(node) => {
reply.entry(&TTL, &FileAttr {
ino: self.block_inode(node.0),
ino: node.0,
size: node.1.extents[0].length,
blocks: (node.1.extents[0].length + 511)/512,
atime: CREATE_TIME,
@@ -63,12 +52,11 @@ impl Filesystem for RedoxFS {
}
}
fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
let block = self.inode_block(ino);
fn getattr(&mut self, _req: &Request, block: u64, reply: ReplyAttr) {
match self.fs.node(block) {
Ok(node) => {
reply.attr(&TTL, &FileAttr {
ino: self.block_inode(node.0),
ino: node.0,
size: node.1.extents[0].length,
blocks: (node.1.extents[0].length + 511)/512,
atime: CREATE_TIME,
@@ -94,17 +82,16 @@ impl Filesystem for RedoxFS {
}
}
fn setattr(&mut self, _req: &Request, ino: u64, _mode: Option<u32>,
fn setattr(&mut self, _req: &Request, block: u64, _mode: Option<u32>,
_uid: Option<u32>, _gid: Option<u32>, _size: Option<u64>,
_atime: Option<Timespec>, _mtime: Option<Timespec>, _fh: Option<u64>,
_crtime: Option<Timespec>, _chgtime: Option<Timespec>, _bkuptime: Option<Timespec>,
_flags: Option<u32>, reply: ReplyAttr) {
//TODO: Implement truncate
let block = self.inode_block(ino);
match self.fs.node(block) {
Ok(node) => {
reply.attr(&TTL, &FileAttr {
ino: self.block_inode(node.0),
ino: node.0,
size: node.1.extents[0].length,
blocks: (node.1.extents[0].length + 511)/512,
atime: CREATE_TIME,
@@ -130,8 +117,7 @@ impl Filesystem for RedoxFS {
}
}
fn read(&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, size: u32, reply: ReplyData) {
let block = self.inode_block(ino);
fn read(&mut self, _req: &Request, block: u64, _fh: u64, offset: u64, size: u32, reply: ReplyData) {
let mut data = vec![0; size as usize];
match self.fs.read_node(block, offset, &mut data) {
Ok(count) => {
@@ -143,8 +129,7 @@ impl Filesystem for RedoxFS {
}
}
fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, data: &[u8], _flags: u32, reply: ReplyWrite) {
let block = self.inode_block(ino);
fn write(&mut self, _req: &Request, block: u64, _fh: u64, offset: u64, data: &[u8], _flags: u32, reply: ReplyWrite) {
match self.fs.write_node(block, offset, &data) {
Ok(count) => {
reply.written(count as u32);
@@ -163,8 +148,7 @@ impl Filesystem for RedoxFS {
reply.ok();
}
fn readdir(&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64, mut reply: ReplyDirectory) {
let parent_block = self.inode_block(ino);
fn readdir(&mut self, _req: &Request, parent_block: u64, _fh: u64, offset: u64, mut reply: ReplyDirectory) {
let mut children = Vec::new();
match self.fs.child_nodes(&mut children, parent_block) {
Ok(()) => {
@@ -191,12 +175,11 @@ impl Filesystem for RedoxFS {
}
}
fn create(&mut self, _req: &Request, ino: u64, name: &Path, _mode: u32, flags: u32, reply: ReplyCreate) {
let parent_block = self.inode_block(ino);
fn create(&mut self, _req: &Request, parent_block: u64, name: &Path, _mode: u32, flags: u32, reply: ReplyCreate) {
match self.fs.create_node(redoxfs::Node::MODE_FILE, name.to_str().unwrap(), parent_block) {
Ok(node) => {
reply.created(&TTL, &FileAttr {
ino: self.block_inode(node.0),
ino: node.0,
size: node.1.extents[0].length,
blocks: (node.1.extents[0].length + 511)/512,
atime: CREATE_TIME,
@@ -222,12 +205,11 @@ impl Filesystem for RedoxFS {
}
}
fn mkdir(&mut self, _req: &Request, ino: u64, name: &Path, _mode: u32, reply: ReplyEntry) {
let parent_block = self.inode_block(ino);
fn mkdir(&mut self, _req: &Request, parent_block: u64, name: &Path, _mode: u32, reply: ReplyEntry) {
match self.fs.create_node(redoxfs::Node::MODE_DIR, name.to_str().unwrap(), parent_block) {
Ok(node) => {
reply.entry(&TTL, &FileAttr {
ino: self.block_inode(node.0),
ino: node.0,
size: node.1.extents[0].length,
blocks: (node.1.extents[0].length + 511)/512,
atime: CREATE_TIME,
@@ -253,8 +235,7 @@ impl Filesystem for RedoxFS {
}
}
fn rmdir(&mut self, _req: &Request, ino: u64, name: &Path, reply: ReplyEmpty) {
let parent_block = self.inode_block(ino);
fn rmdir(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEmpty) {
match self.fs.remove_node(redoxfs::Node::MODE_DIR, name.to_str().unwrap(), parent_block) {
Ok(()) => {
reply.ok();
@@ -265,8 +246,7 @@ impl Filesystem for RedoxFS {
}
}
fn unlink(&mut self, _req: &Request, ino: u64, name: &Path, reply: ReplyEmpty) {
let parent_block = self.inode_block(ino);
fn unlink(&mut self, _req: &Request, parent_block: u64, name: &Path, reply: ReplyEmpty) {
match self.fs.remove_node(redoxfs::Node::MODE_FILE, name.to_str().unwrap(), parent_block) {
Ok(()) => {
reply.ok();
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
mkdir -p test
cargo run --bin redoxfs-fuse test.bin test &
+47 -28
View File
@@ -5,29 +5,39 @@ use super::{Disk, ExNode, Extent, Header, Node};
/// A file system
pub struct FileSystem {
pub disk: Box<Disk>,
pub block: u64,
pub header: (u64, Header)
}
impl FileSystem {
/// Open a file system on a disk
pub fn open(mut disk: Box<Disk>) -> Result<Self> {
let mut header = (1, Header::default());
try!(disk.read_at(header.0, &mut header.1));
for block in 0..4096 {
let mut header = (0, Header::default());
try!(disk.read_at(block + header.0, &mut header.1));
if header.1.valid() {
let mut root = (header.1.root, Node::default());
try!(disk.read_at(root.0, &mut root.1));
if header.1.valid() {
println!("{:?}", header);
let mut free = (header.1.free, Node::default());
try!(disk.read_at(free.0, &mut free.1));
let mut root = (header.1.root, Node::default());
try!(disk.read_at(block + root.0, &mut root.1));
Ok(FileSystem {
disk: disk,
header: header
})
}else{
Err(Error::new(ENOENT))
println!("{:?}", root);
let mut free = (header.1.free, Node::default());
try!(disk.read_at(block + free.0, &mut free.1));
println!("{:?}", free);
return Ok(FileSystem {
disk: disk,
block: block,
header: header
});
}
}
Err(Error::new(ENOENT))
}
/// Create a file system on a disk
@@ -35,18 +45,19 @@ impl FileSystem {
let size = try!(disk.size());
if size >= 4 * 512 {
let mut free = (3, Node::new(Node::MODE_FILE, "free", 0));
let mut free = (2, Node::new(Node::MODE_FILE, "free", 0));
free.1.extents[0] = Extent::new(4, size - 4 * 512);
try!(disk.write_at(free.0, &free.1));
let root = (2, Node::new(Node::MODE_DIR, "root", 0));
let root = (1, Node::new(Node::MODE_DIR, "root", 0));
try!(disk.write_at(root.0, &root.1));
let header = (1, Header::new(size, root.0, free.0));
let header = (0, Header::new(size, root.0, free.0));
try!(disk.write_at(header.0, &header.1));
Ok(FileSystem {
disk: disk,
block: 0,
header: header
})
} else {
@@ -54,6 +65,14 @@ impl FileSystem {
}
}
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
self.disk.read_at(self.block + block, buffer)
}
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
self.disk.write_at(self.block + block, buffer)
}
pub fn allocate(&mut self, length: u64) -> Result<u64> {
//TODO: traverse next pointer
let free_block = self.header.1.free;
@@ -68,7 +87,7 @@ impl FileSystem {
}
}
if let Some(block) = block_option {
try!(self.disk.write_at(free.0, &free.1));
try!(self.write_at(free.0, &free.1));
Ok(block)
} else {
Err(Error::new(ENOSPC))
@@ -82,13 +101,13 @@ impl FileSystem {
pub fn node(&mut self, block: u64) -> Result<(u64, Node)> {
let mut node = Node::default();
try!(self.disk.read_at(block, &mut node));
try!(self.read_at(block, &mut node));
Ok((block, node))
}
pub fn ex_node(&mut self, block: u64) -> Result<(u64, ExNode)> {
let mut node = ExNode::default();
try!(self.disk.read_at(block, &mut node));
try!(self.read_at(block, &mut node));
Ok((block, node))
}
@@ -141,7 +160,7 @@ impl FileSystem {
let mut block = self.header.1.root;
nodes.push(try!(self.node(block)));
for part in path.split(':') {
for part in path.split('/') {
if ! part.is_empty() {
let node = try!(self.find_node(part, block));
block = node.0;
@@ -181,13 +200,13 @@ impl FileSystem {
}
if inserted {
try!(self.disk.write_at(parent.0, &parent.1));
try!(self.write_at(parent.0, &parent.1));
Ok(())
} else {
if parent.1.next == 0 {
parent.1.next = try!(self.allocate(1));
try!(self.disk.write_at(parent.0, &parent.1));
try!(self.disk.write_at(parent.1.next, &Node::default()));
try!(self.write_at(parent.0, &parent.1));
try!(self.write_at(parent.1.next, &Node::default()));
}
self.insert_blocks(block, length, parent.1.next)
@@ -199,7 +218,7 @@ impl FileSystem {
Err(Error::new(EEXIST))
} else {
let node = (try!(self.allocate(1)), Node::new(mode, name, parent_block));
try!(self.disk.write_at(node.0, &node.1));
try!(self.write_at(node.0, &node.1));
try!(self.insert_blocks(node.0, 512, parent_block));
@@ -240,7 +259,7 @@ impl FileSystem {
}
if removed {
try!(self.disk.write_at(parent.0, &parent.1));
try!(self.write_at(parent.0, &parent.1));
if let Some(replace) = replace_option {
try!(self.insert_blocks(replace.block, replace.length, parent_block));
@@ -266,7 +285,7 @@ impl FileSystem {
}
try!(self.remove_blocks(node.0, 1, parent_block));
try!(self.disk.write_at(node.0, &Node::default()));
try!(self.write_at(node.0, &Node::default()));
Ok(())
} else if node.1.is_dir() {
@@ -357,7 +376,7 @@ impl FileSystem {
for extent in extents.iter() {
for (block, size) in extent.blocks() {
let mut sector = [0; 512];
try!(self.disk.read_at(block, &mut sector));
try!(self.read_at(block, &mut sector));
for (s_b, mut b) in sector[byte_offset..size].iter().zip(buf[i..].iter_mut()) {
*b = *s_b;
@@ -390,7 +409,7 @@ impl FileSystem {
i += 1;
}
try!(self.disk.write_at(block, &sector));
try!(self.write_at(block, &sector));
byte_offset = 0;
}
+1 -1
View File
@@ -22,7 +22,7 @@ pub struct Header {
impl Header {
pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0";
pub const VERSION: u64 = 0xFFFFFFFFFFFFFFFF;
pub const VERSION: u64 = 1;
pub fn default() -> Header {
Header {
Executable
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
fusermount -u test
+2 -2
View File
@@ -219,8 +219,8 @@ fn main() {
Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
}
}else{
//Create a 4 MB disk image
let size = 4 * 1024 * 1024;
//Create a 128 MB disk image
let size = 128 * 1024 * 1024;
match Image::create(&path, size) {
Ok(disk) => match FileSystem::create(Box::new(disk)) {
Ok(filesystem) => {