2#include "VirtioBlkDisk.h"
3#include "pedigree/kernel/Log.h"
4#include "pedigree/kernel/TargetInfo.h"
5#include "pedigree/kernel/utilities/utility.h"
7#include "VirtioBlkController.h"
10 m_pParent = controller;
11 setSpecificType(
String(
"virtio-blk-disk"));
14VirtioBlkDisk::~VirtioBlkDisk() {
20 name.assign(
"Virtio Block Disk");
24 return m_Controller->sizeBytes();
27size_t VirtioBlkDisk::getBlockCount()
const {
36 return m_Controller->sectorBytes();
39bool VirtioBlkDisk::writeFrom(uint64_t location,
const void* buffer,
size_t length) {
40 if (m_Controller->readOnly()) {
41 return !length && location <=
getSize();
43 return ScsiDisk::writeFrom(location, buffer, length);
47 if (m_Controller->readOnly()) {
48 for (
size_t i = 0; buffers && i < count; ++i) {
49 buffers[i].complete =
false;
57 if (!m_Controller->readOnly()) {
63 return m_Controller->readOnly() ? (!length && location <=
getSize())
67BufferView VirtioBlkDisk::acquireView(uint64_t location,
bool writable, uint64_t& token) {
68 if (writable && m_Controller->readOnly()) {
71 return ScsiDisk::acquireView(location, writable, token);
74size_t VirtioBlkDisk::validPageLength(uint64_t location)
const {
76 if (!native || location >=
getSize() || location % native) {
79 const size_t remaining =
getSize() - location;
81 return remaining < page ? remaining : page;
84uint64_t VirtioBlkDisk::doRead(uint64_t location) {
89 const uintptr_t existing = getCache().
lookup(location);
95 const uintptr_t page = getCache().
insert(location, &existed);
103 if (!m_Controller->readWrite(location,
reinterpret_cast<void*
>(page), bytes,
false)) {
104 if (!getCache().discardEditing(location)) {
105 FATAL(
"Virtio block: failed to discard incomplete cache fill");
113uint64_t VirtioBlkDisk::doWrite(uint64_t location) {
117 if (m_Controller->readOnly() || !validPageLength(location)) {
120 const uintptr_t page = getCache().
lookup(location);
133 const size_t bytes = validPageLength(location);
134 if (m_Controller->readOnly() || !page || !bytes) {
137 return m_Controller->readWrite(location,
reinterpret_cast<void*
>(page), bytes,
true) ? bytes : 0;
141uint64_t VirtioBlkDisk::doSync(uint64_t location) {
145 const size_t bytes = location == SyncWholeDevice ?
size_t{1} : validPageLength(location);
146 return bytes && m_Controller->flush() ? bytes : 0;
150bool VirtioBlkDisk::transferBuffer(uint64_t location,
void* buffer,
size_t length,
bool writing) {
158 length >
getSize() - location || !native || location % native || length % native ||
159 (writing && m_Controller->readOnly())) {
162 return m_Controller->readWrite(location, buffer, length, writing);
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)
virtual void write(uint64_t location)
size_t getCacheFillLength(uint64_t location) const
bool writeFromBatch(WriteBuffer *buffers, size_t count) override
bool zero(uint64_t location, size_t length) override
static constexpr size_t getPageSize() noexcept
void write(uint64_t location) override
size_t getSize() const override
Gets the size of the disk.
size_t getNativeBlockSize() const override
bool writeFromBatch(WriteBuffer *buffers, size_t count) override
uint64_t doWriteDirect(uint64_t location, uintptr_t page) override
void getName(String &name) override
bool zero(uint64_t location, size_t length) override
size_t getBlockSize() const override
Gets the preferred I/O extent of the disk.