21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/machine/Disk.h"
23#include "pedigree/kernel/panic.h"
24#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
25#include "pedigree/kernel/utilities/utility.h"
32 :
File(name, 0 , 0 , 0 ,
33 0 , static_cast<
Filesystem*>(pFs), 0 , pParent),
44 uint32_t permissions = FILE_UR | FILE_UW | FILE_GR | FILE_OR;
45 setPermissions(permissions);
51RawFsFile::~RawFsFile() {
53 panic(
"rawfs: file cache shutdown failed; unwritten data remains");
61 if (offset >= getSize())
64 return m_PageCache.
sync(offset - offset % pageSize, async);
67bool RawFsFile::shutdown() {
71bool RawFsFile::cacheCallback(CacheConstants::CallbackCause cause, uintptr_t location,
72 uintptr_t page,
void* context) {
73 auto* file =
static_cast<RawFsFile*
>(context);
74 if (cause == CacheConstants::Eviction)
76 if (cause != CacheConstants::WriteBack || !page || location >= file->getSize())
79 const size_t length = min(pageSize,
static_cast<size_t>(file->getSize() - location));
81 file->m_pDisk->writeFrom(location,
reinterpret_cast<const void*
>(page), length);
83 const bool durable = file->m_pDisk->syncData();
84 return written && durable;
96 const uint64_t pageLocation = location - (location % pageSize);
97 const size_t pageOffset = location - pageLocation;
98 if (location >= getSize() || pageLocation >= getSize()) {
101 const size_t validLength =
102 pageSize < (getSize() - pageLocation) ? pageSize : (getSize() - pageLocation);
104 uintptr_t buffer = m_PageCache.
lookup(pageLocation);
106 return buffer + pageOffset;
109 bool didExist =
false;
110 buffer = m_PageCache.
insert(pageLocation, &didExist);
116 ByteSet(
reinterpret_cast<void*
>(buffer), 0, pageSize);
118 while (copied < validLength) {
119 const uint64_t diskLocation = pageLocation + copied;
127 const size_t remaining = validLength - copied;
128 const size_t chunk = source.size() < remaining ? source.size() : remaining;
130 m_pDisk->
unpin(diskLocation);
135 MemoryCopy(
reinterpret_cast<void*
>(buffer + copied), source.data(), chunk);
136 m_pDisk->
unpin(diskLocation);
142 buffer = m_PageCache.
lookup(pageLocation);
143 return buffer ? buffer + pageOffset : 0;
148 const uint64_t pageLocation = location - (location % pageSize);
149 if (!address || location >= getSize() || pageLocation >= getSize()) {
152 const size_t validLength =
153 pageSize < (getSize() - pageLocation) ? pageSize : (getSize() - pageLocation);
155 const uintptr_t page =
readBlock(pageLocation);
159 MemoryCopy(
reinterpret_cast<void*
>(page),
reinterpret_cast<const void*
>(address), validLength);
161 m_PageCache.
release(pageLocation);
166 if (location >= getSize()) {
169 return m_PageCache.
pin(location - (location % pageSize));
174 if (location >= getSize()) {
177 m_PageCache.
release(location - (location % pageSize));
MUST_USE_RESULT bool discardEditing(uintptr_t key)
bool shutdown(ShutdownMode mode=ShutdownMode::WriteBack)
MUST_USE_RESULT bool syncAll()
void setCallback(writeback_t newCallback, void *meta)
void release(uintptr_t key)
uintptr_t insert(uintptr_t key, bool *alreadyExisted=nullptr)
void markDirty(uintptr_t key)
bool sync(uintptr_t key, bool async)
void markNoLongerEditing(uintptr_t key, size_t length=0)
uintptr_t lookup(uintptr_t key)
MUST_USE_RESULT bool pin(uintptr_t key)
virtual BufferView read(uint64_t location)
virtual size_t getSize() const
Gets the size of the disk.
virtual void unpin(uint64_t location)=0
static bool writeCallback(CacheConstants::CallbackCause cause, uintptr_t loc, uintptr_t page, void *meta)
static constexpr size_t getPageSize() PURE
RawFsFile(const RawFsFile &file)
virtual size_t getBlockSize() const
virtual bool pinBlock(uint64_t location)
virtual uintptr_t readBlock(uint64_t location)
virtual void writeBlock(uint64_t location, uintptr_t address)
virtual void unpinBlock(uint64_t location)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN