Fixes to fuse, allow filesystem offset
This commit is contained in:
@@ -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
@@ -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();
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
mkdir -p test
|
||||
|
||||
cargo run --bin redoxfs-fuse test.bin test &
|
||||
+47
-28
@@ -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, §or));
|
||||
try!(self.write_at(block, §or));
|
||||
|
||||
byte_offset = 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+2
-2
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user