fix FUSE write. fix SFS freemap by updating crate 'bitvec'.

master
WangRunji 6 years ago
parent ea7dfa79b8
commit 4b5dba67df

@ -1,6 +1,12 @@
language: rust language: rust
rust: rust:
- nightly - 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: script:
- cargo build - cargo build
- cargo test --verbose - cargo test --verbose

@ -5,8 +5,7 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, Request}; use fuse::{FileAttr, Filesystem, FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyWrite, Request};
use libc; //use log::*;
use log::*;
use structopt::StructOpt; use structopt::StructOpt;
use time::Timespec; use time::Timespec;
@ -79,6 +78,7 @@ impl<T: vfs::FileSystem> VfsWrapper<T> {
} }
} }
/// Helper macro to reply error when VFS operation fails
macro_rules! try_vfs { macro_rules! try_vfs {
($reply:expr, $expr:expr) => (match $expr { ($reply:expr, $expr:expr) => (match $expr {
Ok(val) => val, Ok(val) => val,
@ -90,6 +90,11 @@ macro_rules! try_vfs {
} }
impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> { impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
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) { fn lookup(&mut self, _req: &Request, parent: u64, name: &OsStr, reply: ReplyEntry) {
let inode = try_vfs!(reply, self.get_inode(parent)); let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.lookup(name.to_str().unwrap())); let target = try_vfs!(reply, inode.lookup(name.to_str().unwrap()));
@ -106,7 +111,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
reply.attr(&TTL, &attr); 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 name = name.to_str().unwrap();
let inode = try_vfs!(reply, self.get_inode(parent)); let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.create(name, vfs::FileType::File)); let target = try_vfs!(reply, inode.create(name, vfs::FileType::File));
@ -116,7 +121,7 @@ impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
reply.entry(&TTL, &attr, 0); 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 name = name.to_str().unwrap();
let inode = try_vfs!(reply, self.get_inode(parent)); let inode = try_vfs!(reply, self.get_inode(parent));
let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir)); let target = try_vfs!(reply, inode.create(name, vfs::FileType::Dir));
@ -168,8 +173,13 @@ impl<T: vfs::FileSystem> Filesystem for VfsWrapper<T> {
reply.data(data.as_slice()); 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 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)); let len = try_vfs!(reply, inode.write_at(offset as usize, data));
reply.written(len as u32); reply.written(len as u32);
} }

@ -10,9 +10,14 @@ path = "src/bin/mksfs.rs"
required-features = ["std"] required-features = ["std"]
[dependencies] [dependencies]
bit-vec = { default-features = false, git = "https://github.com/AltSysrq/bit-vec.git" } # default-features contains 'std'
static_assertions = "0.3" static_assertions = "0.3"
spin = "0.4" spin = "0.4"
log = "0.4"
[dependencies.bitvec]
version = "0.9"
default-features = false
features = ["alloc"]
[dev-dependencies] [dev-dependencies]
tempfile = "3" tempfile = "3"

@ -2,9 +2,9 @@ use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::{Arc, Weak}
use core::any::Any; use core::any::Any;
use core::fmt::{Debug, Error, Formatter}; use core::fmt::{Debug, Error, Formatter};
use core::mem::uninitialized; use core::mem::uninitialized;
use core::slice;
use bit_vec::BitVec; use bitvec::BitVec;
use log::*;
use spin::{Mutex, RwLock}; use spin::{Mutex, RwLock};
use crate::dirty::Dirty; use crate::dirty::Dirty;
@ -547,7 +547,7 @@ impl SimpleFileSystem {
Ok(SimpleFileSystem { Ok(SimpleFileSystem {
super_block: RwLock::new(Dirty::new(super_block)), 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()), inodes: RwLock::new(BTreeMap::new()),
device: Mutex::new(device), device: Mutex::new(device),
self_ptr: Weak::default(), self_ptr: Weak::default(),
@ -565,7 +565,8 @@ impl SimpleFileSystem {
info: Str32::from(DEFAULT_INFO), info: Str32::from(DEFAULT_INFO),
}; };
let free_map = { 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 { for i in 3..blocks {
bitset.set(i, true); bitset.set(i, true);
} }
@ -592,7 +593,7 @@ impl SimpleFileSystem {
/// Wrap pure SimpleFileSystem with Arc /// Wrap pure SimpleFileSystem with Arc
/// Used in constructors /// Used in constructors
fn wrap(self) -> Arc<Self> { fn wrap(self) -> Arc<Self> {
// 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. // It's a little tricky.
let fs = Arc::new(self); let fs = Arc::new(self);
let weak = Arc::downgrade(&fs); let weak = Arc::downgrade(&fs);
@ -612,6 +613,7 @@ impl SimpleFileSystem {
return None return None
} }
super_block.unused_blocks -= 1; // will not underflow super_block.unused_blocks -= 1; // will not underflow
trace!("alloc block {:#x}", block_id);
} }
id id
} }
@ -621,6 +623,7 @@ impl SimpleFileSystem {
assert!(!free_map[block_id]); assert!(!free_map[block_id]);
free_map.set(block_id, true); free_map.set(block_id, true);
self.super_block.write().unused_blocks += 1; self.super_block.write().unused_blocks += 1;
trace!("free block {:#x}", block_id);
} }
/// Create a new INode struct, then insert it to self.inodes /// Create a new INode struct, then insert it to self.inodes
@ -732,12 +735,10 @@ impl BitsetAlloc for BitVec {
impl AsBuf for BitVec { impl AsBuf for BitVec {
fn as_buf(&self) -> &[u8] { fn as_buf(&self) -> &[u8] {
let slice = self.storage(); self.as_ref()
unsafe { slice::from_raw_parts(slice as *const _ as *const u8, slice.len() * 4) }
} }
fn as_buf_mut(&mut self) -> &mut [u8] { fn as_buf_mut(&mut self) -> &mut [u8] {
let slice = self.storage(); self.as_mut()
unsafe { slice::from_raw_parts_mut(slice as *const _ as *mut u8, slice.len() * 4) }
} }
} }

Loading…
Cancel
Save