kernel: implement POSIX fsync through the shared file API

This commit is contained in:
nmzik
2026-10-18 20:15:53 +02:00
parent 831862a50b
commit 7675579e79
5 changed files with 56 additions and 10 deletions
+1 -1
View File
@@ -367,7 +367,7 @@ bool SysFileDeleteFile(const std::filesystem::path& name) {
bool SysFileFlush(sys_file_t& f) {
if (f.type == SYS_FILE_FILE && f.f != nullptr) {
return (fflush(f.f) == 0);
return fflush(f.f) == 0 && fsync(fileno(f.f)) == 0;
}
return false;
+21
View File
@@ -1326,6 +1326,27 @@ int KYTY_SYSV_ABI KernelFtruncate(int d, int64_t length) {
return OK;
}
int KYTY_SYSV_ABI KernelFsync(int d) {
PRINT_NAME();
if (d < DESCRIPTOR_MIN) {
return KERNEL_ERROR_EBADF;
}
auto* file = g_files->GetFile(d);
if (file == nullptr || !file->opened) {
return KERNEL_ERROR_EBADF;
}
Common::LockGuard lock(file->mutex);
if (file->f.IsInvalid() || !file->f.Flush()) {
return KERNEL_ERROR_EIO;
}
LOGF("\tFsync: %s\n", Common::PathToString(file->real_name).c_str());
return OK;
}
int KYTY_SYSV_ABI KernelUnlink(const char* path) {
PRINT_NAME();
+1
View File
@@ -72,6 +72,7 @@ int KYTY_SYSV_ABI KernelStat(const char* path, FileStat* sb);
int KYTY_SYSV_ABI KernelFstat(int d, FileStat* sb);
int KYTY_SYSV_ABI KernelTruncate(const char* path, int64_t length);
int KYTY_SYSV_ABI KernelFtruncate(int d, int64_t length);
int KYTY_SYSV_ABI KernelFsync(int d);
int KYTY_SYSV_ABI KernelUnlink(const char* path);
int KYTY_SYSV_ABI KernelRename(const char* from, const char* to);
int KYTY_SYSV_ABI KernelGetdirentries(int fd, char* buf, int nbytes, int64_t* basep);
+8 -9
View File
@@ -1341,14 +1341,6 @@ static int KYTY_SYSV_ABI KernelGetOperationMode(int* mode, int* submode) {
return OK;
}
static int KYTY_SYSV_ABI KernelFsync(int fd) {
PRINT_NAME();
LOGF("\t fd = %d\n", fd);
return OK;
}
static void KYTY_SYSV_ABI KernelSync() {
PRINT_NAME();
}
@@ -1986,6 +1978,12 @@ int KYTY_SYSV_ABI ftruncate(int d, int64_t length) {
return POSIX_CALL(LibKernel::FileSystem::KernelFtruncate(d, length));
}
int KYTY_SYSV_ABI fsync(int d) {
PRINT_NAME();
return POSIX_CALL(LibKernel::FileSystem::KernelFsync(d));
}
int KYTY_SYSV_ABI socket(int family, int type, int protocol) {
PRINT_NAME();
return Network::Net::Socket(family, type, protocol);
@@ -2174,6 +2172,7 @@ LIB_DEFINE(InitLibKernel_1_Posix) {
LIB_FUNC("E6ao34wPw+U", stat);
LIB_FUNC("JGMio+21L4c", mkdir);
LIB_FUNC("ih4CD9-gghM", Posix::ftruncate);
LIB_FUNC("juWbTNM+8hw", Posix::fsync);
LIB_FUNC("8nY19bKoiZk", Posix::fcntl);
LIB_FUNC("pDuPEf3m4fI", Posix::sem_init);
LIB_FUNC("cDW233RAwWo", Posix::sem_destroy);
@@ -3394,7 +3393,7 @@ LIB_DEFINE(InitLibKernel_1) {
LIB_FUNC("959qrazPIrg", LibKernel::KernelGetProcParam);
LIB_FUNC("tU5e3f9gSiU", LibKernel::KernelIsTrinityMode);
LIB_FUNC("NH6xARDOVv8", LibKernel::KernelGetOperationMode);
LIB_FUNC("fTx66l5iWIA", LibKernel::KernelFsync);
LIB_FUNC("fTx66l5iWIA", FileSystem::KernelFsync);
LIB_FUNC("uvT2iYBBnkY", LibKernel::KernelSync);
LIB_FUNC("HoLVWNanBBc", LibKernel::getpid);
LIB_FUNC("9BcDykPmo1I", LibKernel::get_error_addr);
+25
View File
@@ -483,6 +483,27 @@ void TestSaveOpenVisibility() {
Check(FileSystem::KernelClose(truncated) == OK, "close truncated save file");
}
void TestFsync() {
Loader::SymbolDatabase symbols;
Libs::InitLibKernel_1(&symbols);
const auto* symbol = symbols.Find(
{"juWbTNM+8hw", "Posix", 1, "libkernel", 1, 1, Loader::SymbolType::Func});
Check(symbol != nullptr, "POSIX fsync export resolves");
const auto fsync = reinterpret_cast<int (KYTY_SYSV_ABI *)(int)>(symbol->vaddr);
Check(fsync(std::numeric_limits<int>::min()) == -1 &&
*Libs::Posix::GetErrorAddr() == Libs::Posix::POSIX_EBADF,
"invalid fsync descriptor reports POSIX EBADF");
constexpr char Path[] = "/savedata0/fsync.dat";
const int fd = FileSystem::KernelOpen(Path, 0x602, 0777);
Check(fd >= 3 && FileSystem::KernelWrite(fd, "save", 4) == 4 && fsync(fd) == OK &&
FileSystem::KernelLseek(fd, 0, 1) == 4,
"fsync flushes a writable file without changing its offset");
Check(FileSystem::KernelClose(fd) == OK && fsync(fd) == -1 &&
*Libs::Posix::GetErrorAddr() == Libs::Posix::POSIX_EBADF,
"closed fsync descriptor reports POSIX EBADF");
}
void TestSaveTruncate() {
namespace Kernel = Libs::LibKernel;
Loader::SymbolDatabase symbols;
@@ -973,6 +994,9 @@ void CheckArchiveMount(const std::filesystem::path &root) {
std::equal(bytes.begin(), bytes.begin() + 9, payload.end() - 9) &&
FileSystem::KernelRead(fd, bytes.data(), bytes.size()) == 0,
"archive reads stop at the member boundary");
Check(FileSystem::KernelFsync(fd) == OK &&
FileSystem::KernelLseek(fd, 0, 1) == payload.size(),
"fsync succeeds on an immutable archive member without changing its offset");
Check(FileSystem::KernelWrite(fd, bytes.data(), 1) ==
Libs::LibKernel::KERNEL_ERROR_EBADF &&
FileSystem::KernelPwrite(fd, bytes.data(), 1, 0) ==
@@ -2271,6 +2295,7 @@ int main(int, char**) {
CheckAprPaths(temporary.Path());
FileSystem::Mount(temporary.Path(), "/savedata0");
TestSaveOpenVisibility();
TestFsync();
TestSaveTruncate();
TestSaveWritev();
TestAioBatches();