The Pedigree Project 0.1
Partition.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "Partition.h"
21#include "pedigree/kernel/processor/types.h"
22
23Partition::Partition(const String& type, uint64_t start, uint64_t length)
24 : m_Type(type),
25 m_Uuid(),
26 m_Label(),
27 m_Start(start),
28 m_Length(length),
29 m_AlignmentLock(),
30 m_bAligned(false) {
31 setSpecificType(String("partition"));
32}
33
34Partition::~Partition() {}
35
36bool Partition::containsRange(uint64_t location, size_t length) const {
37 const auto* parent = static_cast<const Disk*>(getParent());
38 if (!parent || location > m_Length || length > m_Length - location ||
39 location > ~uint64_t{0} - m_Start)
40 return false;
41 const uint64_t translated = m_Start + location;
42 return translated <= parent->getSize() && length <= parent->getSize() - translated;
43}
44
45bool Partition::readInto(uint64_t location, void* buffer, size_t length) {
46 if (!containsRange(location, length))
47 return false;
48 auto* parent = static_cast<Disk*>(getParent());
49 ensureAligned(parent);
50 return parent->readInto(m_Start + location, buffer, length);
51}
52
53bool Partition::readIntoBatch(ReadBuffer* buffers, size_t count) {
54 if (count > MaxReadBuffers || (count && !buffers))
55 return false;
56 for (size_t i = 0; i < count; ++i)
57 buffers[i].complete = false;
58 if (!count)
59 return true;
60 ReadBuffer translated[MaxReadBuffers];
61 for (size_t i = 0; i < count; ++i) {
62 if (!containsRange(buffers[i].location, buffers[i].length))
63 return false;
64 translated[i] = buffers[i];
65 translated[i].location += m_Start;
66 }
67 auto* parent = static_cast<Disk*>(getParent());
68 ensureAligned(parent);
69 const bool success = parent->readIntoBatch(translated, count);
70 for (size_t i = 0; i < count; ++i)
71 buffers[i].complete = translated[i].complete;
72 return success;
73}
74
75bool Partition::writeFrom(uint64_t location, const void* buffer, size_t length) {
76 if (!containsRange(location, length))
77 return false;
78 auto* parent = static_cast<Disk*>(getParent());
79 ensureAligned(parent);
80 return parent->writeFrom(m_Start + location, buffer, length);
81}
82
83bool Partition::writeFromBatch(WriteBuffer* buffers, size_t count) {
84 if (count > MaxWriteBuffers || (count && !buffers))
85 return false;
86 WriteBuffer translated[MaxWriteBuffers];
87 for (size_t i = 0; i < count; ++i)
88 buffers[i].complete = false;
89 for (size_t i = 0; i < count; ++i) {
90 if (!containsRange(buffers[i].location, buffers[i].length))
91 return false;
92 translated[i] = buffers[i];
93 translated[i].location += m_Start;
94 }
95 auto* parent = static_cast<Disk*>(getParent());
96 if (!parent)
97 return false;
98 ensureAligned(parent);
99 const bool success = parent->writeFromBatch(translated, count);
100 for (size_t i = 0; i < count; ++i)
101 buffers[i].complete = translated[i].complete;
102 return success;
103}
104
106 auto* parent = static_cast<Disk*>(getParent());
107 return parent && parent->syncData();
108}
109
110bool Partition::syncPages(const uint64_t* locations, size_t count) {
111 if (count > MaxSyncPages || (count && !locations))
112 return false;
113 if (!count)
114 return true;
115 Disk* parent = static_cast<Disk*>(getParent());
116 if (!parent)
117 return false;
118 uint64_t translated[MaxSyncPages];
119 for (size_t i = 0; i < count; ++i) {
120 if (!containsCachePage(locations[i]) || locations[i] > ~uint64_t(0) - m_Start)
121 return false;
122 translated[i] = locations[i] + m_Start;
123 if (translated[i] >= parent->getSize())
124 return false;
125 }
126 ensureAligned(parent);
127 return parent->syncPages(translated, count);
128}
129
131 Disk* parent = static_cast<Disk*>(getParent());
132 // A device-wide drain is stronger than the partition's persistence boundary.
133 return parent && parent->syncAll();
134}
135
137 return m_Start;
138}
Device * getParent() const
Definition Device.h:166
Definition Disk.h:35
virtual size_t getSize() const
Gets the size of the disk.
Definition Disk.cc:344
virtual MUST_USE_RESULT bool syncPages(const uint64_t *locations, size_t count)
Definition Disk.cc:362
virtual MUST_USE_RESULT bool syncData()
Definition Disk.cc:299
virtual MUST_USE_RESULT bool syncAll()
Definition Disk.cc:375
uint64_t getStart()
Definition Partition.cc:136
MUST_USE_RESULT bool syncPages(const uint64_t *locations, size_t count) override
Definition Partition.cc:110
bool writeFromBatch(WriteBuffer *buffers, size_t count) override
Definition Partition.cc:83
bool readIntoBatch(ReadBuffer *buffers, size_t count) override
Definition Partition.cc:53
bool syncData() override
Definition Partition.cc:105
virtual MUST_USE_RESULT bool syncAll() override
Definition Partition.cc:130
bool readInto(uint64_t location, void *buffer, size_t length) override
Definition Partition.cc:45