Modify the statfs on SEFS or UnionFS with ocall
This commit is contained in:
parent
16e8b12e4d
commit
85d6977118
@ -153,6 +153,8 @@ enclave {
|
||||
|
||||
void occlum_ocall_sync(void);
|
||||
|
||||
int occlum_ocall_statfs([in, string] const char* path, [out] struct statfs* buf) propagate_errno;
|
||||
|
||||
void* occlum_ocall_posix_memalign(size_t alignment, size_t size);
|
||||
void occlum_ocall_free([user_check] void* ptr);
|
||||
|
||||
|
@ -19,7 +19,7 @@ struct occlum_stdio_fds {
|
||||
int stderr_fd;
|
||||
};
|
||||
|
||||
typedef struct _timespec{
|
||||
struct _timespec{
|
||||
time_t tv_sec;
|
||||
syscall_slong_t tv_nsec;
|
||||
};
|
||||
@ -34,4 +34,19 @@ typedef struct {
|
||||
unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
|
||||
} fd_set;
|
||||
|
||||
struct statfs {
|
||||
unsigned long f_type;
|
||||
unsigned long f_bsize;
|
||||
unsigned long f_blocks;
|
||||
unsigned long f_bfree;
|
||||
unsigned long f_bavail;
|
||||
unsigned long f_files;
|
||||
unsigned long f_ffree;
|
||||
int f_fsid[2];
|
||||
unsigned long f_namelen;
|
||||
unsigned long f_frsize;
|
||||
unsigned long f_flags;
|
||||
unsigned long f_spare[4];
|
||||
};
|
||||
|
||||
#endif /* __OCCLUM_EDL_TYPES_H__ */
|
||||
|
@ -1,11 +1,15 @@
|
||||
use super::*;
|
||||
use rcore_fs::vfs::FsInfo;
|
||||
use std::ffi::CString;
|
||||
|
||||
pub fn do_fstatfs(fd: FileDesc) -> Result<Statfs> {
|
||||
debug!("fstatfs: fd: {}", fd);
|
||||
|
||||
let file_ref = current!().file(fd)?;
|
||||
let statfs = Statfs::from(file_ref.fs()?.info());
|
||||
let statfs = {
|
||||
let fs_info = file_ref.fs()?.info();
|
||||
do_statfs_inner(fs_info)?
|
||||
};
|
||||
trace!("fstatfs result: {:?}", statfs);
|
||||
Ok(statfs)
|
||||
}
|
||||
@ -18,12 +22,28 @@ pub fn do_statfs(path: &str) -> Result<Statfs> {
|
||||
let fs = current.fs().read().unwrap();
|
||||
fs.lookup_inode(path)?
|
||||
};
|
||||
let statfs = Statfs::from(inode.fs().info());
|
||||
let statfs = {
|
||||
let fs_info = inode.fs().info();
|
||||
do_statfs_inner(fs_info)?
|
||||
};
|
||||
trace!("statfs result: {:?}", statfs);
|
||||
Ok(statfs)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
fn do_statfs_inner(fs_info: FsInfo) -> Result<Statfs> {
|
||||
let statfs = if fs_info.magic == rcore_fs_unionfs::UNIONFS_MAGIC
|
||||
|| fs_info.magic == rcore_fs_sefs::SEFS_MAGIC as usize
|
||||
{
|
||||
let mut host_statfs = host_statfs()?;
|
||||
host_statfs.f_type = fs_info.magic;
|
||||
host_statfs
|
||||
} else {
|
||||
Statfs::from(fs_info)
|
||||
};
|
||||
Ok(statfs)
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct Statfs {
|
||||
/// Type of filesystem
|
||||
@ -52,6 +72,21 @@ pub struct Statfs {
|
||||
f_spare: [usize; 4],
|
||||
}
|
||||
|
||||
impl Statfs {
|
||||
fn validate(&self) -> Result<()> {
|
||||
if self.f_blocks < self.f_bfree || self.f_blocks < self.f_bavail {
|
||||
return_errno!(EINVAL, "invalid blocks");
|
||||
}
|
||||
if self.f_files < self.f_ffree {
|
||||
return_errno!(EINVAL, "invalid inodes");
|
||||
}
|
||||
if self.f_bsize == 0 || self.f_namelen == 0 || self.f_frsize == 0 {
|
||||
return_errno!(EINVAL, "invalid non-zero fields");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FsInfo> for Statfs {
|
||||
fn from(info: FsInfo) -> Self {
|
||||
Self {
|
||||
@ -78,3 +113,23 @@ impl From<FsInfo> for Statfs {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn host_statfs() -> Result<Statfs> {
|
||||
extern "C" {
|
||||
fn occlum_ocall_statfs(ret: *mut i32, path: *const i8, buf: *mut Statfs) -> sgx_status_t;
|
||||
}
|
||||
|
||||
let mut ret: i32 = 0;
|
||||
let mut statfs: Statfs = Default::default();
|
||||
let host_dir = unsafe { CString::new(INSTANCE_DIR.as_bytes()).unwrap() };
|
||||
let sgx_status = unsafe { occlum_ocall_statfs(&mut ret, host_dir.as_ptr(), &mut statfs) };
|
||||
assert!(sgx_status == sgx_status_t::SGX_SUCCESS);
|
||||
assert!(ret == 0 || libc::errno() == Errno::EINTR as i32);
|
||||
if ret != 0 {
|
||||
return_errno!(EINTR, "failed to get host statfs");
|
||||
}
|
||||
|
||||
// do sanity check
|
||||
statfs.validate().expect("invalid statfs");
|
||||
Ok(statfs)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <sys/select.h> // import fd_set
|
||||
#include <sys/time.h> // import struct timeval
|
||||
#include <sys/uio.h> // import struct iovec
|
||||
#include <sys/vfs.h> // import struct statfs
|
||||
#include <occlum_pal_api.h> // import occlum_stdio_fds
|
||||
|
||||
#endif /* __OCCLUM_EDL_TYPES__ */
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
void occlum_ocall_sync(void) {
|
||||
sync();
|
||||
@ -41,3 +42,7 @@ int occlum_ocall_ioctl(int fd, int request, void *arg, size_t len) {
|
||||
|
||||
return ioctl(fd, request, arg);
|
||||
}
|
||||
|
||||
int occlum_ocall_statfs(const char *path, struct statfs *buf) {
|
||||
return statfs(path, buf);
|
||||
}
|
Loading…
Reference in New Issue
Block a user