Skip to content

Commit daa9682

Browse files
authored
Merge pull request #917 from stlankes/fuse
Extend the FUSE support
2 parents 1872cc0 + 5a1d248 commit daa9682

File tree

7 files changed

+907
-28
lines changed

7 files changed

+907
-28
lines changed

src/fd/file.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use alloc::boxed::Box;
22
use core::{isize, slice};
33

44
use crate::fd::{
5-
uhyve_send, ObjectInterface, SysClose, SysLseek, SysRead, SysWrite, UHYVE_PORT_CLOSE,
6-
UHYVE_PORT_LSEEK, UHYVE_PORT_READ, UHYVE_PORT_WRITE,
5+
uhyve_send, DirectoryEntry, ObjectInterface, SysClose, SysLseek, SysRead, SysWrite,
6+
UHYVE_PORT_CLOSE, UHYVE_PORT_LSEEK, UHYVE_PORT_READ, UHYVE_PORT_WRITE,
77
};
8-
use crate::syscalls::fs::{self, PosixFile, SeekWhence};
8+
use crate::syscalls::fs::{self, FileAttr, PosixFile, SeekWhence};
99

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

9999
ret as isize
100100
}
101+
102+
/// `fstat`
103+
fn fstat(&self, stat: *mut FileAttr) -> i32 {
104+
debug!("fstat ! {}", self.0);
105+
let mut result = 0;
106+
let mut fs = fs::FILESYSTEM.lock();
107+
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| {
108+
result = file
109+
.fstat(stat)
110+
.map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0);
111+
});
112+
113+
result
114+
}
115+
116+
fn readdir(&self) -> DirectoryEntry {
117+
debug!("readdir ! {}", self.0);
118+
119+
let mut fs = fs::FILESYSTEM.lock();
120+
let mut ret = DirectoryEntry::Invalid(-crate::errno::EINVAL);
121+
fs.fd_op(self.0, |file: &mut Box<dyn PosixFile + Send>| {
122+
match file.readdir() {
123+
Ok(dir_ptr) => ret = DirectoryEntry::Valid(dir_ptr),
124+
Err(e) => ret = DirectoryEntry::Invalid(-num::ToPrimitive::to_i32(&e).unwrap()),
125+
}
126+
});
127+
128+
ret
129+
}
101130
}
102131

103132
impl Drop for GenericFile {

src/fd/mod.rs

+62-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::env;
1313
use crate::errno::*;
1414
use crate::fd::file::{GenericFile, UhyveFile};
1515
use crate::fd::stdio::*;
16-
use crate::syscalls::fs::{self, FilePerms, SeekWhence};
16+
use crate::syscalls::fs::{self, Dirent, FileAttr, FilePerms, SeekWhence};
1717
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "newlib")))]
1818
use crate::syscalls::net::*;
1919

@@ -181,6 +181,13 @@ fn open_flags_to_perm(flags: i32, mode: u32) -> FilePerms {
181181
perms
182182
}
183183

184+
#[derive(Copy, Clone, Debug)]
185+
#[repr(C)]
186+
pub enum DirectoryEntry {
187+
Invalid(i32),
188+
Valid(*const Dirent),
189+
}
190+
184191
pub trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone {
185192
/// `read` attempts to read `len` bytes from the object references
186193
/// by the descriptor
@@ -199,11 +206,33 @@ pub trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone {
199206
(-EINVAL).try_into().unwrap()
200207
}
201208

202-
/// `unlink` removes directory entry
209+
/// `fstat`
210+
fn fstat(&self, _stat: *mut FileAttr) -> i32 {
211+
-EINVAL
212+
}
213+
214+
/// `unlink` removes file entry
203215
fn unlink(&self, _name: *const u8) -> i32 {
204216
-EINVAL
205217
}
206218

219+
/// `rmdir` removes directory entry
220+
fn rmdir(&self, _name: *const u8) -> i32 {
221+
-EINVAL
222+
}
223+
224+
/// 'readdir' returns a pointer to a dirent structure
225+
/// representing the next directory entry in the directory stream
226+
/// pointed to by the file descriptor
227+
fn readdir(&self) -> DirectoryEntry {
228+
DirectoryEntry::Invalid(-ENOSYS)
229+
}
230+
231+
/// `mkdir` creates a directory entry
232+
fn mkdir(&self, _name: *const u8, _mode: u32) -> i32 {
233+
-EINVAL
234+
}
235+
207236
/// `accept` a connection on a socket
208237
#[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "newlib")))]
209238
fn accept(&self, _addr: *mut sockaddr, _addrlen: *mut socklen_t) -> i32 {
@@ -319,6 +348,37 @@ pub(crate) fn open(name: *const u8, flags: i32, mode: i32) -> Result<FileDescrip
319348
}
320349
}
321350

351+
#[allow(unused_variables)]
352+
pub(crate) fn opendir(name: *const u8) -> Result<FileDescriptor, i32> {
353+
if env::is_uhyve() {
354+
Err(-EINVAL)
355+
} else {
356+
#[cfg(target_arch = "x86_64")]
357+
{
358+
let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();
359+
debug!("Open directory {}", name);
360+
361+
let mut fs = fs::FILESYSTEM.lock();
362+
if let Ok(filesystem_fd) = fs.opendir(name) {
363+
let fd = FD_COUNTER.fetch_add(1, Ordering::SeqCst);
364+
// Would a GenericDir make sense?
365+
let file = GenericFile::new(filesystem_fd);
366+
if OBJECT_MAP.write().try_insert(fd, Arc::new(file)).is_err() {
367+
Err(-EINVAL)
368+
} else {
369+
Ok(fd as FileDescriptor)
370+
}
371+
} else {
372+
Err(-EINVAL)
373+
}
374+
}
375+
#[cfg(not(target_arch = "x86_64"))]
376+
{
377+
Err(-ENOSYS)
378+
}
379+
}
380+
}
381+
322382
pub(crate) fn get_object(fd: FileDescriptor) -> Result<Arc<dyn ObjectInterface>, i32> {
323383
Ok((*(OBJECT_MAP.read().get(&fd).ok_or(-EINVAL)?)).clone())
324384
}

0 commit comments

Comments
 (0)