From 4b5dba67dfd1e85ab9cd45a5686026bf5f5d76c0 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Mon, 11 Feb 2019 19:14:04 +0800 Subject: [PATCH] fix FUSE write. fix SFS freemap by updating crate 'bitvec'. --- .travis.yml | 8 +++++++- rcore-fs-fuse/src/main.rs | 20 +++++++++++++++----- rcore-fs/Cargo.toml | 7 ++++++- rcore-fs/src/sfs.rs | 19 ++++++++++--------- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 800986e..5d5b40c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,12 @@ language: rust + rust: - nightly + +install: + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update && sudo apt-get install -y libfuse-dev; fi + - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update && brew tap caskroom/cask && brew cask install osxfuse; fi + script: - cargo build - - cargo test --verbose \ No newline at end of file + - cargo test --verbose diff --git a/rcore-fs-fuse/src/main.rs b/rcore-fs-fuse/src/main.rs index 4960979..94230e8 100644 --- a/rcore-fs-fuse/src/main.rs +++ b/rcore-fs-fuse/src/main.rs @@ -5,8 +5,7 @@ use std::path::PathBuf; use std::sync::Arc; use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, Request}; -use libc; -use log::*; +//use log::*; use structopt::StructOpt; use time::Timespec; @@ -79,6 +78,7 @@ impl VfsWrapper { } } +/// Helper macro to reply error when VFS operation fails macro_rules! try_vfs { ($reply:expr, $expr:expr) => (match $expr { Ok(val) => val, @@ -90,6 +90,11 @@ macro_rules! try_vfs { } impl Filesystem for VfsWrapper { + fn destroy(&mut self, _req: &Request) { + self.inodes.clear(); + self.fs.sync().unwrap(); + } + fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) { let inode = try_vfs!(reply, self.get_inode(parent)); let target = try_vfs!(reply, inode.lookup(name.to_str().unwrap())); @@ -106,7 +111,7 @@ impl Filesystem for VfsWrapper { reply.attr(&TTL, &attr); } - fn mknod(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, _rdev: u32, reply: ReplyEntry) { + fn mknod(&mut self, _req: &Request, parent: u64, name: &OsStr, _mode: u32, _rdev: u32, reply: ReplyEntry) { let name = name.to_str().unwrap(); let inode = try_vfs!(reply, self.get_inode(parent)); let target = try_vfs!(reply, inode.create(name, vfs::FileType::File)); @@ -116,7 +121,7 @@ impl Filesystem for VfsWrapper { reply.entry(&TTL, &attr, 0); } - fn mkdir(&mut self, _req: &Request, parent: u64, name: &OsStr, mode: u32, reply: ReplyEntry) { + fn mkdir(&mut self, _req: &Request, parent: u64, name: &OsStr, _mode: u32, reply: ReplyEntry) { let name = name.to_str().unwrap(); let inode = try_vfs!(reply, self.get_inode(parent)); let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir)); @@ -168,8 +173,13 @@ impl Filesystem for VfsWrapper { reply.data(data.as_slice()); } - fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, data: &[u8], flags: u32, reply: ReplyWrite) { + fn write(&mut self, _req: &Request, ino: u64, _fh: u64, offset: i64, data: &[u8], _flags: u32, reply: ReplyWrite) { let inode = try_vfs!(reply, self.get_inode(ino)); + let info = try_vfs!(reply, inode.info()); + let end = offset as usize + data.len(); + if end > info.size { + try_vfs!(reply, inode.resize(end)); + } let len = try_vfs!(reply, inode.write_at(offset as usize, data)); reply.written(len as u32); } diff --git a/rcore-fs/Cargo.toml b/rcore-fs/Cargo.toml index 484bef8..63b98a7 100644 --- a/rcore-fs/Cargo.toml +++ b/rcore-fs/Cargo.toml @@ -10,9 +10,14 @@ path = "src/bin/mksfs.rs" required-features = ["std"] [dependencies] -bit-vec = { default-features = false, git = "https://github.com/AltSysrq/bit-vec.git" } # default-features contains 'std' static_assertions = "0.3" spin = "0.4" +log = "0.4" + +[dependencies.bitvec] +version = "0.9" +default-features = false +features = ["alloc"] [dev-dependencies] tempfile = "3" diff --git a/rcore-fs/src/sfs.rs b/rcore-fs/src/sfs.rs index 35e67a8..15cedb7 100644 --- a/rcore-fs/src/sfs.rs +++ b/rcore-fs/src/sfs.rs @@ -2,9 +2,9 @@ use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::{Arc, Weak} use core::any::Any; use core::fmt::{Debug, Error, Formatter}; use core::mem::uninitialized; -use core::slice; -use bit_vec::BitVec; +use bitvec::BitVec; +use log::*; use spin::{Mutex, RwLock}; use crate::dirty::Dirty; @@ -547,7 +547,7 @@ impl SimpleFileSystem { Ok(SimpleFileSystem { super_block: RwLock::new(Dirty::new(super_block)), - free_map: RwLock::new(Dirty::new(BitVec::from_bytes(&free_map))), + free_map: RwLock::new(Dirty::new(BitVec::from(free_map.as_ref()))), inodes: RwLock::new(BTreeMap::new()), device: Mutex::new(device), self_ptr: Weak::default(), @@ -565,7 +565,8 @@ impl SimpleFileSystem { info: Str32::from(DEFAULT_INFO), }; let free_map = { - let mut bitset = BitVec::from_elem(BLKBITS, false); + let mut bitset = BitVec::with_capacity(BLKBITS); + bitset.extend(core::iter::repeat(false).take(BLKBITS)); for i in 3..blocks { bitset.set(i, true); } @@ -592,7 +593,7 @@ impl SimpleFileSystem { /// Wrap pure SimpleFileSystem with Arc /// Used in constructors fn wrap(self) -> Arc { - // Create a Arc, make a Weak from it, then put it into the struct. + // Create an Arc, make a Weak from it, then put it into the struct. // It's a little tricky. let fs = Arc::new(self); let weak = Arc::downgrade(&fs); @@ -612,6 +613,7 @@ impl SimpleFileSystem { return None } super_block.unused_blocks -= 1; // will not underflow + trace!("alloc block {:#x}", block_id); } id } @@ -621,6 +623,7 @@ impl SimpleFileSystem { assert!(!free_map[block_id]); free_map.set(block_id, true); self.super_block.write().unused_blocks += 1; + trace!("free block {:#x}", block_id); } /// Create a new INode struct, then insert it to self.inodes @@ -732,12 +735,10 @@ impl BitsetAlloc for BitVec { impl AsBuf for BitVec { fn as_buf(&self) -> &[u8] { - let slice = self.storage(); - unsafe { slice::from_raw_parts(slice as *const _ as *const u8, slice.len() * 4) } + self.as_ref() } fn as_buf_mut(&mut self) -> &mut [u8] { - let slice = self.storage(); - unsafe { slice::from_raw_parts_mut(slice as *const _ as *mut u8, slice.len() * 4) } + self.as_mut() } }