21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/Log.h"
23#include "pedigree/kernel/Service.h"
24#include "pedigree/kernel/ServiceFeatures.h"
25#include "pedigree/kernel/ServiceManager.h"
26#include "pedigree/kernel/TargetInfo.h"
27#include "pedigree/kernel/utilities/assert.h"
28#include "pedigree/kernel/utilities/utility.h"
30#include "modules/Module.h"
31#include "modules/system/vfs/VFS.h"
33FileDisk::FileDisk(
String file, AccessType mode)
35 m_bVfsReference(false),
38 m_MemRegion(
"FileDisk"),
44 WARNING(
"FileDisk: '" << file <<
"' doesn't exist...");
46 m_bVfsReference = m_pFile->retainVfsReference();
47 if (!m_bVfsReference) {
48 WARNING(
"FileDisk: '" << file <<
"' cannot be retained...");
53 m_pFile->increaseRefCount(
false);
60 NOTICE(
"Asking if the partition provider supports touch");
63 "It does, attempting to inform the partitioner of our "
67 reinterpret_cast<void*
>(
static_cast<Disk*
>(
this)),
68 sizeof(*
static_cast<Disk*
>(
this)))) {
69 NOTICE(
"Successful.");
74 "FileDisk: Couldn't tell the partition service about the "
77 ERROR(
"FileDisk: Partition service doesn't appear to support touch");
81FileDisk::~FileDisk() {
84 m_pFile->decreaseRefCount(
false);
93bool FileDisk::initialise() {
101 FATAL(
"Read with location % 512.");
109 uint64_t alignPoint = 0;
110 for (
size_t i = 0; i < m_nAlignPoints; i++)
111 if (m_AlignPoints[i] <= location && m_AlignPoints[i] > alignPoint)
112 alignPoint = m_AlignPoints[i];
113 alignPoint %= pageSize;
116 const uint64_t pageOffset = (location - alignPoint) % pageSize;
117 const uint64_t readPage = location - pageOffset;
118 const uint64_t fileSize =
m_pFile->getSize();
119 if (location >= fileSize || readPage >= fileSize) {
122 const size_t validLength = pageSize < (fileSize - readPage) ? pageSize : (fileSize - readPage);
124 uintptr_t buffer = m_Cache.
lookup(readPage);
127 return BufferView::fromAddress(buffer + pageOffset, validLength - pageOffset);
129 buffer = m_Cache.
insert(readPage);
134 ByteSet(
reinterpret_cast<void*
>(buffer), 0, pageSize);
135 if (
m_pFile->
read(readPage, validLength, buffer) != validLength) {
143 buffer = m_Cache.
lookup(readPage);
144 return buffer ? BufferView::fromAddress(buffer + pageOffset, validLength - pageOffset)
158 for (
size_t i = 0; i < m_nAlignPoints; ++i) {
159 if (m_AlignPoints[i] == location) {
163 assert(m_nAlignPoints < 8);
164 m_AlignPoints[m_nAlignPoints++] = location;
176 uint64_t alignPoint = 0;
177 for (
size_t i = 0; i < m_nAlignPoints; i++)
178 if (m_AlignPoints[i] <= location && m_AlignPoints[i] > alignPoint)
179 alignPoint = m_AlignPoints[i];
180 alignPoint %= pageSize;
182 const uint64_t page = location - ((location - alignPoint) % pageSize);
184 if (location >= fileSize || page >= fileSize) {
187 return m_Cache.
pin(page);
195 uint64_t alignPoint = 0;
196 for (
size_t i = 0; i < m_nAlignPoints; i++)
197 if (m_AlignPoints[i] <= location && m_AlignPoints[i] > alignPoint)
198 alignPoint = m_AlignPoints[i];
199 alignPoint %= pageSize;
201 const uint64_t page = location - ((location - alignPoint) % pageSize);
203 if (location >= fileSize || page >= fileSize) {
213static void destroy() {}
215MODULE_INFO(
"lodisk", &init, &destroy,
"vfs");
MUST_USE_RESULT bool discardEditing(uintptr_t key)
bool shutdown(ShutdownMode mode=ShutdownMode::WriteBack)
void release(uintptr_t key)
uintptr_t insert(uintptr_t key, bool *alreadyExisted=nullptr)
void markNoLongerEditing(uintptr_t key, size_t length=0)
uintptr_t lookup(uintptr_t key)
MUST_USE_RESULT bool pin(uintptr_t key)
virtual bool pin(uint64_t location)
Pins a cache page.
virtual void align(uint64_t location)
Sets the page boundary alignment after a specific location on the disk.
bool m_bVfsReference
Whether this disk owns a persistent VFS reference to m_pFile.
virtual size_t getSize() const
Gets the size of the disk.
virtual void write(uint64_t location)
virtual BufferView read(uint64_t location)
virtual void unpin(uint64_t location)
File * m_pFile
File we're using as a disk.
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
virtual void releaseVfsReference()
virtual bool provides(Type service)
Service * getService(const String &serviceName)
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
static constexpr size_t getPageSize() noexcept
File * findRetained(const String &path, Directory::ChildLease &result, File *pStartNode=nullptr)