Add posix_fallocate
This commit is contained in:
parent
a789871d93
commit
be62e2c65d
2
deps/sefs
vendored
2
deps/sefs
vendored
@ -1 +1 @@
|
||||
Subproject commit 88784548d5db1156f2d9e71f968d0d78fa7957db
|
||||
Subproject commit bb574e0c0bb0a3034f1f4eb48b1d559fe84d2555
|
@ -96,6 +96,7 @@ impl ToErrno for rcore_fs::vfs::FsError {
|
||||
FsError::NoIntegrity => EIO,
|
||||
FsError::PermError => EPERM,
|
||||
FsError::NameTooLong => ENAMETOOLONG,
|
||||
FsError::FileTooBig => EFBIG,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,10 @@ pub trait File: Debug + Sync + Send + Any {
|
||||
return_op_unsupported_error!("set_advisory_lock")
|
||||
}
|
||||
|
||||
fn fallocate(&self, _mode: u32, _offset: u64, _len: u64) -> Result<()> {
|
||||
return_op_unsupported_error!("fallocate")
|
||||
}
|
||||
|
||||
// TODO: remove this function after all users of this code are removed
|
||||
fn poll(&self) -> Result<(crate::net::PollEventFlags)> {
|
||||
return_op_unsupported_error!("poll")
|
||||
|
11
src/libos/src/fs/file_ops/fallocate.rs
Normal file
11
src/libos/src/fs/file_ops/fallocate.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use super::*;
|
||||
|
||||
pub fn do_fallocate(fd: FileDesc, mode: u32, offset: u64, len: u64) -> Result<()> {
|
||||
debug!(
|
||||
"fallocate: fd: {}, mode: {}, offset: {}, len: {}",
|
||||
fd, mode, offset, len
|
||||
);
|
||||
let file_ref = current!().file(fd)?;
|
||||
file_ref.fallocate(mode, offset, len)?;
|
||||
Ok(())
|
||||
}
|
@ -7,6 +7,7 @@ pub use self::chown::{do_fchown, do_fchownat, ChownFlags};
|
||||
pub use self::close::do_close;
|
||||
pub use self::dirent::{do_getdents, do_getdents64};
|
||||
pub use self::dup::{do_dup, do_dup2, do_dup3};
|
||||
pub use self::fallocate::do_fallocate;
|
||||
pub use self::fcntl::{do_fcntl, FcntlCmd};
|
||||
pub use self::file_flags::{AccessMode, CreationFlags, StatusFlags};
|
||||
pub use self::flock::{Flock, FlockType};
|
||||
@ -36,6 +37,7 @@ mod chown;
|
||||
mod close;
|
||||
mod dirent;
|
||||
mod dup;
|
||||
mod fallocate;
|
||||
mod fcntl;
|
||||
mod file_flags;
|
||||
mod flock;
|
||||
|
@ -121,6 +121,11 @@ impl File for INodeFile {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fallocate(&self, mode: u32, offset: u64, len: u64) -> Result<()> {
|
||||
self.inode.fallocate(mode, offset, len)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_len(&self, len: u64) -> Result<()> {
|
||||
if !self.access_mode.writable() {
|
||||
return_errno!(EACCES, "File not writable. Can't set len.");
|
||||
|
@ -537,3 +537,19 @@ pub fn do_mount_rootfs(
|
||||
fs_ops::do_mount_rootfs(&user_config, &key)?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn do_fallocate(fd: FileDesc, mode: u32, offset: off_t, len: off_t) -> Result<isize> {
|
||||
if offset < 0 || len <= 0 {
|
||||
return_errno!(
|
||||
EINVAL,
|
||||
"offset was less than 0, or len was less than or equal to 0"
|
||||
);
|
||||
}
|
||||
// Current implementation is just the posix_fallocate
|
||||
// TODO: Support more modes in fallocate
|
||||
if mode != 0 {
|
||||
return_errno!(ENOSYS, "unsupported mode");
|
||||
}
|
||||
file_ops::do_fallocate(fd, mode, offset as u64, len as u64)?;
|
||||
Ok(0)
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ use util::mem_util::from_user::*;
|
||||
use crate::exception::do_handle_exception;
|
||||
use crate::fs::{
|
||||
do_access, do_chdir, do_chmod, do_chown, do_close, do_dup, do_dup2, do_dup3, do_eventfd,
|
||||
do_eventfd2, do_faccessat, do_fchmod, do_fchmodat, do_fchown, do_fchownat, do_fcntl,
|
||||
do_fdatasync, do_fstat, do_fstatat, do_fsync, do_ftruncate, do_getcwd, do_getdents,
|
||||
do_eventfd2, do_faccessat, do_fallocate, do_fchmod, do_fchmodat, do_fchown, do_fchownat,
|
||||
do_fcntl, do_fdatasync, do_fstat, do_fstatat, do_fsync, do_ftruncate, do_getcwd, do_getdents,
|
||||
do_getdents64, do_ioctl, do_lchown, do_link, do_linkat, do_lseek, do_lstat, do_mkdir,
|
||||
do_mkdirat, do_mount_rootfs, do_open, do_openat, do_pipe, do_pipe2, do_pread, do_pwrite,
|
||||
do_read, do_readlink, do_readlinkat, do_readv, do_rename, do_renameat, do_rmdir, do_sendfile,
|
||||
@ -369,7 +369,7 @@ macro_rules! process_syscall_table_with_callback {
|
||||
(Signalfd = 282) => handle_unsupported(),
|
||||
(TimerfdCreate = 283) => handle_unsupported(),
|
||||
(Eventfd = 284) => do_eventfd(init_val: u32),
|
||||
(Fallocate = 285) => handle_unsupported(),
|
||||
(Fallocate = 285) => do_fallocate(fd: FileDesc, mode: u32, offset: off_t, len: off_t),
|
||||
(TimerfdSettime = 286) => handle_unsupported(),
|
||||
(TimerfdGettime = 287) => handle_unsupported(),
|
||||
(Accept4 = 288) => do_accept4(fd: c_int, addr: *mut libc::sockaddr, addr_len: *mut libc::socklen_t, flags: c_int),
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <sys/uio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include "test_fs.h"
|
||||
|
||||
// ============================================================================
|
||||
@ -162,6 +163,46 @@ static int __test_lseek(const char *file_path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __test_posix_fallocate(const char *file_path) {
|
||||
int fd = open(file_path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
THROW_ERROR("failed to open a file to read/write");
|
||||
}
|
||||
off_t offset = -1;
|
||||
off_t len = 100;
|
||||
if (posix_fallocate(fd, offset, len) != EINVAL) {
|
||||
THROW_ERROR("failed to call posix_fallocate with invalid offset");
|
||||
}
|
||||
offset = 16;
|
||||
len = 0;
|
||||
if (posix_fallocate(fd, offset, len) != EINVAL) {
|
||||
THROW_ERROR("failed to call posix_fallocate with invalid len");
|
||||
}
|
||||
len = 48;
|
||||
if (posix_fallocate(fd, offset, len) != 0) {
|
||||
THROW_ERROR("failed to call posix_fallocate");
|
||||
}
|
||||
struct stat stat_buf;
|
||||
if (fstat(fd, &stat_buf) < 0) {
|
||||
THROW_ERROR("failed to stat file");
|
||||
}
|
||||
if (stat_buf.st_size < offset + len) {
|
||||
THROW_ERROR("failed to check the len after posix_fallocate");
|
||||
}
|
||||
|
||||
char *read_buf = malloc(stat_buf.st_size);
|
||||
if (read_buf == NULL) {
|
||||
THROW_ERROR("failed to malloc buf to read");
|
||||
}
|
||||
if (read(fd, read_buf, stat_buf.st_size) != stat_buf.st_size) {
|
||||
THROW_ERROR("failed to read correct size of fallocated file");
|
||||
}
|
||||
|
||||
free(read_buf);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int(*test_file_func_t)(const char *);
|
||||
|
||||
static int test_file_framework(test_file_func_t fn) {
|
||||
@ -195,6 +236,10 @@ static int test_lseek() {
|
||||
return test_file_framework(__test_lseek);
|
||||
}
|
||||
|
||||
static int test_posix_fallocate() {
|
||||
return test_file_framework(__test_posix_fallocate);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test suite main
|
||||
// ============================================================================
|
||||
@ -204,6 +249,7 @@ static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_pwrite_pread),
|
||||
TEST_CASE(test_writev_readv),
|
||||
TEST_CASE(test_lseek),
|
||||
TEST_CASE(test_posix_fallocate),
|
||||
};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
Loading…
Reference in New Issue
Block a user