1 /*
2     SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
3     SPDX-FileCopyrightText: 2008 Laurent Montel <montel@kde.org>
4     SPDX-FileCopyrightText: 2013-2020 Andrius Štikonas <andrius@stikonas.eu>
5     SPDX-FileCopyrightText: 2015 Chris Campbell <c.j.campbell@ed.ac.uk>
6     SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
7     SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
8 
9     SPDX-License-Identifier: GPL-3.0-or-later
10 */
11 
12 #ifndef KPMCORE_PARTITION_H
13 #define KPMCORE_PARTITION_H
14 
15 #include "core/partitionnode.h"
16 #include "core/partitionrole.h"
17 #include "core/partitiontable.h"
18 
19 #include "util/libpartitionmanagerexport.h"
20 
21 #include <QtGlobal>
22 #include <QPointer>
23 
24 class Device;
25 class OperationStack;
26 class CoreBackendPartitionTable;
27 class PartitionAlignment;
28 
29 class PartResizerWidget;
30 class ResizeDialog;
31 class InsertDialog;
32 class NewDialog;
33 class EditMountPointDialog;
34 class PartPropsDialog;
35 class SizeDialogBase;
36 
37 class CreateFileSystemOperation;
38 class RestoreOperation;
39 class SetPartFlagsOperation;
40 class CopyOperation;
41 class NewOperation;
42 class ResizeOperation;
43 
44 class SetPartGeometryJob;
45 class CreatePartitionJob;
46 class SetPartFlagsJob;
47 class RestoreFileSystemJob;
48 
49 class FileSystem;
50 
51 class Report;
52 
53 class QString;
54 class QTextStream;
55 
56 /** A partition or some unallocated space on a Device.
57 
58     Represent partitions in a PartitionTable on a Device. Partitions can be unallocated, thus not all
59     instances really are partitions in the way the user would see them.
60 
61     Extended partitions have child objects that represent the logicals inside them.
62 
63     @see PartitionTable, Device, FileSystem
64     @author Volker Lanz <vl@fidra.de>
65 */
66 class LIBKPMCORE_EXPORT Partition : public PartitionNode
67 {
68 
69 public:
70     /** A Partition state -- where did it come from? */
71     enum State {
72         None,      /**< exists on disk */
73         New,       /**< from a NewOperation */
74         Copy,      /**< from a CopyOperation */
75         Restore,   /**< from a RestoreOperation */
76         StateNone [[deprecated("Use Partition::State::None")]] = None,
77         StateNew [[deprecated("Use Partition::State::New")]] = New,
78         StateCopy [[deprecated("Use Partition::State::Copy")]] = Copy,
79         StateRestore [[deprecated("Use Partition::State::Restore")]] = Restore
80     };
81 
82     Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::Flag::None, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::Flag::None, State state = State::None);
83     ~Partition() override;
84 
85     Partition(const Partition& other, PartitionNode* parent = nullptr);
86     Partition& operator=(const Partition&);
87 
88     bool operator==(const Partition& other) const;
89     bool operator!=(const Partition& other) const;
90 
number()91     qint32 number() const {
92         return m_Number;    /**< @return the Partition's device number, e.g. 7 for /dev/sdd7 */
93     }
94 
isRoot()95     bool isRoot() const override {
96         return false;    /**< @return always false for Partition */
97     }
98 
99     const PartitionTable* partitionTable() const;
100 
parent()101     PartitionNode* parent() override {
102         return m_Parent;    /**< @return the Partition's parent PartitionNode */
103     }
parent()104     const PartitionNode* parent() const override {
105         return m_Parent;    /**< @return the Partition's parent PartitionNode */
106     }
107 
children()108     Partitions& children() override {
109         return m_Children;    /**< @return the Partition's children. empty for non-extended. */
110     }
children()111     const Partitions& children() const override {
112         return m_Children;    /**< @return the Partition's children. empty for non-extended. */
113     }
devicePath()114     const QString& devicePath() const {
115         return m_DevicePath;    /**< @return the Partition's device path, e.g. /dev/sdd */
116     }
partitionPath()117     const QString& partitionPath() const {
118         return m_PartitionPath;    /**< @return the Partition's path, e.g. /dev/sdd1 */
119     }
label()120     const QString& label() const {
121         return m_Label;    /**< @return the GPT Partition label */
122     }
type()123     const QString& type() const {
124         return m_Type;    /**< @return the GPT Partition type */
125     }
uuid()126     const QString& uuid() const {
127         return m_UUID;    /**< @return the GPT Partition UUID */
128     }
attributes()129     quint64 attributes() const {
130         return m_Attributes;    /**< @return the GPT Partition attributes */
131     }
firstSector()132     qint64 firstSector() const {
133         return m_FirstSector;    /**< @return the Partition's first sector on the Device */
134     }
lastSector()135     qint64 lastSector() const {
136         return m_LastSector;    /**< @return the Partition's last sector on the Device */
137     }
firstByte()138     qint64 firstByte() const {
139         return firstSector() * sectorSize();    /**< @return the Partition's first byte on the Device */
140     }
lastByte()141     qint64 lastByte() const {
142         return firstByte() + length() * sectorSize() - 1;    /**< @return the Partition's last byte on the Device */
143     }
144     qint64 sectorsUsed() const;
sectorSize()145     qint64 sectorSize() const {
146         return m_SectorSize;    /**< @return the sector size on the Partition's Device */
147     }
length()148     qint64 length() const {
149         return lastSector() - firstSector() + 1;    /**< @return the length of the Partition */
150     }
capacity()151     qint64 capacity() const {
152         return length() * sectorSize();    /**< @return the capacity of the Partition in bytes */
153     }
used()154     qint64 used() const {
155         return sectorsUsed() < 0 ? -1 : sectorsUsed() * sectorSize();    /**< @return the number of used sectors in the Partition's FileSystem */
156     }
available()157     qint64 available() const {
158         return sectorsUsed() < 0 ? -1 : capacity() - used();    /**< @return the number of free sectors in the Partition's FileSystem */
159     }
160     qint64 minimumSectors() const;
161     qint64 maximumSectors() const;
162     qint64 maxFirstSector() const;
163     qint64 minLastSector() const;
164 
165     QString deviceNode() const;
166 
roles()167     const PartitionRole& roles() const {
168         return m_Roles;    /**< @return the Partition's role(s) */
169     }
170 
mountPoint()171     const QString& mountPoint() const {
172         return m_MountPoint;    /**< @return the Partition's mount point */
173     }
174 
activeFlags()175     PartitionTable::Flags activeFlags() const {
176         return m_ActiveFlags;    /**< @return the flags currently set for this Partition */
177     }
availableFlags()178     PartitionTable::Flags availableFlags() const {
179         return m_AvailableFlags;    /**< @return the flags available for this Partition */
180     }
isMounted()181     bool isMounted() const {
182         return m_IsMounted;    /**< @return true if Partition is mounted */
183     }
fileSystem()184     FileSystem& fileSystem() {
185         return *m_FileSystem;    /**< @return the Partition's FileSystem */
186     }
fileSystem()187     const FileSystem& fileSystem() const {
188         return *m_FileSystem;    /**< @return the Partition's FileSystem */
189     }
state()190     State state() const {
191         return m_State;    /**< @return the Partition's state */
192     }
193     bool hasChildren() const;
194 
195     bool mount(Report& report);
196     bool unmount(Report& report);
197 
198     bool canMount() const;
199     bool canUnmount() const;
200 
201     void adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber) const;
202     void checkChildrenMounted();
203 
setFirstSector(qint64 s)204     void setFirstSector(qint64 s) {
205         m_FirstSector = s;
206     }
setLastSector(qint64 s)207     void setLastSector(qint64 s) {
208         m_LastSector = s;
209     }
210 
setLabel(const QString & s)211     void setLabel(const QString& s) {
212         m_Label = s;    /**< @param s the new label */
213     }
setType(const QString & s)214     void setType(const QString& s) {
215         m_Type = s;    /**< @param s the new type */
216     }
setUUID(const QString & s)217     void setUUID(const QString& s) {
218         m_UUID = s;    /**< @param s the new UUID */
219     }
setAttributes(quint64 f)220     void setAttributes(quint64 f) {
221         m_Attributes = f;    /**< @param f the new attributes */
222     }
223 
append(Partition * p)224     void append(Partition* p) override {
225         m_Children.append(p);
226         std::sort(m_Children.begin(), m_Children.end(), [] (const Partition *a, const Partition *b) -> bool {return a->firstSector() < b->firstSector();});
227     }
setDevicePath(const QString & s)228     void setDevicePath(const QString& s) {
229         m_DevicePath = s;
230     }
231     void setPartitionPath(const QString& s);
setRoles(const PartitionRole & r)232     void setRoles(const PartitionRole& r) {
233         m_Roles = r;
234     }
setMountPoint(const QString & s)235     void setMountPoint(const QString& s) {
236         m_MountPoint = s;
237     }
setFlags(PartitionTable::Flags f)238     void setFlags(PartitionTable::Flags f) {
239         m_ActiveFlags = f;
240     }
setSectorSize(qint32 s)241     void setSectorSize(qint32 s) {
242         m_SectorSize = s;
243     }
244     void move(qint64 newStartSector);
245     void setMounted(bool b);
246 
setFlag(PartitionTable::Flag f)247     void setFlag(PartitionTable::Flag f) {
248         m_ActiveFlags = m_ActiveFlags.setFlag(f);
249     }
unsetFlag(PartitionTable::Flag f)250     void unsetFlag(PartitionTable::Flag f) {
251         m_ActiveFlags = m_ActiveFlags.setFlag(f, false);
252     }
setParent(PartitionNode * p)253     void setParent(PartitionNode* p) {
254         m_Parent = p;
255     }
256     void setFileSystem(FileSystem* fs);
setState(State s)257     void setState(State s) {
258         m_State = s;
259     }
260     void deleteFileSystem();
261 
262 private:
setNumber(qint32 n)263     void setNumber(qint32 n) {
264         m_Number = n;
265     }
266 
267     qint32 m_Number = 0;
268     Partitions m_Children;
269     QPointer< PartitionNode > m_Parent = nullptr;
270     FileSystem* m_FileSystem = nullptr;
271     PartitionRole m_Roles;
272     qint64 m_FirstSector = 0;
273     qint64 m_LastSector = 0;
274     QString m_DevicePath;
275     QString m_Label;
276     QString m_Type;
277     QString m_UUID;
278     quint64 m_Attributes = 0;
279     QString m_PartitionPath;
280     QString m_MountPoint;
281     PartitionTable::Flags m_AvailableFlags;
282     PartitionTable::Flags m_ActiveFlags;
283     bool m_IsMounted = false;
284     qint64 m_SectorSize = 0;
285     State m_State = None;
286 };
287 
288 QTextStream& operator<<(QTextStream& stream, const Partition& p);
289 
290 #endif
291