Skip to content

Commit

Permalink
vfs reading from filesystem tmpfs
Browse files Browse the repository at this point in the history
  • Loading branch information
corigan01 committed Dec 4, 2023
1 parent 9066c0d commit 13b71a2
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 18 deletions.
108 changes: 108 additions & 0 deletions lib/fs/src/file/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
*
*/

use crate::{
io::{FileProvider, Metadata, Read, Seek, Write},
FsResult, Vfs,
};

#[derive(Clone, Copy, PartialEq, Debug)]
pub struct FileDescriptor(pub usize);

Expand All @@ -38,3 +43,106 @@ impl Into<usize> for FileDescriptor {
self.0
}
}

impl FileDescriptor {
pub fn link_vfs<'a>(self, vfs: &'a mut Vfs) -> VfsLinkedFD<'a> {
VfsLinkedFD { fd: self, vfs }
}
}

pub struct VfsLinkedFD<'a> {
fd: FileDescriptor,
vfs: &'a mut Vfs,
}

impl<'a> VfsLinkedFD<'a> {
pub fn unlink(self) -> FileDescriptor {
self.fd
}

pub fn close(self) -> FsResult<()> {
self.vfs.close(self.fd)
}
}

impl<'a> FileProvider for VfsLinkedFD<'a> {}
impl<'a> Metadata for VfsLinkedFD<'a> {
fn date_created(&self) -> Option<crate::UnixTime> {
self.vfs.fd_ref(self.fd).ok()?.data.date_created()
}

fn date_modified(&self) -> Option<crate::UnixTime> {
self.vfs.fd_ref(self.fd).ok()?.data.date_modified()
}

fn date_accessed(&self) -> Option<crate::UnixTime> {
self.vfs.fd_ref(self.fd).ok()?.data.date_accessed()
}

fn date_removed(&self) -> Option<crate::UnixTime> {
self.vfs.fd_ref(self.fd).ok()?.data.date_removed()
}

fn permissions(&self) -> crate::permission::Permissions {
self.vfs.fd_ref(self.fd).unwrap().data.permissions()
}

fn kind(&self) -> crate::io::EntryType {
self.vfs.fd_ref(self.fd).unwrap().data.kind()
}

fn can_write(&self) -> bool {
self.vfs.fd_ref(self.fd).unwrap().data.can_write()
}

fn can_read(&self) -> bool {
self.vfs.fd_ref(self.fd).unwrap().data.can_read()
}

fn can_seek(&self) -> bool {
self.vfs.fd_ref(self.fd).unwrap().data.can_seek()
}

fn len(&self) -> u64 {
self.vfs.fd_ref(self.fd).unwrap().data.len()
}
}

// TODO: Add the rest of these
impl<'a> Read for VfsLinkedFD<'a> {
fn read(&mut self, buf: &mut [u8]) -> crate::FsResult<usize> {
self.vfs.fd_mut(self.fd)?.data.read(buf)
}
}

impl<'a> Write for VfsLinkedFD<'a> {
fn write(&mut self, buf: &[u8]) -> crate::FsResult<usize> {
self.vfs.fd_mut(self.fd)?.data.write(buf)
}

fn flush(&mut self) -> crate::FsResult<()> {
self.vfs.fd_mut(self.fd)?.data.flush()
}
}

impl<'a> Seek for VfsLinkedFD<'a> {
fn seek(&mut self, pos: crate::io::SeekFrom) -> crate::FsResult<u64> {
self.vfs.fd_mut(self.fd)?.data.seek(pos)
}

fn rewind(&mut self) -> crate::FsResult<()> {
self.vfs.fd_mut(self.fd)?.data.rewind()
}

fn stream_len(&mut self) -> crate::FsResult<u64> {
self.vfs.fd_mut(self.fd)?.data.stream_len()
}

fn stream_len_dirty(&mut self) -> crate::FsResult<u64> {
self.vfs.fd_mut(self.fd)?.data.stream_len_dirty()
}

fn stream_position(&mut self) -> crate::FsResult<u64> {
self.vfs.fd_mut(self.fd)?.data.stream_position()
}
}
6 changes: 3 additions & 3 deletions lib/fs/src/filesystems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

mod dosfs;
mod fakefs;
mod tmpfs;
pub mod dosfs;
pub mod fakefs;
pub mod tmpfs;

#[macro_export]
macro_rules! sub_fsprovider {
Expand Down
4 changes: 2 additions & 2 deletions lib/fs/src/filesystems/tmpfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ use crate::{
};
use qk_alloc::{boxed::Box, vec::Vec};

mod dir;
mod file;
pub mod dir;
pub mod file;

pub struct TmpFs {
files: Vec<Box<TmpFile>>,
Expand Down
89 changes: 76 additions & 13 deletions lib/fs/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

use crate::{
dir::dd::DirDescriptor,
error::{FsError, FsErrorKind},
fd::FileDescriptor,
io::{DirectoryProvider, FileProvider, FileSystemProvider},
io::{DirectoryProvider, FileProvider, FileSystemProvider, SeekFrom},
path::Path,
permission::Permissions,
FsResult,
Expand All @@ -37,18 +36,18 @@ use qk_alloc::{bitfield::Bitmap, boxed::Box, vec::Vec};

pub type FilesystemID = usize;

struct OpenFile {
id: FileDescriptor,
fs_id: FilesystemID,
path: Path,
data: Box<dyn FileProvider>,
pub(crate) struct OpenFile {
pub id: FileDescriptor,
pub fs_id: FilesystemID,
pub path: Path,
pub data: Box<dyn FileProvider>,
}

struct OpenDir {
id: DirDescriptor,
fs_id: FilesystemID,
path: Path,
data: Box<dyn DirectoryProvider>,
pub(crate) struct OpenDir {
pub id: DirDescriptor,
pub fs_id: FilesystemID,
pub path: Path,
pub data: Box<dyn DirectoryProvider>,
}

struct OpenFs {
Expand Down Expand Up @@ -363,11 +362,44 @@ impl Vfs {

fs.data.rmdir(fs_rel_path)
}

pub(crate) fn fd_ref(&self, fd: FileDescriptor) -> FsResult<&OpenFile> {
if self.open_ids.len() < fd.0 {
return Err(FsError::new(
FsErrorKind::NotFound,
"That file descriptor was not found!",
));
}

Ok(&self.open_ids[fd.0])
}

pub(crate) fn fd_mut(&mut self, fd: FileDescriptor) -> FsResult<&mut OpenFile> {
if self.open_ids.len() < fd.0 {
return Err(FsError::new(
FsErrorKind::NotFound,
"That file descriptor was not found!",
));
}

Ok(&mut self.open_ids[fd.0])
}

pub fn fread(&mut self, fd: FileDescriptor, buf: &mut [u8]) -> FsResult<usize> {
self.fd_mut(fd)?.data.read(buf)
}

pub fn fseek(&mut self, fd: FileDescriptor, seek: SeekFrom) -> FsResult<u64> {
self.fd_mut(fd)?.data.seek(seek)
}
}

#[cfg(test)]
mod test {
use crate::io::DirectoryProvider;
use crate::{
filesystems::tmpfs::TmpFs,
io::{DirectoryProvider, Write},
};

use super::*;

Expand Down Expand Up @@ -597,4 +629,35 @@ mod test {
Ok(0)
);
}

#[test]
fn test_vfs_with_tmpfs() {
crate::set_example_allocator();
use crate::io::{Read, Seek};

let mut vfs = Vfs::new();

assert_eq!(
vfs.mount(Path::from("/"), Box::new(TmpFs::new(Permissions::all()))),
Ok(0)
);

vfs.touch("/myfile.txt".into(), Permissions::all()).unwrap();
{
let mut file = vfs.open("/myfile.txt".into()).unwrap().link_vfs(&mut vfs);

assert_eq!(file.write(b"123456789"), Ok(9));
let mut read_buf = [0u8; 9];
file.rewind().unwrap();
assert_eq!(file.read(&mut read_buf), Ok(9));
assert_eq!(&read_buf, b"123456789");
file.close().unwrap();
}

assert_eq!(vfs.open_ids.len(), 0);
assert_eq!(vfs.open_dds.len(), 0);

vfs.rm("/myfile.txt".into()).unwrap();
assert!(matches!(vfs.open("/myfile.txt".into()), Err(_)));
}
}

0 comments on commit 13b71a2

Please sign in to comment.