diff --git a/fuse/main.rs b/fuse/main.rs index d557918276bdc608da607e939b2a85723ba41084..fb44f35a355eee8a613e2da88bfef76f8571a1d0 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<u32>, - _uid: Option<u32>, _gid: Option<u32>, _size: Option<u64>, + _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 + /*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 52e907ec3787d67fadb4934eb5ff6162b282ef6d..7c8b3c06baeef6c001607097163ed055f757395d 100644 --- a/scheme/resource.rs +++ b/scheme/resource.rs @@ -18,7 +18,7 @@ pub trait Resource { fn sync(&mut self) -> Result<usize>; - fn truncate(&mut self, len: usize) -> Result<usize>; + fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize>; } pub struct DirResource { @@ -82,7 +82,7 @@ impl Resource for DirResource { Err(Error::new(EINVAL)) } - fn truncate(&mut self, _len: usize) -> Result<usize> { + fn truncate(&mut self, _len: usize, _fs: &mut FileSystem) -> Result<usize> { Err(Error::new(EINVAL)) } } @@ -152,7 +152,7 @@ impl Resource for FileResource { Ok(0) } - fn truncate(&mut self, len: usize) -> Result<usize> { - Ok(0) + fn truncate(&mut self, len: usize, fs: &mut FileSystem) -> Result<usize> { + fs.node_set_len(self.block, len as u64).and(Ok(0)) } } diff --git a/scheme/scheme.rs b/scheme/scheme.rs index 8af7985692393614affb5de82ae82142a2787b54..d90351588a4d89fffe48237704145e84677914b3 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<usize> { // 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 4252eebaa4170459db6b7215ade080395470a4a9..f9191dc1775febb9dd607a57154e9a8bc724e7dd 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<Extent>) -> Result<()> { if block == 0 { return Ok(());