Serenity Operating System
at master 99 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/FileSystem/Inode.h> 8#include <Kernel/Memory/InodeVMObject.h> 9 10namespace Kernel::Memory { 11 12InodeVMObject::InodeVMObject(Inode& inode, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, Bitmap dirty_pages) 13 : VMObject(move(new_physical_pages)) 14 , m_inode(inode) 15 , m_dirty_pages(move(dirty_pages)) 16{ 17} 18 19InodeVMObject::InodeVMObject(InodeVMObject const& other, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, Bitmap dirty_pages) 20 : VMObject(move(new_physical_pages)) 21 , m_inode(other.m_inode) 22 , m_dirty_pages(move(dirty_pages)) 23{ 24 for (size_t i = 0; i < page_count(); ++i) 25 m_dirty_pages.set(i, other.m_dirty_pages.get(i)); 26} 27 28InodeVMObject::~InodeVMObject() = default; 29 30size_t InodeVMObject::amount_clean() const 31{ 32 size_t count = 0; 33 VERIFY(page_count() == m_dirty_pages.size()); 34 for (size_t i = 0; i < page_count(); ++i) { 35 if (!m_dirty_pages.get(i) && m_physical_pages[i]) 36 ++count; 37 } 38 return count * PAGE_SIZE; 39} 40 41size_t InodeVMObject::amount_dirty() const 42{ 43 size_t count = 0; 44 for (size_t i = 0; i < m_dirty_pages.size(); ++i) { 45 if (m_dirty_pages.get(i)) 46 ++count; 47 } 48 return count * PAGE_SIZE; 49} 50 51int InodeVMObject::release_all_clean_pages() 52{ 53 SpinlockLocker locker(m_lock); 54 55 int count = 0; 56 for (size_t i = 0; i < page_count(); ++i) { 57 if (!m_dirty_pages.get(i) && m_physical_pages[i]) { 58 m_physical_pages[i] = nullptr; 59 ++count; 60 } 61 } 62 if (count) { 63 for_each_region([](auto& region) { 64 region.remap(); 65 }); 66 } 67 return count; 68} 69 70int InodeVMObject::try_release_clean_pages(int page_amount) 71{ 72 SpinlockLocker locker(m_lock); 73 74 int count = 0; 75 for (size_t i = 0; i < page_count() && count < page_amount; ++i) { 76 if (!m_dirty_pages.get(i) && m_physical_pages[i]) { 77 m_physical_pages[i] = nullptr; 78 ++count; 79 } 80 } 81 if (count) { 82 for_each_region([](auto& region) { 83 region.remap(); 84 }); 85 } 86 return count; 87} 88 89u32 InodeVMObject::writable_mappings() const 90{ 91 u32 count = 0; 92 const_cast<InodeVMObject&>(*this).for_each_region([&](auto& region) { 93 if (region.is_writable()) 94 ++count; 95 }); 96 return count; 97} 98 99}