File indexing completed on 2024-04-28 05:45:46
0001 /* 0002 SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de> 0003 SPDX-FileCopyrightText: 2014-2016 Andrius Štikonas <andrius@stikonas.eu> 0004 SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org> 0005 0006 SPDX-License-Identifier: GPL-3.0-or-later 0007 */ 0008 0009 #include "core/partitionnode.h" 0010 0011 #include "core/partition.h" 0012 #include "core/partitionrole.h" 0013 0014 #include "fs/filesystem.h" 0015 0016 /** Tries to find the predecessor for a Partition. 0017 @param p the Partition to find a predecessor for 0018 @return pointer to the predecessor or nullptr if none was found 0019 */ 0020 Partition* PartitionNode::predecessor(Partition& p) 0021 { 0022 Q_ASSERT(p.parent()); 0023 0024 Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children(); 0025 0026 for (int idx = 1; idx < plist.size(); idx++) 0027 if (plist[idx] == &p) 0028 return plist[idx - 1]; 0029 0030 return nullptr; 0031 } 0032 0033 /** 0034 @overload 0035 */ 0036 const Partition* PartitionNode::predecessor(const Partition& p) const 0037 { 0038 Q_ASSERT(p.parent()); 0039 0040 const Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children(); 0041 0042 for (int idx = 1; idx < plist.size(); idx++) 0043 if (plist[idx] == &p) 0044 return plist[idx - 1]; 0045 0046 return nullptr; 0047 } 0048 0049 /** Tries to find the successor for a Partition. 0050 @param p the Partition to find a successor for 0051 @return pointer to the successor or nullptr if none was found 0052 */ 0053 Partition* PartitionNode::successor(Partition& p) 0054 { 0055 Q_ASSERT(p.parent()); 0056 0057 Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children(); 0058 0059 for (int idx = plist.size() - 2; idx >= 0; idx--) 0060 if (plist[idx] == &p) 0061 return plist[idx + 1]; 0062 0063 return nullptr; 0064 } 0065 0066 /** 0067 @overload 0068 */ 0069 const Partition* PartitionNode::successor(const Partition& p) const 0070 { 0071 Q_ASSERT(p.parent()); 0072 0073 const Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children(); 0074 0075 for (int idx = plist.size() - 2; idx >= 0; idx--) 0076 if (plist[idx] == &p) 0077 return plist[idx + 1]; 0078 0079 return nullptr; 0080 } 0081 0082 /** Inserts a Partition into a PartitionNode's children 0083 @param p pointer to the Partition to insert. May be nullptr. 0084 @return true on success 0085 */ 0086 bool PartitionNode::insert(Partition* p) 0087 { 0088 if (p == nullptr) 0089 return false; 0090 0091 for (int idx = 0; idx < children().size(); idx++) { 0092 if (children()[idx]->firstSector() > p->firstSector()) { 0093 children().insert(idx, p); 0094 return true; 0095 } 0096 } 0097 0098 children().insert(children().size(), p); 0099 0100 return true; 0101 } 0102 0103 /** Removes a Partition from the PartitionNode's children. 0104 @param p pointer to the Partition to remove. May be nullptr. 0105 @return true on success. 0106 */ 0107 bool PartitionNode::remove(Partition* p) 0108 { 0109 if (p == nullptr) 0110 return false; 0111 0112 return children().removeOne(p); 0113 } 0114 0115 /** Deletes all children */ 0116 void PartitionNode::clearChildren() 0117 { 0118 qDeleteAll(children()); 0119 children().clear(); 0120 } 0121 0122 /** Finds a Partition by sector. 0123 @param s the sector the Partition is at 0124 @param role the PartitionRole the Partition is supposed to have 0125 @return pointer to the Partition found or nullptr if none was found 0126 */ 0127 Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role) 0128 { 0129 const auto partitions = children(); 0130 for (auto &p : partitions) { 0131 // (women and) children first. ;-) 0132 const auto pChildren = p->children(); 0133 for (auto &child : pChildren) 0134 if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector()) 0135 return child; 0136 0137 if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector()) 0138 return p; 0139 } 0140 0141 return nullptr; 0142 } 0143 0144 /** 0145 @overload 0146 */ 0147 const Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role) const 0148 { 0149 for (const auto *p : children()) { 0150 for (const auto &child : p->children()) 0151 if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector()) 0152 return child; 0153 0154 if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector()) 0155 return p; 0156 } 0157 0158 return nullptr; 0159 } 0160 0161 /** Reparents a Partition to this PartitionNode 0162 @param p the Partition to reparent 0163 */ 0164 void PartitionNode::reparent(Partition& p) 0165 { 0166 p.setParent(this); 0167 0168 if (!isRoot()) 0169 p.setRoles(PartitionRole(PartitionRole::Logical)); 0170 else if (!p.roles().has(PartitionRole::Extended)) 0171 p.setRoles(PartitionRole(PartitionRole::Primary)); 0172 else 0173 p.setRoles(PartitionRole(PartitionRole::Extended)); 0174 } 0175 0176 /** @return the number of the highest mounted child, e.g. 7 if /dev/sdd7 is a child of this PartitionNode and mounted and /dev/sdd8 and /dev/sdd9 and so on aren't 0177 */ 0178 qint32 PartitionNode::highestMountedChild() const 0179 { 0180 qint32 result = -1; 0181 0182 for (const auto * p : children()) 0183 if (p->number() > result && p->isMounted()) 0184 result = p->number(); 0185 0186 return result; 0187 } 0188 0189 /** @return true if any of the partition's children are mounted */ 0190 bool PartitionNode::isChildMounted() const 0191 { 0192 for (const auto * child : children()) 0193 if (child->isMounted() || (child->hasChildren() && child->isChildMounted())) 0194 return true; 0195 0196 return false; 0197 }