Skip to content
13 changes: 12 additions & 1 deletion os/StarryOS/kernel/src/syscall/fs/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,19 @@ pub fn sys_fdatasync(fd: c_int) -> AxResult<isize> {
Err(AxError::from(LinuxError::EINVAL))
}

pub fn sys_sync_file_range(fd: c_int, _offset: i64, _nbytes: i64, _flags: u32) -> AxResult<isize> {
pub fn sys_sync_file_range(fd: c_int, offset: i64, nbytes: i64, flags: u32) -> AxResult<isize> {
debug!("sys_sync_file_range <= fd: {fd}");
const SYNC_FILE_RANGE_WAIT_BEFORE: u32 = 1;
const SYNC_FILE_RANGE_WRITE: u32 = 2;
const SYNC_FILE_RANGE_WAIT_AFTER: u32 = 4;
const SYNC_FILE_RANGE_ALL: u32 =
SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER;
if offset < 0 || nbytes < 0 {
return Err(AxError::from(LinuxError::EINVAL));
}
if flags == 0 || (flags & !SYNC_FILE_RANGE_ALL) != 0 {
Comment thread
date727 marked this conversation as resolved.
Outdated
return Err(AxError::from(LinuxError::EINVAL));
}
// sync_file_range(2) is an advisory hint to initiate writeback for a
// byte range. Until range-based writeback is implemented, keep this as
// a no-op after basic fd validation rather than turning it into a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
* 测试文件系统修复:
* 1. fsync 对目录 fd 应返回成功 (Linux 允许)
* 2. fdatasync 对目录 fd 应返回成功
* 3. sync_file_range 应返回成功 (建议性优化)
* 3. 非法 fd 应返回 EBADF
* 4. pipe fd 应返回 EINVAL
* 5. socket fd 应返回 EINVAL
* 6. sync_file_range 应返回成功 (建议性优化)
*/

#include "test_framework.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>

int main(void)
{
Expand Down Expand Up @@ -40,7 +45,41 @@ int main(void)
unlink("/tmp/starry_fsync_test/file");
}

/* Test 3: sync_file_range */
/* Test 3: invalid fd handling */
{
CHECK_ERR(fsync(-1), EBADF, "fsync on invalid fd -> EBADF");
CHECK_ERR(fdatasync(-1), EBADF, "fdatasync on invalid fd -> EBADF");
}

/* Test 4: fsync on pipe -> EINVAL (Linux behavior) */
{
int pfd[2];
CHECK(pipe(pfd) == 0, "create pipe for fsync EINVAL");
if (pfd[0] >= 0) {
CHECK_ERR(fsync(pfd[0]), EINVAL, "fsync on pipe -> EINVAL");
CHECK_ERR(fdatasync(pfd[0]), EINVAL, "fdatasync on pipe -> EINVAL");
close(pfd[0]);
}
if (pfd[1] >= 0) {
close(pfd[1]);
}
}

/* Test 5: fsync on socket -> EINVAL (Linux behavior) */
{
int sfd[2];
CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd) == 0, "create socketpair for fsync EINVAL");
if (sfd[0] >= 0) {
CHECK_ERR(fsync(sfd[0]), EINVAL, "fsync on socket -> EINVAL");
CHECK_ERR(fdatasync(sfd[0]), EINVAL, "fdatasync on socket -> EINVAL");
close(sfd[0]);
}
if (sfd[1] >= 0) {
close(sfd[1]);
}
}

/* Test 6: sync_file_range */
{
int fd = open("/tmp/starry_fsync_test/sfrfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
CHECK(fd >= 0, "create file for sync_file_range");
Expand All @@ -50,6 +89,10 @@ int main(void)
* SYNC_FILE_RANGE_WRITE = 2 */
long rc = syscall(SYS_sync_file_range, fd, 0, 29, 2);
CHECK(rc == 0, "sync_file_range returns 0");
CHECK_ERR(syscall(SYS_sync_file_range, fd, 0, 29, 0x8000), EINVAL,
"sync_file_range invalid flags -> EINVAL");
CHECK_ERR(syscall(SYS_sync_file_range, fd, (off_t)-1, 29, 2), EINVAL,
"sync_file_range negative offset -> EINVAL");
close(fd);
unlink("/tmp/starry_fsync_test/sfrfile");
}
Expand Down