mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 21:08:12 +00:00
Kernel: Implement basic support for sys$mmap() with MAP_PRIVATE
You can now mmap a file as private and writable, and the changes you make will only be visible to you. This works because internally a MAP_PRIVATE region is backed by a unique PrivateInodeVMObject instead of using the globally shared SharedInodeVMObject like we always did before. :^) Fixes #1045.
This commit is contained in:
parent
aa1e209845
commit
8fbdda5a2d
11 changed files with 45 additions and 31 deletions
|
@ -54,7 +54,7 @@ int File::ioctl(FileDescription&, unsigned, unsigned)
|
|||
return -ENOTTY;
|
||||
}
|
||||
|
||||
KResultOr<Region*> File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int)
|
||||
KResultOr<Region*> File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int, bool)
|
||||
{
|
||||
return KResult(-ENODEV);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
virtual ssize_t read(FileDescription&, u8*, ssize_t) = 0;
|
||||
virtual ssize_t write(FileDescription&, const u8*, ssize_t) = 0;
|
||||
virtual int ioctl(FileDescription&, unsigned request, unsigned arg);
|
||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot);
|
||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);
|
||||
|
||||
virtual String absolute_path(const FileDescription&) const = 0;
|
||||
|
||||
|
|
|
@ -281,10 +281,10 @@ InodeMetadata FileDescription::metadata() const
|
|||
return {};
|
||||
}
|
||||
|
||||
KResultOr<Region*> FileDescription::mmap(Process& process, VirtualAddress vaddr, size_t offset, size_t size, int prot)
|
||||
KResultOr<Region*> FileDescription::mmap(Process& process, VirtualAddress vaddr, size_t offset, size_t size, int prot, bool shared)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
return m_file->mmap(process, *this, vaddr, offset, size, prot);
|
||||
return m_file->mmap(process, *this, vaddr, offset, size, prot, shared);
|
||||
}
|
||||
|
||||
KResult FileDescription::truncate(u64 length)
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
Custody* custody() { return m_custody.ptr(); }
|
||||
const Custody* custody() const { return m_custody.ptr(); }
|
||||
|
||||
KResultOr<Region*> mmap(Process&, VirtualAddress, size_t offset, size_t, int prot);
|
||||
KResultOr<Region*> mmap(Process&, VirtualAddress, size_t offset, size_t, int prot, bool shared);
|
||||
|
||||
bool is_blocking() const { return m_is_blocking; }
|
||||
void set_blocking(bool b) { m_is_blocking = b; }
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <Kernel/FileSystem/InodeFile.h>
|
||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||
#include <Kernel/Process.h>
|
||||
#include <Kernel/VM/PrivateInodeVMObject.h>
|
||||
#include <Kernel/VM/SharedInodeVMObject.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -60,11 +61,18 @@ ssize_t InodeFile::write(FileDescription& description, const u8* data, ssize_t c
|
|||
return nwritten;
|
||||
}
|
||||
|
||||
KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& description, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot)
|
||||
KResultOr<Region*> InodeFile::mmap(Process& process, FileDescription& description, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared)
|
||||
{
|
||||
ASSERT(offset == 0);
|
||||
// FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec.
|
||||
auto* region = process.allocate_region_with_vmobject(preferred_vaddr, size, SharedInodeVMObject::create_with_inode(inode()), offset, description.absolute_path(), prot);
|
||||
RefPtr<InodeVMObject> vmobject;
|
||||
if (shared)
|
||||
vmobject = SharedInodeVMObject::create_with_inode(inode());
|
||||
else
|
||||
vmobject = PrivateInodeVMObject::create_with_inode(inode());
|
||||
if (!vmobject)
|
||||
return KResult(-ENOMEM);
|
||||
auto* region = process.allocate_region_with_vmobject(preferred_vaddr, size, *vmobject, offset, description.absolute_path(), prot);
|
||||
if (!region)
|
||||
return KResult(-ENOMEM);
|
||||
return region;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
virtual ssize_t read(FileDescription&, u8*, ssize_t) override;
|
||||
virtual ssize_t write(FileDescription&, const u8*, ssize_t) override;
|
||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot) override;
|
||||
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override;
|
||||
|
||||
virtual String absolute_path(const FileDescription&) const override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue