add genfs; port existing fs operations to genfs
This commit is contained in:
parent
057b3cc7e9
commit
abcf7c5c84
|
@ -7,6 +7,7 @@ authors = ["Szymon Walter <walter.szymon.98@gmail.com>"]
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
rlibc = { version = "1.0", optional = true }
|
rlibc = { version = "1.0", optional = true }
|
||||||
spin = "0.4"
|
spin = "0.4"
|
||||||
|
genfs = "^0.1.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["no_std"]
|
default = ["no_std"]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use core::fmt::{self, Display};
|
use core::fmt::{self, Display};
|
||||||
use alloc::{String, Vec};
|
use alloc::String;
|
||||||
|
|
||||||
#[cfg(any(test, not(feature = "no_std")))]
|
#[cfg(any(test, not(feature = "no_std")))]
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
393
src/fs/sync.rs
393
src/fs/sync.rs
|
@ -6,6 +6,7 @@ use alloc::{String, Vec};
|
||||||
use alloc::arc::Arc;
|
use alloc::arc::Arc;
|
||||||
|
|
||||||
use spin::{Mutex, MutexGuard};
|
use spin::{Mutex, MutexGuard};
|
||||||
|
use genfs::*;
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use sector::{Address, SectorSize};
|
use sector::{Address, SectorSize};
|
||||||
|
@ -43,82 +44,11 @@ impl<S: SectorSize, V: Volume<u8, S>> Synced<Ext2<S, V>> {
|
||||||
Ext2::new(volume).map(|inner| Synced::with_inner(inner))
|
Ext2::new(volume).map(|inner| Synced::with_inner(inner))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_inode(
|
pub fn root_inode(&self) -> Inode<S, V> {
|
||||||
&self,
|
|
||||||
abs_path: &[u8],
|
|
||||||
) -> Result<(Inode<S, V>, Address<S>), Error> {
|
|
||||||
pub fn inner<'a, S, V, I>(
|
|
||||||
fs: &Synced<Ext2<S, V>>,
|
|
||||||
inode: (u32, Inode<S, V>, Address<S>),
|
|
||||||
mut path: I,
|
|
||||||
abs_path: &[u8],
|
|
||||||
) -> Result<(Inode<S, V>, Address<S>), Error>
|
|
||||||
where
|
|
||||||
S: SectorSize,
|
|
||||||
V: Volume<u8, S>,
|
|
||||||
I: Iterator<Item = &'a [u8]>,
|
|
||||||
{
|
|
||||||
let name = match path.next() {
|
|
||||||
Some(name) => name,
|
|
||||||
None => return Ok((inode.1, inode.2)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut dir = match inode.1.directory() {
|
|
||||||
Some(dir) => dir,
|
|
||||||
None => {
|
|
||||||
return Err(Error::NotADirectory {
|
|
||||||
inode: inode.0,
|
|
||||||
name: String::from_utf8_lossy(abs_path).into_owned(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let num = match dir.find(|entry| {
|
|
||||||
entry.is_err() || entry.as_ref().unwrap().name == name
|
|
||||||
}) {
|
|
||||||
Some(Ok(entry)) => entry.inode,
|
|
||||||
Some(Err(err)) => return Err(err),
|
|
||||||
None => {
|
|
||||||
return Err(Error::NotFound {
|
|
||||||
name: String::from_utf8_lossy(abs_path).into_owned(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let inode = match fs.inode_nth(num) {
|
|
||||||
Some((inode, addr)) => (num as u32, inode, addr),
|
|
||||||
None => {
|
|
||||||
return Err(Error::InodeNotFound {
|
|
||||||
inode: inode.0 as u32,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inner(fs, inode, path, abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if abs_path.len() == 0 || abs_path[0] != b'/' {
|
|
||||||
return Err(Error::NotAbsolute {
|
|
||||||
name: String::from_utf8_lossy(abs_path).into_owned(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if abs_path == b"/" {
|
|
||||||
return Ok(self.root_inode());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut path = abs_path.split(|byte| *byte == b'/');
|
|
||||||
path.next();
|
|
||||||
let (root, addr) = self.root_inode();
|
|
||||||
|
|
||||||
inner(self, (2, root, addr), path, abs_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn root_inode(&self) -> (Inode<S, V>, Address<S>) {
|
|
||||||
self.inode_nth(2).unwrap()
|
self.inode_nth(2).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inode_nth(&self, index: usize) -> Option<(Inode<S, V>, Address<S>)> {
|
pub fn inode_nth(&self, index: usize) -> Option<Inode<S, V>> {
|
||||||
self.inodes_nth(index).next()
|
self.inodes_nth(index).next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +78,172 @@ impl<S: SectorSize, V: Volume<u8, S>> Synced<Ext2<S, V>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: SectorSize, V: Volume<u8, S>> Fs for Synced<Ext2<S, V>> {
|
||||||
|
type Path = [u8];
|
||||||
|
type PathOwned = Vec<u8>;
|
||||||
|
type File = Inode<S, V>;
|
||||||
|
type Dir = Directory<S, V>;
|
||||||
|
type DirEntry = DirectoryEntry;
|
||||||
|
type Metadata = (); // TODO
|
||||||
|
type Permissions = (); // TODO
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn open(
|
||||||
|
&self,
|
||||||
|
abs_path: &Self::Path,
|
||||||
|
_options: &OpenOptions<Self::Permissions>,
|
||||||
|
) -> Result<Self::File, Self::Error> {
|
||||||
|
fn inner<'a, S, V, I>(
|
||||||
|
fs: &Synced<Ext2<S, V>>,
|
||||||
|
inode: Inode<S, V>,
|
||||||
|
mut path: I,
|
||||||
|
abs_path: &[u8],
|
||||||
|
) -> Result<Inode<S, V>, Error>
|
||||||
|
where
|
||||||
|
S: SectorSize,
|
||||||
|
V: Volume<u8, S>,
|
||||||
|
I: Iterator<Item = &'a [u8]>,
|
||||||
|
{
|
||||||
|
let name = match path.next() {
|
||||||
|
Some(name) => name,
|
||||||
|
None => return Ok(inode),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut dir =
|
||||||
|
inode.directory().ok_or_else(|| Error::NotADirectory {
|
||||||
|
inode: inode.num,
|
||||||
|
name: String::from_utf8_lossy(abs_path).into_owned(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let entry = dir.find(|entry| {
|
||||||
|
entry.is_err() || entry.as_ref().unwrap().name == name
|
||||||
|
}).ok_or_else(|| Error::NotFound {
|
||||||
|
name: String::from_utf8_lossy(abs_path).into_owned(),
|
||||||
|
})??;
|
||||||
|
|
||||||
|
let inode = fs.inode_nth(entry.inode)
|
||||||
|
.ok_or(Error::InodeNotFound { inode: inode.num })?;
|
||||||
|
|
||||||
|
inner(fs, inode, path, abs_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if abs_path.len() == 0 || abs_path[0] != b'/' {
|
||||||
|
return Err(Error::NotAbsolute {
|
||||||
|
name: String::from_utf8_lossy(abs_path).into_owned(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if abs_path == b"/" {
|
||||||
|
return Ok(self.root_inode());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path = abs_path.split(|byte| *byte == b'/');
|
||||||
|
path.next();
|
||||||
|
let root = self.root_inode();
|
||||||
|
|
||||||
|
inner(self, root, path, abs_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file(&mut self, _path: &Self::Path) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(
|
||||||
|
&self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
) -> Result<Self::Metadata, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn symlink_metadata(
|
||||||
|
&self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
) -> Result<Self::Metadata, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rename(
|
||||||
|
&mut self,
|
||||||
|
_from: &Self::Path,
|
||||||
|
_to: &Self::Path,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy(
|
||||||
|
&mut self,
|
||||||
|
_from: &Self::Path,
|
||||||
|
_to: &Self::Path,
|
||||||
|
) -> Result<u64, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hard_link(
|
||||||
|
&mut self,
|
||||||
|
_src: &Self::Path,
|
||||||
|
_dst: &Self::Path,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn symlink(
|
||||||
|
&mut self,
|
||||||
|
_src: &Self::Path,
|
||||||
|
_dst: &Self::Path,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_link(
|
||||||
|
&self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
) -> Result<Self::PathOwned, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn canonicalize(
|
||||||
|
&self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
) -> Result<Self::PathOwned, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_dir(
|
||||||
|
&mut self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
_options: &DirOptions<Self::Permissions>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir(&mut self, _path: &Self::Path) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir_all(
|
||||||
|
&mut self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(&self, path: &Self::Path) -> Result<Self::Dir, Self::Error> {
|
||||||
|
let inode = self.open(path, OpenOptions::new().read(true))?;
|
||||||
|
inode.directory().ok_or(Error::NotADirectory {
|
||||||
|
inode: inode.num,
|
||||||
|
name: String::from_utf8_lossy(path).into_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_permissions(
|
||||||
|
&mut self,
|
||||||
|
_path: &Self::Path,
|
||||||
|
_perm: Self::Permissions,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: SectorSize, V: Volume<u8, S>> Debug for Synced<Ext2<S, V>> {
|
impl<S: SectorSize, V: Volume<u8, S>> Debug for Synced<Ext2<S, V>> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Synced<Ext2<{}>>", S::SIZE)
|
write!(f, "Synced<Ext2<{}>>", S::SIZE)
|
||||||
|
@ -165,7 +261,7 @@ pub struct Inodes<S: SectorSize, V: Volume<u8, S>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SectorSize, V: Volume<u8, S>> Iterator for Inodes<S, V> {
|
impl<S: SectorSize, V: Volume<u8, S>> Iterator for Inodes<S, V> {
|
||||||
type Item = (Inode<S, V>, Address<S>);
|
type Item = Inode<S, V>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.index < self.inodes_count {
|
if self.index < self.inodes_count {
|
||||||
|
@ -186,7 +282,14 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for Inodes<S, V> {
|
||||||
let raw = unsafe {
|
let raw = unsafe {
|
||||||
RawInode::find_inode(&fs.volume, offset, self.inode_size).ok()
|
RawInode::find_inode(&fs.volume, offset, self.inode_size).ok()
|
||||||
};
|
};
|
||||||
raw.map(|(raw, offset)| (Inode::new(self.fs.clone(), raw), offset))
|
raw.map(|(raw, offset)| {
|
||||||
|
Inode::new(
|
||||||
|
self.fs.clone(),
|
||||||
|
raw,
|
||||||
|
offset,
|
||||||
|
(self.index - 1) as u32,
|
||||||
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -197,6 +300,8 @@ impl<S: SectorSize, V: Volume<u8, S>> Iterator for Inodes<S, V> {
|
||||||
pub struct Inode<S: SectorSize, V: Volume<u8, S>> {
|
pub struct Inode<S: SectorSize, V: Volume<u8, S>> {
|
||||||
fs: Synced<Ext2<S, V>>,
|
fs: Synced<Ext2<S, V>>,
|
||||||
inner: RawInode,
|
inner: RawInode,
|
||||||
|
addr: Address<S>,
|
||||||
|
num: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SectorSize, V: Volume<u8, S>> Clone for Inode<S, V> {
|
impl<S: SectorSize, V: Volume<u8, S>> Clone for Inode<S, V> {
|
||||||
|
@ -204,38 +309,25 @@ impl<S: SectorSize, V: Volume<u8, S>> Clone for Inode<S, V> {
|
||||||
Inode {
|
Inode {
|
||||||
fs: self.fs.clone(),
|
fs: self.fs.clone(),
|
||||||
inner: self.inner,
|
inner: self.inner,
|
||||||
|
addr: self.addr,
|
||||||
|
num: self.num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
pub fn new(fs: Synced<Ext2<S, V>>, inner: RawInode) -> Inode<S, V> {
|
pub fn new(
|
||||||
Inode { fs, inner }
|
fs: Synced<Ext2<S, V>>,
|
||||||
}
|
inner: RawInode,
|
||||||
|
addr: Address<S>,
|
||||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
num: u32,
|
||||||
let total_size = self.size();
|
) -> Inode<S, V> {
|
||||||
let block_size = {
|
Inode {
|
||||||
let fs = self.fs.inner();
|
fs,
|
||||||
fs.block_size()
|
inner,
|
||||||
};
|
addr,
|
||||||
let mut offset = 0;
|
num,
|
||||||
|
|
||||||
for block in self.blocks() {
|
|
||||||
match block {
|
|
||||||
Ok((data, _)) => {
|
|
||||||
let data_size = block_size
|
|
||||||
.min(total_size - offset)
|
|
||||||
.min(buf.len() - offset);
|
|
||||||
let end = offset + data_size;
|
|
||||||
buf[offset..end].copy_from_slice(&data[..data_size]);
|
|
||||||
offset += data_size;
|
|
||||||
}
|
|
||||||
Err(err) => return Err(err.into()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(offset)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize, Error> {
|
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize, Error> {
|
||||||
|
@ -437,6 +529,47 @@ impl<S: SectorSize, V: Volume<u8, S>> Inode<S, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: SectorSize, V: Volume<u8, S>> File for Inode<S, V> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
let total_size = self.size();
|
||||||
|
let block_size = {
|
||||||
|
let fs = self.fs.inner();
|
||||||
|
fs.block_size()
|
||||||
|
};
|
||||||
|
let mut offset = 0;
|
||||||
|
|
||||||
|
for block in self.blocks() {
|
||||||
|
match block {
|
||||||
|
Ok((data, _)) => {
|
||||||
|
let data_size = block_size
|
||||||
|
.min(total_size - offset)
|
||||||
|
.min(buf.len() - offset);
|
||||||
|
let end = offset + data_size;
|
||||||
|
buf[offset..end].copy_from_slice(&data[..data_size]);
|
||||||
|
offset += data_size;
|
||||||
|
}
|
||||||
|
Err(err) => return Err(err.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, _buf: &[u8]) -> Result<usize, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seek(&mut self, _pos: SeekFrom) -> Result<u64, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct InodeBlocks<S: SectorSize, V: Volume<u8, S>> {
|
pub struct InodeBlocks<S: SectorSize, V: Volume<u8, S>> {
|
||||||
inode: Inode<S, V>,
|
inode: Inode<S, V>,
|
||||||
|
@ -478,6 +611,11 @@ pub struct Directory<S: SectorSize, V: Volume<u8, S>> {
|
||||||
block_size: usize,
|
block_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: SectorSize, V: Volume<u8, S>> Dir<DirectoryEntry, Error>
|
||||||
|
for Directory<S, V>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<S: SectorSize, V: Volume<u8, S>> Iterator for Directory<S, V> {
|
impl<S: SectorSize, V: Volume<u8, S>> Iterator for Directory<S, V> {
|
||||||
type Item = Result<DirectoryEntry, Error>;
|
type Item = Result<DirectoryEntry, Error>;
|
||||||
|
|
||||||
|
@ -524,11 +662,37 @@ pub struct DirectoryEntry {
|
||||||
pub ty: u8,
|
pub ty: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DirEntry for DirectoryEntry {
|
||||||
|
type Path = [u8];
|
||||||
|
type PathOwned = Vec<u8>;
|
||||||
|
type Metadata = (); // TODO
|
||||||
|
type FileType = u8; // TODO: enum FileType
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn path(&self) -> Self::PathOwned {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> Result<Self::Metadata, Self::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_type(&self) -> Result<Self::FileType, Self::Error> {
|
||||||
|
Ok(self.ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> &Self::Path {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
use genfs::{File as GenFile, Fs, OpenOptions};
|
||||||
|
|
||||||
use sector::{SectorSize, Size512};
|
use sector::{SectorSize, Size512};
|
||||||
use volume::Volume;
|
use volume::Volume;
|
||||||
|
|
||||||
|
@ -566,7 +730,7 @@ mod tests {
|
||||||
|
|
||||||
let fs = fs.unwrap();
|
let fs = fs.unwrap();
|
||||||
|
|
||||||
let inodes = fs.inodes().filter(|inode| inode.0.in_use());
|
let inodes = fs.inodes().filter(|inode| inode.in_use());
|
||||||
for inode in inodes {
|
for inode in inodes {
|
||||||
println!("{:?}", inode);
|
println!("{:?}", inode);
|
||||||
}
|
}
|
||||||
|
@ -579,12 +743,12 @@ mod tests {
|
||||||
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
||||||
|
|
||||||
let inodes = fs.inodes().filter(|inode| {
|
let inodes = fs.inodes().filter(|inode| {
|
||||||
inode.0.in_use() && inode.0.uid() == 1000 && inode.0.size() < 1024
|
inode.in_use() && inode.uid() == 1000 && inode.size() < 1024
|
||||||
});
|
});
|
||||||
for inode in inodes {
|
for inode in inodes {
|
||||||
println!("{:?}", inode.0);
|
println!("{:?}", inode);
|
||||||
let size = inode.0.size();
|
let size = inode.size();
|
||||||
for block in inode.0.blocks() {
|
for block in inode.blocks() {
|
||||||
let (data, _) = block.unwrap();
|
let (data, _) = block.unwrap();
|
||||||
assert_eq!(data.len(), {
|
assert_eq!(data.len(), {
|
||||||
let fs = fs.inner();
|
let fs = fs.inner();
|
||||||
|
@ -603,9 +767,9 @@ mod tests {
|
||||||
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
||||||
|
|
||||||
let inodes = fs.inodes().filter(|inode| {
|
let inodes = fs.inodes().filter(|inode| {
|
||||||
inode.0.in_use() && inode.0.uid() == 1000 && inode.0.size() < 1024
|
inode.in_use() && inode.uid() == 1000 && inode.size() < 1024
|
||||||
});
|
});
|
||||||
for (inode, _) in inodes {
|
for inode in inodes {
|
||||||
let mut buf = Vec::with_capacity(inode.size());
|
let mut buf = Vec::with_capacity(inode.size());
|
||||||
unsafe {
|
unsafe {
|
||||||
buf.set_len(inode.size());
|
buf.set_len(inode.size());
|
||||||
|
@ -626,10 +790,9 @@ mod tests {
|
||||||
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
||||||
|
|
||||||
let inodes = fs.inodes().filter(|inode| {
|
let inodes = fs.inodes().filter(|inode| {
|
||||||
inode.0.in_use() && inode.0.uid() == 1000
|
inode.in_use() && inode.uid() == 1000 && inode.size() == 537600
|
||||||
&& inode.0.size() == 537600
|
|
||||||
});
|
});
|
||||||
for (inode, _) in inodes {
|
for inode in inodes {
|
||||||
let mut buf = Vec::with_capacity(inode.size());
|
let mut buf = Vec::with_capacity(inode.size());
|
||||||
unsafe {
|
unsafe {
|
||||||
buf.set_len(inode.size());
|
buf.set_len(inode.size());
|
||||||
|
@ -670,7 +833,7 @@ mod tests {
|
||||||
if entry_name != "." && entry_name != ".." {
|
if entry_name != "." && entry_name != ".." {
|
||||||
walk(
|
walk(
|
||||||
fs,
|
fs,
|
||||||
fs.inode_nth(entry.inode).unwrap().0,
|
fs.inode_nth(entry.inode).unwrap(),
|
||||||
format!("{}/{}", name, entry_name),
|
format!("{}/{}", name, entry_name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -681,7 +844,7 @@ mod tests {
|
||||||
let file = RefCell::new(File::open("ext2.img").unwrap());
|
let file = RefCell::new(File::open("ext2.img").unwrap());
|
||||||
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
||||||
|
|
||||||
let (root, _) = fs.root_inode();
|
let root = fs.root_inode();
|
||||||
walk(&fs, root, String::new());
|
walk(&fs, root, String::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,10 +854,10 @@ mod tests {
|
||||||
let file = RefCell::new(File::open("ext2.img").unwrap());
|
let file = RefCell::new(File::open("ext2.img").unwrap());
|
||||||
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
let fs = Synced::<Ext2<Size512, _>>::new(file).unwrap();
|
||||||
|
|
||||||
let found = fs.find_inode(b"/home/funky/README.md");
|
let found = fs.open(b"/home/funky/README.md", &OpenOptions::new());
|
||||||
|
|
||||||
assert!(found.is_ok());
|
assert!(found.is_ok());
|
||||||
let (inode, _) = found.unwrap();
|
let inode = found.unwrap();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
assert!(inode.read_to_end(&mut vec).is_ok());
|
assert!(inode.read_to_end(&mut vec).is_ok());
|
||||||
println!("{}", str::from_utf8(&vec).unwrap());
|
println!("{}", str::from_utf8(&vec).unwrap());
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
extern crate genfs;
|
||||||
extern crate spin;
|
extern crate spin;
|
||||||
|
|
||||||
#[cfg(any(test, not(feature = "no_std")))]
|
#[cfg(any(test, not(feature = "no_std")))]
|
||||||
|
|
Reference in a new issue