DiskBackedFileSystem.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "DiskBackedFileSystem.h"
  2. #ifdef SERENITY
  3. #include "i386.h"
  4. #else
  5. typedef int InterruptDisabler;
  6. #endif
  7. //#define DBFS_DEBUG
  8. #define BLOCK_CACHE
  9. DiskBackedFS::DiskBackedFS(RetainPtr<DiskDevice>&& device)
  10. : m_device(move(device))
  11. {
  12. ASSERT(m_device);
  13. }
  14. DiskBackedFS::~DiskBackedFS()
  15. {
  16. }
  17. bool DiskBackedFS::writeBlock(unsigned index, const ByteBuffer& data)
  18. {
  19. ASSERT(data.size() == blockSize());
  20. #ifdef DBFS_DEBUG
  21. kprintf("DiskBackedFileSystem::writeBlock %u\n", index);
  22. #endif
  23. DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
  24. return device().write(baseOffset, blockSize(), data.pointer());
  25. }
  26. bool DiskBackedFS::writeBlocks(unsigned index, unsigned count, const ByteBuffer& data)
  27. {
  28. #ifdef DBFS_DEBUG
  29. kprintf("DiskBackedFileSystem::writeBlocks %u x%u\n", index, count);
  30. #endif
  31. DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
  32. return device().write(baseOffset, count * blockSize(), data.pointer());
  33. }
  34. ByteBuffer DiskBackedFS::readBlock(unsigned index) const
  35. {
  36. #ifdef DBFS_DEBUG
  37. kprintf("DiskBackedFileSystem::readBlock %u\n", index);
  38. #endif
  39. #ifdef BLOCK_CACHE
  40. {
  41. LOCKER(m_blockCacheLock);
  42. InterruptDisabler disabler;
  43. auto it = m_blockCache.find(index);
  44. if (it != m_blockCache.end()) {
  45. return (*it).value;
  46. }
  47. }
  48. #endif
  49. auto buffer = ByteBuffer::create_uninitialized(blockSize());
  50. //kprintf("created block buffer with size %u\n", blockSize());
  51. DiskOffset baseOffset = static_cast<DiskOffset>(index) * static_cast<DiskOffset>(blockSize());
  52. auto* bufferPointer = buffer.pointer();
  53. bool success = device().read(baseOffset, blockSize(), bufferPointer);
  54. ASSERT(success);
  55. ASSERT(buffer.size() == blockSize());
  56. #ifdef BLOCK_CACHE
  57. {
  58. LOCKER(m_blockCacheLock);
  59. InterruptDisabler disabler;
  60. if (m_blockCache.size() >= 32)
  61. m_blockCache.removeOneRandomly();
  62. m_blockCache.set(index, buffer);
  63. }
  64. #endif
  65. return buffer;
  66. }
  67. ByteBuffer DiskBackedFS::readBlocks(unsigned index, unsigned count) const
  68. {
  69. if (!count)
  70. return nullptr;
  71. if (count == 1)
  72. return readBlock(index);
  73. auto blocks = ByteBuffer::create_uninitialized(count * blockSize());
  74. byte* out = blocks.pointer();
  75. for (unsigned i = 0; i < count; ++i) {
  76. auto block = readBlock(index + i);
  77. if (!block)
  78. return nullptr;
  79. memcpy(out, block.pointer(), block.size());
  80. out += blockSize();
  81. }
  82. return blocks;
  83. }
  84. void DiskBackedFS::setBlockSize(unsigned blockSize)
  85. {
  86. if (blockSize == m_blockSize)
  87. return;
  88. m_blockSize = blockSize;
  89. invalidateCaches();
  90. }
  91. void DiskBackedFS::invalidateCaches()
  92. {
  93. LOCKER(m_blockCacheLock);
  94. InterruptDisabler disabler;
  95. m_blockCache.clear();
  96. }