mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-09 08:40:44 +00:00
Add a VMO pointer to VNode.
This way, if anyone tries to map an already mapped file, we share the VMO.
This commit is contained in:
parent
862f108cb5
commit
3b2dcd5929
|
@ -87,7 +87,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CallableType>
|
template<typename CallableType>
|
||||||
class CallableWrapper : public CallableWrapperBase {
|
class CallableWrapper final : public CallableWrapperBase {
|
||||||
public:
|
public:
|
||||||
explicit CallableWrapper(CallableType&& callable)
|
explicit CallableWrapper(CallableType&& callable)
|
||||||
: m_callable(move(callable))
|
: m_callable(move(callable))
|
||||||
|
|
|
@ -28,9 +28,10 @@ inline T max(const T& a, const T& b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename U>
|
||||||
static inline T ceilDiv(T a, T b)
|
static inline T ceilDiv(T a, U b)
|
||||||
{
|
{
|
||||||
|
static_assert(sizeof(T) == sizeof(U));
|
||||||
T result = a / b;
|
T result = a / b;
|
||||||
if ((a % b) != 0)
|
if ((a % b) != 0)
|
||||||
++result;
|
++result;
|
||||||
|
|
|
@ -220,8 +220,7 @@ Region* MemoryManager::region_from_laddr(Process& process, LinearAddress laddr)
|
||||||
return region.ptr();
|
return region.ptr();
|
||||||
}
|
}
|
||||||
kprintf("%s(%u) Couldn't find region for L%x\n", process.name().characters(), process.pid(), laddr.get());
|
kprintf("%s(%u) Couldn't find region for L%x\n", process.name().characters(), process.pid(), laddr.get());
|
||||||
process.dumpRegions();
|
return nullptr;
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryManager::copy_on_write(Process& process, Region& region, unsigned page_index_in_region)
|
bool MemoryManager::copy_on_write(Process& process, Region& region, unsigned page_index_in_region)
|
||||||
|
@ -292,7 +291,10 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
|
||||||
dbgprintf("MM: handle_page_fault(%w) at L%x\n", fault.code(), fault.laddr().get());
|
dbgprintf("MM: handle_page_fault(%w) at L%x\n", fault.code(), fault.laddr().get());
|
||||||
#endif
|
#endif
|
||||||
auto* region = region_from_laddr(*current, fault.laddr());
|
auto* region = region_from_laddr(*current, fault.laddr());
|
||||||
ASSERT(region);
|
if (!region) {
|
||||||
|
kprintf("NP(error) fault at invalid address L%x\n", fault.laddr().get());
|
||||||
|
return PageFaultResponse::ShouldCrash;
|
||||||
|
}
|
||||||
auto page_index_in_region = region->page_index_from_address(fault.laddr());
|
auto page_index_in_region = region->page_index_from_address(fault.laddr());
|
||||||
if (fault.is_not_present()) {
|
if (fault.is_not_present()) {
|
||||||
if (region->vmo().vnode()) {
|
if (region->vmo().vnode()) {
|
||||||
|
@ -640,7 +642,12 @@ void PhysicalPage::return_to_freelist()
|
||||||
|
|
||||||
RetainPtr<VMObject> VMObject::create_file_backed(RetainPtr<VirtualFileSystem::Node>&& vnode, size_t size)
|
RetainPtr<VMObject> VMObject::create_file_backed(RetainPtr<VirtualFileSystem::Node>&& vnode, size_t size)
|
||||||
{
|
{
|
||||||
return adopt(*new VMObject(move(vnode), size));
|
InterruptDisabler disabler;
|
||||||
|
if (vnode->vmo())
|
||||||
|
return static_cast<VMObject*>(vnode->vmo());
|
||||||
|
auto vmo = adopt(*new VMObject(move(vnode), size));
|
||||||
|
vmo->vnode()->set_vmo(vmo.ptr());
|
||||||
|
return vmo;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetainPtr<VMObject> VMObject::create_anonymous(size_t size)
|
RetainPtr<VMObject> VMObject::create_anonymous(size_t size)
|
||||||
|
@ -679,6 +686,11 @@ VMObject::VMObject(RetainPtr<VirtualFileSystem::Node>&& vnode, size_t size)
|
||||||
|
|
||||||
VMObject::~VMObject()
|
VMObject::~VMObject()
|
||||||
{
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
if (m_vnode) {
|
||||||
|
ASSERT(m_vnode->vmo() == this);
|
||||||
|
m_vnode->set_vmo(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Region::commit(Process& process)
|
int Region::commit(Process& process)
|
||||||
|
|
|
@ -49,7 +49,7 @@ ByteBuffer procfs$pid_vm(Process& process)
|
||||||
{
|
{
|
||||||
ProcessInspectionScope scope(process);
|
ProcessInspectionScope scope(process);
|
||||||
char* buffer;
|
char* buffer;
|
||||||
auto stringImpl = StringImpl::createUninitialized(80 + process.regionCount() * 80 + 4096, buffer);
|
auto stringImpl = StringImpl::createUninitialized(80 + process.regionCount() * 160 + 4096, buffer);
|
||||||
memset(buffer, 0, stringImpl->length());
|
memset(buffer, 0, stringImpl->length());
|
||||||
char* ptr = buffer;
|
char* ptr = buffer;
|
||||||
ptr += ksprintf(ptr, "BEGIN END SIZE NAME\n");
|
ptr += ksprintf(ptr, "BEGIN END SIZE NAME\n");
|
||||||
|
@ -59,12 +59,17 @@ ByteBuffer procfs$pid_vm(Process& process)
|
||||||
region->linearAddress.offset(region->size - 1).get(),
|
region->linearAddress.offset(region->size - 1).get(),
|
||||||
region->size,
|
region->size,
|
||||||
region->name.characters());
|
region->name.characters());
|
||||||
|
ptr += ksprintf(ptr, "VMO: %s \"%s\" @ %x(%u)\n",
|
||||||
|
region->vmo().is_anonymous() ? "anonymous" : "file-backed",
|
||||||
|
region->vmo().name().characters(),
|
||||||
|
®ion->vmo(),
|
||||||
|
region->vmo().retainCount());
|
||||||
for (size_t i = 0; i < region->vmo().page_count(); ++i) {
|
for (size_t i = 0; i < region->vmo().page_count(); ++i) {
|
||||||
auto& physical_page = region->vmo().physical_pages()[i];
|
auto& physical_page = region->vmo().physical_pages()[i];
|
||||||
ptr += ksprintf(ptr, "P%x%s(%u) ",
|
ptr += ksprintf(ptr, "P%x%s(%u) ",
|
||||||
physical_page ? physical_page->paddr().get() : 0,
|
physical_page ? physical_page->paddr().get() : 0,
|
||||||
region->cow_map.get(i) ? "!" : "",
|
region->cow_map.get(i) ? "!" : "",
|
||||||
physical_page->retain_count()
|
physical_page ? physical_page->retain_count() : 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ptr += ksprintf(ptr, "\n");
|
ptr += ksprintf(ptr, "\n");
|
||||||
|
|
|
@ -296,7 +296,6 @@ void init()
|
||||||
procfs->initialize();
|
procfs->initialize();
|
||||||
|
|
||||||
Process::initialize();
|
Process::initialize();
|
||||||
|
|
||||||
Process::create_kernel_process(init_stage2, "init_stage2");
|
Process::create_kernel_process(init_stage2, "init_stage2");
|
||||||
|
|
||||||
Scheduler::pick_next();
|
Scheduler::pick_next();
|
||||||
|
|
|
@ -139,6 +139,27 @@ close_it:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sh_mp(int, const char**)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int fd = open("/kernel.map", O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("open(/kernel.map)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("opened /kernel.map, calling mmap...\n");
|
||||||
|
byte* data = (byte*)mmap(nullptr, getpagesize() * 10, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
if (data == MAP_FAILED) {
|
||||||
|
perror("mmap()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("mapped file @ %p\n", data);
|
||||||
|
printf("contents: %c%c%c%c%c%c%c...\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
|
||||||
|
|
||||||
|
printf("leaving it open :)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sh_exit(int, const char**)
|
static int sh_exit(int, const char**)
|
||||||
{
|
{
|
||||||
printf("Good-bye!\n");
|
printf("Good-bye!\n");
|
||||||
|
@ -221,6 +242,10 @@ static bool handle_builtin(int argc, const char** argv, int& retval)
|
||||||
retval = sh_mf(argc, argv);
|
retval = sh_mf(argc, argv);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(argv[0], "mp")) {
|
||||||
|
retval = sh_mp(argc, argv);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!strcmp(argv[0], "fork")) {
|
if (!strcmp(argv[0], "fork")) {
|
||||||
retval = sh_fork(argc, argv);
|
retval = sh_fork(argc, argv);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -180,6 +180,7 @@ auto VirtualFileSystem::allocateNode() -> RetainPtr<Node>
|
||||||
ASSERT(node->retainCount == 0);
|
ASSERT(node->retainCount == 0);
|
||||||
node->retainCount = 1;
|
node->retainCount = 1;
|
||||||
node->m_vfs = this;
|
node->m_vfs = this;
|
||||||
|
node->m_vmo = nullptr;
|
||||||
return adopt(*node);
|
return adopt(*node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +198,8 @@ void VirtualFileSystem::freeNode(Node* node)
|
||||||
m_device2vnode.remove(encodedDevice(node->m_characterDevice->major(), node->m_characterDevice->minor()));
|
m_device2vnode.remove(encodedDevice(node->m_characterDevice->major(), node->m_characterDevice->minor()));
|
||||||
node->m_characterDevice = nullptr;
|
node->m_characterDevice = nullptr;
|
||||||
}
|
}
|
||||||
|
node->m_vfs = nullptr;
|
||||||
|
node->m_vmo = nullptr;
|
||||||
m_nodeFreeList.append(move(node));
|
m_nodeFreeList.append(move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,16 @@ public:
|
||||||
VirtualFileSystem* vfs() { return m_vfs; }
|
VirtualFileSystem* vfs() { return m_vfs; }
|
||||||
const VirtualFileSystem* vfs() const { return m_vfs; }
|
const VirtualFileSystem* vfs() const { return m_vfs; }
|
||||||
|
|
||||||
|
void* vmo() { return m_vmo; }
|
||||||
|
void set_vmo(void* vmo) { m_vmo = vmo; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class VirtualFileSystem;
|
friend class VirtualFileSystem;
|
||||||
VirtualFileSystem* m_vfs { nullptr };
|
VirtualFileSystem* m_vfs { nullptr };
|
||||||
unsigned retainCount { 0 };
|
unsigned retainCount { 0 };
|
||||||
CharacterDevice* m_characterDevice { nullptr };
|
CharacterDevice* m_characterDevice { nullptr };
|
||||||
mutable InodeMetadata m_cachedMetadata;
|
mutable InodeMetadata m_cachedMetadata;
|
||||||
|
void* m_vmo { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
static VirtualFileSystem& the() PURE;
|
static VirtualFileSystem& the() PURE;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user