InodeVMObject.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/FileSystem/Inode.h>
  7. #include <Kernel/Memory/InodeVMObject.h>
  8. namespace Kernel::Memory {
  9. InodeVMObject::InodeVMObject(Inode& inode, size_t size)
  10. : VMObject(size)
  11. , m_inode(inode)
  12. , m_dirty_pages(page_count(), false)
  13. {
  14. }
  15. InodeVMObject::InodeVMObject(InodeVMObject const& other)
  16. : VMObject(other)
  17. , m_inode(other.m_inode)
  18. , m_dirty_pages(page_count(), false)
  19. {
  20. for (size_t i = 0; i < page_count(); ++i)
  21. m_dirty_pages.set(i, other.m_dirty_pages.get(i));
  22. }
  23. InodeVMObject::~InodeVMObject()
  24. {
  25. }
  26. size_t InodeVMObject::amount_clean() const
  27. {
  28. size_t count = 0;
  29. VERIFY(page_count() == m_dirty_pages.size());
  30. for (size_t i = 0; i < page_count(); ++i) {
  31. if (!m_dirty_pages.get(i) && m_physical_pages[i])
  32. ++count;
  33. }
  34. return count * PAGE_SIZE;
  35. }
  36. size_t InodeVMObject::amount_dirty() const
  37. {
  38. size_t count = 0;
  39. for (size_t i = 0; i < m_dirty_pages.size(); ++i) {
  40. if (m_dirty_pages.get(i))
  41. ++count;
  42. }
  43. return count * PAGE_SIZE;
  44. }
  45. int InodeVMObject::release_all_clean_pages()
  46. {
  47. SpinlockLocker locker(m_lock);
  48. int count = 0;
  49. for (size_t i = 0; i < page_count(); ++i) {
  50. if (!m_dirty_pages.get(i) && m_physical_pages[i]) {
  51. m_physical_pages[i] = nullptr;
  52. ++count;
  53. }
  54. }
  55. if (count) {
  56. for_each_region([](auto& region) {
  57. region.remap();
  58. });
  59. }
  60. return count;
  61. }
  62. u32 InodeVMObject::writable_mappings() const
  63. {
  64. u32 count = 0;
  65. const_cast<InodeVMObject&>(*this).for_each_region([&](auto& region) {
  66. if (region.is_writable())
  67. ++count;
  68. });
  69. return count;
  70. }
  71. u32 InodeVMObject::executable_mappings() const
  72. {
  73. u32 count = 0;
  74. const_cast<InodeVMObject&>(*this).for_each_region([&](auto& region) {
  75. if (region.is_executable())
  76. ++count;
  77. });
  78. return count;
  79. }
  80. }