Skip to content

Commit

Permalink
Merge pull request #917 from stlankes/fuse
Browse files Browse the repository at this point in the history
Extend the FUSE support
  • Loading branch information
mkroening authored Sep 19, 2023
2 parents 1872cc0 + 5a1d248 commit daa9682
Show file tree
Hide file tree
Showing 7 changed files with 907 additions and 28 deletions.
35 changes: 32 additions & 3 deletions src/fd/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use alloc::boxed::Box;
use core::{isize, slice};

use crate::fd::{
uhyve_send, ObjectInterface, SysClose, SysLseek, SysRead, SysWrite, UHYVE_PORT_CLOSE,
UHYVE_PORT_LSEEK, UHYVE_PORT_READ, UHYVE_PORT_WRITE,
uhyve_send, DirectoryEntry, ObjectInterface, SysClose, SysLseek, SysRead, SysWrite,
UHYVE_PORT_CLOSE, UHYVE_PORT_LSEEK, UHYVE_PORT_READ, UHYVE_PORT_WRITE,
};
use crate::syscalls::fs::{self, PosixFile, SeekWhence};
use crate::syscalls::fs::{self, FileAttr, PosixFile, SeekWhence};

#[derive(Debug, Clone)]
pub struct UhyveFile(i32);
Expand Down Expand Up @@ -98,6 +98,35 @@ impl ObjectInterface for GenericFile {

ret as isize
}

/// `fstat`
fn fstat(&self, stat: *mut FileAttr) -> i32 {
debug!("fstat ! {}", self.0);
let mut result = 0;
let mut fs = fs::FILESYSTEM.lock();
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| {
result = file
.fstat(stat)
.map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0);
});

result
}

fn readdir(&self) -> DirectoryEntry {
debug!("readdir ! {}", self.0);

let mut fs = fs::FILESYSTEM.lock();
let mut ret = DirectoryEntry::Invalid(-crate::errno::EINVAL);
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| {
match file.readdir() {
Ok(dir_ptr) => ret = DirectoryEntry::Valid(dir_ptr),
Err(e) => ret = DirectoryEntry::Invalid(-num::ToPrimitive::to_i32(&e).unwrap()),
}
});

ret
}
}

impl Drop for GenericFile {
Expand Down
64 changes: 62 additions & 2 deletions src/fd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::env;
use crate::errno::*;
use crate::fd::file::{GenericFile, UhyveFile};
use crate::fd::stdio::*;
use crate::syscalls::fs::{self, FilePerms, SeekWhence};
use crate::syscalls::fs::{self, Dirent, FileAttr, FilePerms, SeekWhence};
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "newlib")))]
use crate::syscalls::net::*;

Expand Down Expand Up @@ -181,6 +181,13 @@ fn open_flags_to_perm(flags: i32, mode: u32) -> FilePerms {
perms
}

#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum DirectoryEntry {
Invalid(i32),
Valid(*const Dirent),
}

pub trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone {
/// `read` attempts to read `len` bytes from the object references
/// by the descriptor
Expand All @@ -199,11 +206,33 @@ pub trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone {
(-EINVAL).try_into().unwrap()
}

/// `unlink` removes directory entry
/// `fstat`
fn fstat(&self, _stat: *mut FileAttr) -> i32 {
-EINVAL
}

/// `unlink` removes file entry
fn unlink(&self, _name: *const u8) -> i32 {
-EINVAL
}

/// `rmdir` removes directory entry
fn rmdir(&self, _name: *const u8) -> i32 {
-EINVAL
}

/// 'readdir' returns a pointer to a dirent structure
/// representing the next directory entry in the directory stream
/// pointed to by the file descriptor
fn readdir(&self) -> DirectoryEntry {
DirectoryEntry::Invalid(-ENOSYS)
}

/// `mkdir` creates a directory entry
fn mkdir(&self, _name: *const u8, _mode: u32) -> i32 {
-EINVAL
}

/// `accept` a connection on a socket
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "newlib")))]
fn accept(&self, _addr: *mut sockaddr, _addrlen: *mut socklen_t) -> i32 {
Expand Down Expand Up @@ -319,6 +348,37 @@ pub(crate) fn open(name: *const u8, flags: i32, mode: i32) -> Result<FileDescrip
}
}

#[allow(unused_variables)]
pub(crate) fn opendir(name: *const u8) -> Result<FileDescriptor, i32> {
if env::is_uhyve() {
Err(-EINVAL)
} else {
#[cfg(target_arch = "x86_64")]
{
let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();
debug!("Open directory {}", name);

let mut fs = fs::FILESYSTEM.lock();
if let Ok(filesystem_fd) = fs.opendir(name) {
let fd = FD_COUNTER.fetch_add(1, Ordering::SeqCst);
// Would a GenericDir make sense?
let file = GenericFile::new(filesystem_fd);
if OBJECT_MAP.write().try_insert(fd, Arc::new(file)).is_err() {
Err(-EINVAL)
} else {
Ok(fd as FileDescriptor)
}
} else {
Err(-EINVAL)
}
}
#[cfg(not(target_arch = "x86_64"))]
{
Err(-ENOSYS)
}
}
}

pub(crate) fn get_object(fd: FileDescriptor) -> Result<Arc<dyn ObjectInterface>, i32> {
Ok((*(OBJECT_MAP.read().get(&fd).ok_or(-EINVAL)?)).clone())
}
Expand Down
Loading

0 comments on commit daa9682

Please sign in to comment.