Add posix_fallocate

This commit is contained in:
LI Qing 2021-02-05 14:58:11 +08:00 committed by Zongmin.Gu
parent a789871d93
commit be62e2c65d
9 changed files with 89 additions and 4 deletions

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::NoIntegrity => EIO,
FsError::PermError => EPERM, FsError::PermError => EPERM,
FsError::NameTooLong => ENAMETOOLONG, FsError::NameTooLong => ENAMETOOLONG,
FsError::FileTooBig => EFBIG,
} }
} }
} }

@ -91,6 +91,10 @@ pub trait File: Debug + Sync + Send + Any {
return_op_unsupported_error!("set_advisory_lock") 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 // TODO: remove this function after all users of this code are removed
fn poll(&self) -> Result<(crate::net::PollEventFlags)> { fn poll(&self) -> Result<(crate::net::PollEventFlags)> {
return_op_unsupported_error!("poll") return_op_unsupported_error!("poll")

@ -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::close::do_close;
pub use self::dirent::{do_getdents, do_getdents64}; pub use self::dirent::{do_getdents, do_getdents64};
pub use self::dup::{do_dup, do_dup2, do_dup3}; 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::fcntl::{do_fcntl, FcntlCmd};
pub use self::file_flags::{AccessMode, CreationFlags, StatusFlags}; pub use self::file_flags::{AccessMode, CreationFlags, StatusFlags};
pub use self::flock::{Flock, FlockType}; pub use self::flock::{Flock, FlockType};
@ -36,6 +37,7 @@ mod chown;
mod close; mod close;
mod dirent; mod dirent;
mod dup; mod dup;
mod fallocate;
mod fcntl; mod fcntl;
mod file_flags; mod file_flags;
mod flock; mod flock;

@ -121,6 +121,11 @@ impl File for INodeFile {
Ok(()) 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<()> { fn set_len(&self, len: u64) -> Result<()> {
if !self.access_mode.writable() { if !self.access_mode.writable() {
return_errno!(EACCES, "File not writable. Can't set len."); 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)?; fs_ops::do_mount_rootfs(&user_config, &key)?;
Ok(0) 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::exception::do_handle_exception;
use crate::fs::{ use crate::fs::{
do_access, do_chdir, do_chmod, do_chown, do_close, do_dup, do_dup2, do_dup3, do_eventfd, 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_eventfd2, do_faccessat, do_fallocate, do_fchmod, do_fchmodat, do_fchown, do_fchownat,
do_fdatasync, do_fstat, do_fstatat, do_fsync, do_ftruncate, do_getcwd, do_getdents, 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_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_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, 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(), (Signalfd = 282) => handle_unsupported(),
(TimerfdCreate = 283) => handle_unsupported(), (TimerfdCreate = 283) => handle_unsupported(),
(Eventfd = 284) => do_eventfd(init_val: u32), (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(), (TimerfdSettime = 286) => handle_unsupported(),
(TimerfdGettime = 287) => 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), (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 <sys/uio.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h>
#include "test_fs.h" #include "test_fs.h"
// ============================================================================ // ============================================================================
@ -162,6 +163,46 @@ static int __test_lseek(const char *file_path) {
return 0; 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 *); typedef int(*test_file_func_t)(const char *);
static int test_file_framework(test_file_func_t fn) { static int test_file_framework(test_file_func_t fn) {
@ -195,6 +236,10 @@ static int test_lseek() {
return test_file_framework(__test_lseek); return test_file_framework(__test_lseek);
} }
static int test_posix_fallocate() {
return test_file_framework(__test_posix_fallocate);
}
// ============================================================================ // ============================================================================
// Test suite main // Test suite main
// ============================================================================ // ============================================================================
@ -204,6 +249,7 @@ static test_case_t test_cases[] = {
TEST_CASE(test_pwrite_pread), TEST_CASE(test_pwrite_pread),
TEST_CASE(test_writev_readv), TEST_CASE(test_writev_readv),
TEST_CASE(test_lseek), TEST_CASE(test_lseek),
TEST_CASE(test_posix_fallocate),
}; };
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {