summaryrefslogtreecommitdiff
path: root/Kernel/Memory
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-11-17 19:33:00 +0100
committerAndreas Kling <kling@serenityos.org>2021-11-17 19:34:15 +0100
commit32aa37d5dcfedf90a14696a5a6eec76bc029cffa (patch)
tree61b36cab4480b36db74d6b9f4038b10ffa36a3a8 /Kernel/Memory
parentf2d5548d7a46d054f5015e29e90995a70106dc19 (diff)
downloadserenity-32aa37d5dcfedf90a14696a5a6eec76bc029cffa.zip
Kernel+LibC: Add msync() system call
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. :^)
Diffstat (limited to 'Kernel/Memory')
-rw-r--r--Kernel/Memory/SharedInodeVMObject.cpp19
-rw-r--r--Kernel/Memory/SharedInodeVMObject.h2
2 files changed, 21 insertions, 0 deletions
diff --git a/Kernel/Memory/SharedInodeVMObject.cpp b/Kernel/Memory/SharedInodeVMObject.cpp
index 605af54e18..15ad1c39e2 100644
--- a/Kernel/Memory/SharedInodeVMObject.cpp
+++ b/Kernel/Memory/SharedInodeVMObject.cpp
@@ -5,6 +5,7 @@
*/
#include <Kernel/FileSystem/Inode.h>
+#include <Kernel/Locking/Spinlock.h>
#include <Kernel/Memory/SharedInodeVMObject.h>
namespace Kernel::Memory {
@@ -34,4 +35,22 @@ SharedInodeVMObject::SharedInodeVMObject(SharedInodeVMObject const& 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 {};
+}
+
}
diff --git a/Kernel/Memory/SharedInodeVMObject.h b/Kernel/Memory/SharedInodeVMObject.h
index c596addbf9..81d6a93ca0 100644
--- a/Kernel/Memory/SharedInodeVMObject.h
+++ b/Kernel/Memory/SharedInodeVMObject.h
@@ -18,6 +18,8 @@ public:
static ErrorOr<NonnullRefPtr<SharedInodeVMObject>> try_create_with_inode(Inode&);
virtual ErrorOr<NonnullRefPtr<VMObject>> try_clone() override;
+ ErrorOr<void> sync();
+
private:
virtual bool is_shared_inode() const override { return true; }