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.
This commit is contained in:
		
							parent
							
								
									b924c85669
								
							
						
					
					
						commit
						05e57801e7
					
				|  | @ -2,6 +2,7 @@ | |||
| 
 | ||||
| #include <kernel/Device/Device.h> | ||||
| #include <kernel/FS/RamFS/FileSystem.h> | ||||
| #include <kernel/Semaphore.h> | ||||
| 
 | ||||
| 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 }; | ||||
| 	}; | ||||
| 
 | ||||
| } | ||||
|  | @ -109,7 +109,7 @@ namespace Kernel | |||
| 		BAN::ErrorOr<long> sys_fstatat(int fd, const char* path, struct stat* buf, int flag); | ||||
| 		BAN::ErrorOr<long> sys_stat(const char* path, struct stat* buf, int flag); | ||||
| 
 | ||||
| 		BAN::ErrorOr<long> sys_sync(); | ||||
| 		BAN::ErrorOr<long> sys_sync(bool should_block); | ||||
| 
 | ||||
| 		BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target); | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <kernel/FS/RamFS/Inode.h> | ||||
| #include <kernel/LockGuard.h> | ||||
| #include <kernel/Process.h> | ||||
| #include <kernel/Storage/StorageDevice.h> | ||||
| #include <kernel/Timer/Timer.h> | ||||
| 
 | ||||
| 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<RamInode> 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<RamInode> device) | ||||
|  |  | |||
|  | @ -767,22 +767,10 @@ namespace Kernel | |||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<long> Process::sys_sync() | ||||
| 	BAN::ErrorOr<long> Process::sys_sync(bool should_block) | ||||
| 	{ | ||||
| 		BAN::ErrorOr<long> 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<long> Process::sys_read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size) | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue