From 05e57801e7cdd221362cf7903a64a2f70569e90b Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 27 Sep 2023 00:34:00 +0300 Subject: [PATCH] Kernel: SYS_SYNC now schedules sync to happen soon You can pass non-zero argument to the syscall to block until the sync has finished. --- kernel/include/kernel/FS/DevFS/FileSystem.h | 7 +++ kernel/include/kernel/Process.h | 2 +- kernel/kernel/FS/DevFS/FileSystem.cpp | 62 +++++++++++++++++++++ kernel/kernel/Process.cpp | 18 +----- kernel/kernel/Syscall.cpp | 2 +- 5 files changed, 74 insertions(+), 17 deletions(-) diff --git a/kernel/include/kernel/FS/DevFS/FileSystem.h b/kernel/include/kernel/FS/DevFS/FileSystem.h index ae10e2c799..4006bc98d2 100644 --- a/kernel/include/kernel/FS/DevFS/FileSystem.h +++ b/kernel/include/kernel/FS/DevFS/FileSystem.h @@ -2,6 +2,7 @@ #include #include +#include namespace Kernel { @@ -19,6 +20,8 @@ namespace Kernel dev_t get_next_dev(); + void initiate_sync(bool should_block); + private: DevFileSystem(size_t size) : RamFileSystem(size) @@ -26,6 +29,10 @@ namespace Kernel private: SpinLock m_device_lock; + + Semaphore m_sync_done; + Semaphore m_sync_semaphore; + volatile bool m_should_sync { false }; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 532e961384..62e6de54ce 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -109,7 +109,7 @@ namespace Kernel BAN::ErrorOr sys_fstatat(int fd, const char* path, struct stat* buf, int flag); BAN::ErrorOr sys_stat(const char* path, struct stat* buf, int flag); - BAN::ErrorOr sys_sync(); + BAN::ErrorOr sys_sync(bool should_block); BAN::ErrorOr mount(BAN::StringView source, BAN::StringView target); diff --git a/kernel/kernel/FS/DevFS/FileSystem.cpp b/kernel/kernel/FS/DevFS/FileSystem.cpp index cb9b8199d8..db4d64ac47 100644 --- a/kernel/kernel/FS/DevFS/FileSystem.cpp +++ b/kernel/kernel/FS/DevFS/FileSystem.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace Kernel @@ -53,6 +54,67 @@ namespace Kernel } }, nullptr ); + + auto* sync_process = Process::create_kernel(); + + sync_process->add_thread(MUST(Thread::create_kernel( + [](void*) + { + // NOTE: we lock the device lock here and unlock + // it only while semaphore is blocking + s_instance->m_device_lock.lock(); + + while (true) + { + while (!s_instance->m_should_sync) + { + s_instance->m_device_lock.unlock(); + s_instance->m_sync_semaphore.block(); + s_instance->m_device_lock.lock(); + } + + s_instance->for_each_inode( + [](BAN::RefPtr inode) + { + if (inode->is_device()) + if (((Device*)inode.ptr())->is_storage_device()) + if (auto ret = ((StorageDevice*)inode.ptr())->sync_disk_cache(); ret.is_error()) + dwarnln("disk sync: {}", ret.error()); + return BAN::Iteration::Continue; + } + ); + s_instance->m_should_sync = false; + s_instance->m_sync_done.unblock(); + } + }, nullptr, sync_process + ))); + + sync_process->add_thread(MUST(Kernel::Thread::create_kernel( + [](void*) + { + while (true) + { + SystemTimer::get().sleep(10000); + + LockGuard _(s_instance->m_device_lock); + s_instance->m_should_sync = true; + s_instance->m_sync_semaphore.unblock(); + } + }, nullptr, sync_process + ))); + + sync_process->register_to_scheduler(); + } + + void DevFileSystem::initiate_sync(bool should_block) + { + { + LockGuard _(m_device_lock); + m_should_sync = true; + m_sync_semaphore.unblock(); + } + if (should_block) + m_sync_done.block(); } void DevFileSystem::add_device(BAN::StringView path, BAN::RefPtr device) diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 64334ffb91..47149c5b22 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -767,22 +767,10 @@ namespace Kernel return 0; } - BAN::ErrorOr Process::sys_sync() + BAN::ErrorOr Process::sys_sync(bool should_block) { - BAN::ErrorOr ret = 0; - DevFileSystem::get().for_each_device( - [&](Device* device) - { - if (device->is_storage_device()) - { - auto success = ((StorageDevice*)device)->sync_disk_cache(); - if (success.is_error()) - ret = success.release_error(); - } - return BAN::Iteration::Continue; - } - ); - return ret; + DevFileSystem::get().initiate_sync(should_block); + return 0; } BAN::ErrorOr Process::sys_read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size) diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index d4114ca56f..f48f0ee53b 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -185,7 +185,7 @@ namespace Kernel ret = Process::current().sys_stat((const char*)arg1, (struct stat*)arg2, (int)arg3); break; case SYS_SYNC: - ret = Process::current().sys_sync(); + ret = Process::current().sys_sync((bool)arg1); break; case SYS_MMAP: ret = Process::current().sys_mmap((const sys_mmap_t*)arg1);