From 7d48fcf38292ab80a59e26fd1b2d0bb0df0afcf5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 16 Apr 2016 13:33:21 -0600 Subject: [PATCH] WIP: Add truncate --- fuse/main.rs | 6 ++++-- scheme/resource.rs | 8 ++++---- scheme/scheme.rs | 2 +- src/filesystem.rs | 30 ++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/fuse/main.rs b/fuse/main.rs index d557918276..fb44f35a35 100644 --- a/fuse/main.rs +++ b/fuse/main.rs @@ -83,11 +83,13 @@ impl Filesystem for RedoxFS { } fn setattr(&mut self, _req: &Request, block: u64, _mode: Option, - _uid: Option, _gid: Option, _size: Option, + _uid: Option, _gid: Option, size: Option, _atime: Option, _mtime: Option, _fh: Option, _crtime: Option, _chgtime: Option, _bkuptime: Option, _flags: Option, reply: ReplyAttr) { - //TODO: Implement truncate + /*if let Some(truncate_size) = size { + try!(self.fs.node_set_len(truncate_size)); + }*/ match self.fs.node(block) { Ok(node) => { reply.attr(&TTL, &FileAttr { diff --git a/scheme/resource.rs b/scheme/resource.rs index 52e907ec37..7c8b3c06ba 100644 --- a/scheme/resource.rs +++ b/scheme/resource.rs @@ -18,7 +18,7 @@ pub trait Resource { fn sync(&mut self) -> Result; - fn truncate(&mut self, len: usize) -> Result; + fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result; } pub struct DirResource { @@ -82,7 +82,7 @@ impl Resource for DirResource { Err(Error::new(EINVAL)) } - fn truncate(&mut self, _len: usize) -> Result { + fn truncate(&mut self, _len: usize, _fs: &mut FileSystem) -> Result { Err(Error::new(EINVAL)) } } @@ -152,7 +152,7 @@ impl Resource for FileResource { Ok(0) } - fn truncate(&mut self, len: usize) -> Result { - Ok(0) + fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result { + fs.node_set_len(self.block, len as u64).and(Ok(0)) } } diff --git a/scheme/scheme.rs b/scheme/scheme.rs index 8af7985692..d90351588a 100644 --- a/scheme/scheme.rs +++ b/scheme/scheme.rs @@ -230,7 +230,7 @@ impl Scheme for FileScheme { fn ftruncate(&mut self, id: usize, len: usize) -> Result { // println!("Ftruncate {}, {}", id, len); if let Some(mut file) = self.files.get_mut(&id) { - file.truncate(len) + file.truncate(len, &mut self.fs) } else { Err(Error::new(EBADF)) } diff --git a/src/filesystem.rs b/src/filesystem.rs index 4252eebaa4..f9191dc177 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -323,6 +323,36 @@ impl FileSystem { } } + pub fn node_set_len(&mut self, block: u64, mut length: u64) -> Result<()> { + if block == 0 { + return Err(Error::new(ENOENT)); + } + + let mut changed = false; + + let mut node = try!(self.node(block)); + for mut extent in node.1.extents.iter_mut() { + if extent.length > length { + //TODO: try!(self.deallocate(block, 512)); + extent.length = length; + changed = true; + length = 0; + } else { + length -= extent.length; + } + } + + if changed { + try!(self.write_at(node.0, &node.1)); + } + + if node.1.next > 0 { + self.node_set_len(node.1.next, length) + } else { + Ok(()) + } + } + fn node_extents(&mut self, block: u64, mut offset: u64, mut len: usize, extents: &mut Vec) -> Result<()> { if block == 0 { return Ok(());