The Pedigree Project 0.1
Partition.h
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#ifndef PARTITION_H
21#define PARTITION_H
22
23#include "pedigree/kernel/LockGuard.h"
24#include "pedigree/kernel/TargetInfo.h"
25#include "pedigree/kernel/machine/Disk.h"
26#include "pedigree/kernel/process/Mutex.h"
27#include "pedigree/kernel/processor/types.h"
28#include "pedigree/kernel/utilities/StaticString.h"
29#include "pedigree/kernel/utilities/String.h"
30
34class Partition : public Disk {
35 public:
36 Partition(const String& type, uint64_t start, uint64_t length);
37 virtual ~Partition() override;
38
39 virtual void getName(String& str) override {
41 str2 += m_Type;
42 str2 += " partition";
43 str.assign(str2, str2.length());
44 }
45
46 virtual void dump(String& str) override {
48 str2 += m_Type;
49 str2 += " partition at 0x";
50 str2.append(m_Start, 16);
51 str2 += "-";
52 str2.append(m_Start + m_Length, 16);
53 str.assign(str2, str2.length());
54 }
55
56 virtual BufferView read(uint64_t location) override {
57 if (!containsCachePage(location))
58 return BufferView();
59
60 Disk* pParent = static_cast<Disk*>(getParent());
61
62 ensureAligned(pParent);
63
64 BufferView view = pParent->read(location + m_Start);
65 if (!view) {
66 return BufferView();
67 }
68
69 const uint64_t remaining = m_Length - location;
70 return remaining < view.size() ? view.first(static_cast<size_t>(remaining)) : view;
71 }
72
73 bool zero(uint64_t location, size_t length) override {
74 if (!containsRange(location, length))
75 return false;
76 auto* parent = static_cast<Disk*>(getParent());
77 ensureAligned(parent);
78 return parent->zero(m_Start + location, length);
79 }
80
81 DiskReadView readView(uint64_t location) override {
82 if (!containsRange(location, 1))
83 return {};
84 auto* parent = static_cast<Disk*>(getParent());
85 ensureAligned(parent);
86 auto view = parent->readView(m_Start + location);
87 if (view && m_Length - location < view.size())
88 view.truncate(static_cast<size_t>(m_Length - location));
89 return view;
90 }
91
92 DiskWriteView writeView(uint64_t location) override {
93 if (!containsRange(location, 1))
94 return {};
95 auto* parent = static_cast<Disk*>(getParent());
96 ensureAligned(parent);
97 auto view = parent->writeView(m_Start + location);
98 if (view && m_Length - location < view.size())
99 view.truncate(static_cast<size_t>(m_Length - location));
100 return view;
101 }
102
103 virtual void write(uint64_t location) override {
104 if (!containsCachePage(location))
105 return;
106
107 Disk* pParent = static_cast<Disk*>(getParent());
108
109 ensureAligned(pParent);
110
111 pParent->write(location + m_Start);
112 }
113
114 virtual void flush(uint64_t location) override {
115 if (!containsCachePage(location))
116 return;
117
118 Disk* pParent = static_cast<Disk*>(getParent());
119
120 ensureAligned(pParent);
121
122 pParent->flush(location + m_Start);
123 }
124
125 MUST_USE_RESULT virtual bool retireCachePage(uint64_t location) override {
126 if (!containsCachePage(location))
127 return false;
128
129 Disk* pParent = static_cast<Disk*>(getParent());
130
131 ensureAligned(pParent);
132
133 return pParent->retireCachePage(location + m_Start);
134 }
135
136 virtual bool sync(uint64_t location, bool async) override {
137 if (!containsCachePage(location))
138 return false;
139
140 Disk* parent = static_cast<Disk*>(getParent());
141 ensureAligned(parent);
142 return parent->sync(location + m_Start, async);
143 }
144
145 MUST_USE_RESULT bool syncPages(const uint64_t* locations, size_t count) override;
146
147 bool readInto(uint64_t location, void* buffer, size_t length) override;
148 bool readIntoBatch(ReadBuffer* buffers, size_t count) override;
149 bool writeFrom(uint64_t location, const void* buffer, size_t length) override;
150 bool writeFromBatch(WriteBuffer* buffers, size_t count) override;
151 bool syncData() override;
152
153 MUST_USE_RESULT virtual bool syncAll() override;
154
155 Disk* physicalDisk() override {
156 Disk* parent = static_cast<Disk*>(getParent());
157 return parent ? parent->physicalDisk() : nullptr;
158 }
159
160 virtual size_t getSize() const override {
161 return getLength();
162 }
163
164 virtual size_t getBlockSize() const override {
165 const Disk* pParent = static_cast<const Disk*>(getParent());
166 return pParent->getBlockSize();
167 }
168
169 size_t getNativeBlockSize() const override {
170 const Disk* parent = static_cast<const Disk*>(getParent());
171 return parent ? parent->getNativeBlockSize() : 0;
172 }
173
174 virtual bool pin(uint64_t location) override {
175 if (!containsCachePage(location))
176 return false;
177 Disk* pParent = static_cast<Disk*>(getParent());
178 ensureAligned(pParent);
179 return pParent->pin(location + m_Start);
180 }
181
182 virtual void unpin(uint64_t location) override {
183 if (!containsCachePage(location))
184 return;
185 Disk* pParent = static_cast<Disk*>(getParent());
186 pParent->unpin(location + m_Start);
187 }
188
190 uint64_t getStart();
191
193 uint64_t getLength() const {
194 return m_Length;
195 }
196
198 const String& getPartitionType() const {
199 return m_Type;
200 }
201
202 void setPartitionIdentity(const String& uuid, const String& label) {
203 m_Uuid = uuid;
204 m_Label = label;
205 }
206
207 bool getPartitionUuid(String& uuid) const override {
208 uuid = m_Uuid;
209 return uuid.length() != 0;
210 }
211
212 bool getPartitionLabel(String& label) const override {
213 label = m_Label;
214 return label.length() != 0;
215 }
216
217 private:
218 bool containsRange(uint64_t location, size_t length) const;
219
220 bool containsCachePage(uint64_t location) const {
221 if (location >= m_Length) {
222 return false;
223 }
224
225 const uint64_t pageSize = TargetInfo::getPageSize();
226 const uint64_t pageLocation = location - (location % pageSize);
227 return pageSize <= (m_Length - pageLocation);
228 }
229
230 void ensureAligned(Disk* pParent) {
231 LockGuard<Mutex> guard(m_AlignmentLock);
232 if (!m_bAligned) {
233 // A partition-relative page must map to one parent cache page even
234 // when the partition begins in the middle of a physical page.
235 pParent->align(m_Start);
236 m_bAligned = true;
237 }
238 }
239
240 String m_Type;
241 String m_Uuid;
242 String m_Label;
243 uint64_t m_Start;
244 uint64_t m_Length;
245 Mutex m_AlignmentLock;
246 bool m_bAligned;
247};
248
249#endif
Device * getParent() const
Definition Device.h:166
Definition Disk.h:35
virtual bool sync(uint64_t location, bool async)
Definition Disk.cc:358
virtual void align(uint64_t location)
Sets the page boundary alignment after a specific location on the disk.
Definition Disk.cc:342
virtual BufferView read(uint64_t location)
Definition Disk.cc:163
virtual void unpin(uint64_t location)=0
virtual void write(uint64_t location)
Definition Disk.cc:340
virtual void flush(uint64_t location)
Flush a cached page to disk.
Definition Disk.cc:356
virtual size_t getNativeBlockSize() const
Definition Disk.cc:383
virtual MUST_USE_RESULT bool pin(uint64_t location)=0
Pins a cache page.
virtual size_t getBlockSize() const
Gets the preferred I/O extent of the disk.
Definition Disk.cc:348
virtual MUST_USE_RESULT bool retireCachePage(uint64_t location)
Definition Disk.cc:379
Definition Mutex.h:56
virtual void unpin(uint64_t location) override
Definition Partition.h:182
DiskReadView readView(uint64_t location) override
Definition Partition.h:81
virtual void dump(String &str) override
Definition Partition.h:46
virtual void write(uint64_t location) override
Definition Partition.h:103
const String & getPartitionType() const
Definition Partition.h:198
uint64_t getStart()
Definition Partition.cc:136
uint64_t getLength() const
Definition Partition.h:193
MUST_USE_RESULT bool syncPages(const uint64_t *locations, size_t count) override
Definition Partition.cc:110
virtual void getName(String &str) override
Definition Partition.h:39
bool writeFromBatch(WriteBuffer *buffers, size_t count) override
Definition Partition.cc:83
size_t getNativeBlockSize() const override
Definition Partition.h:169
bool readIntoBatch(ReadBuffer *buffers, size_t count) override
Definition Partition.cc:53
bool syncData() override
Definition Partition.cc:105
virtual bool pin(uint64_t location) override
Pins a cache page.
Definition Partition.h:174
virtual MUST_USE_RESULT bool retireCachePage(uint64_t location) override
Definition Partition.h:125
virtual size_t getSize() const override
Gets the size of the disk.
Definition Partition.h:160
virtual MUST_USE_RESULT bool syncAll() override
Definition Partition.cc:130
virtual void flush(uint64_t location) override
Flush a cached page to disk.
Definition Partition.h:114
bool readInto(uint64_t location, void *buffer, size_t length) override
Definition Partition.cc:45
bool zero(uint64_t location, size_t length) override
Definition Partition.h:73
virtual size_t getBlockSize() const override
Gets the preferred I/O extent of the disk.
Definition Partition.h:164
bool getPartitionUuid(String &uuid) const override
Definition Partition.h:207
virtual BufferView read(uint64_t location) override
Definition Partition.h:56
virtual bool sync(uint64_t location, bool async) override
Definition Partition.h:136
static constexpr size_t getPageSize() noexcept
Definition TargetInfo.h:40