mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-23 08:00:20 +00:00
32aa37d5dc
This allows userspace to trigger a full (FIXME) flush of a shared file mapping to disk. We iterate over all the mapped pages in the VMObject and write them out to the underlying inode, one by one. This is rather naive, and there's lots of room for improvement. Note that shared file mappings are currently not possible since mmap() returns ENOTSUP for PROT_WRITE+MAP_SHARED. That restriction will be removed in a subsequent commit. :^)
56 lines
1.5 KiB
C++
56 lines
1.5 KiB
C++
/*
|
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/FileSystem/Inode.h>
|
|
#include <Kernel/Locking/Spinlock.h>
|
|
#include <Kernel/Memory/SharedInodeVMObject.h>
|
|
|
|
namespace Kernel::Memory {
|
|
|
|
ErrorOr<NonnullRefPtr<SharedInodeVMObject>> SharedInodeVMObject::try_create_with_inode(Inode& inode)
|
|
{
|
|
size_t size = inode.size();
|
|
if (auto shared_vmobject = inode.shared_vmobject())
|
|
return shared_vmobject.release_nonnull();
|
|
auto vmobject = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SharedInodeVMObject(inode, size)));
|
|
vmobject->inode().set_shared_vmobject(*vmobject);
|
|
return vmobject;
|
|
}
|
|
|
|
ErrorOr<NonnullRefPtr<VMObject>> SharedInodeVMObject::try_clone()
|
|
{
|
|
return adopt_nonnull_ref_or_enomem<VMObject>(new (nothrow) SharedInodeVMObject(*this));
|
|
}
|
|
|
|
SharedInodeVMObject::SharedInodeVMObject(Inode& inode, size_t size)
|
|
: InodeVMObject(inode, size)
|
|
{
|
|
}
|
|
|
|
SharedInodeVMObject::SharedInodeVMObject(SharedInodeVMObject const& other)
|
|
: InodeVMObject(other)
|
|
{
|
|
}
|
|
|
|
ErrorOr<void> SharedInodeVMObject::sync()
|
|
{
|
|
SpinlockLocker locker(m_lock);
|
|
|
|
for (size_t page_index = 0; page_index < page_count(); ++page_index) {
|
|
auto& physical_page = m_physical_pages[page_index];
|
|
if (!physical_page)
|
|
continue;
|
|
|
|
u8 page_buffer[PAGE_SIZE];
|
|
MM.copy_physical_page(*physical_page, page_buffer);
|
|
|
|
TRY(m_inode->write_bytes(page_index * PAGE_SIZE, PAGE_SIZE, UserOrKernelBuffer::for_kernel_buffer(page_buffer), nullptr));
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
}
|