158 if (isQuotaFile(source->getInode()) || (replaced && isQuotaFile(replaced->getInode()))) {
159 SYSCALL_ERROR(NotEnoughPermissions);
162 if (oldName.length() > 255 || newName.length() > 255) {
163 SYSCALL_ERROR(NameTooLong);
172 const bool oldFirst =
173 reinterpret_cast<uintptr_t
>(oldDirectory) <
reinterpret_cast<uintptr_t
>(newDirectory);
174 Ext2Directory* first = oldFirst ? oldDirectory : newDirectory;
175 Ext2Directory* second = oldFirst ? newDirectory : oldDirectory;
179 movedDirectory ? movedDirectory->m_DirectoryLock : first->m_DirectoryLock,
180 movedDirectory !=
nullptr);
182 replacedDirectory ? replacedDirectory->m_DirectoryLock : first->m_DirectoryLock,
183 replacedDirectory !=
nullptr);
184 if (oldDirectory->m_Removed || newDirectory->m_Removed ||
185 (movedDirectory && movedDirectory->m_Removed) ||
186 (replacedDirectory && replacedDirectory->m_Removed)) {
187 SYSCALL_ERROR(DoesNotExist);
190 if (movedDirectory && oldDirectory != newDirectory && !replacedDirectory &&
191 LITTLE_TO_HOST16(newDirectory->Ext2Node::getInode()->i_links_count) == 0xffff) {
192 SYSCALL_ERROR(TooManyLinks);
201 if (!oldDirectory->prepareRenameRecord(oldName, source->getInode(), oldRecord)) {
204 if (movedDirectory && oldDirectory != newDirectory &&
205 !movedDirectory->prepareRenameRecord(
String(
".."), oldDirectory->getInodeNumber(),
209 if (replacedDirectory && (!replacedDirectory->prepareRenameRecord(
210 String(
"."), replacedDirectory->getInodeNumber(), replacedDot) ||
211 !replacedDirectory->prepareRenameRecord(
212 String(
".."), newDirectory->getInodeNumber(), replacedParent))) {
216 if (!newDirectory->prepareRenameRecord(newName, replaced->getInode(), newRecord)) {
219 }
else if (!newDirectory->prepareRenameSpace(
220 newName, newRecord, oldDirectory == newDirectory ? &oldRecord :
nullptr)) {
224 if (oldRecord.entry != newRecord.entry) {
225 ByteSet(oldRecord.entry, 0, oldRecord.length);
226 oldRecord.entry->d_reclen = HOST_TO_LITTLE16(oldRecord.length);
228 if (newRecord.split) {
229 newRecord.split->d_reclen = HOST_TO_LITTLE16(newRecord.splitLength);
231 ByteSet(newRecord.entry, 0, newRecord.length);
232 newRecord.entry->d_inode = HOST_TO_LITTLE32(source->getInode());
233 newRecord.entry->d_reclen = HOST_TO_LITTLE16(newRecord.length);
234 newRecord.entry->d_namelen = newName.length();
235 if (checkRequiredFeature(2)) {
236 newRecord.entry->d_file_type = source->
isDirectory() ? EXT2_DIRECTORY
240 MemoryCopy(newRecord.entry->d_name, newName.cstr(), newName.length());
241 if (parentRecord.entry) {
242 parentRecord.entry->d_inode = HOST_TO_LITTLE32(newDirectory->getInodeNumber());
243 writeBlock(parentRecord.block);
244 oldDirectory->queueSyncDependency(parentRecord.block);
245 newDirectory->queueSyncDependency(parentRecord.block);
247 writeBlock(oldRecord.block);
248 if (newRecord.block != oldRecord.block) {
249 writeBlock(newRecord.block);
251 if (replacedDirectory) {
252 replacedDirectory->m_Removed =
true;
253 ByteSet(replacedDot.entry, 0, replacedDot.length);
254 replacedDot.entry->d_reclen = HOST_TO_LITTLE16(replacedDot.length);
255 ByteSet(replacedParent.entry, 0, replacedParent.length);
256 replacedParent.entry->d_reclen = HOST_TO_LITTLE16(replacedParent.length);
257 writeBlock(replacedDot.block);
258 writeBlock(replacedParent.block);
259 releaseInode(newDirectory->getInodeNumber(), newDirectory);
260 releaseInode(replacedDirectory->getInodeNumber(), replacedDirectory);
261 releaseInode(replacedDirectory->getInodeNumber(), replacedDirectory);
264 const uint32_t group = (replacedDirectory->getInodeNumber() - 1) /
265 LITTLE_TO_HOST32(m_pSuperblock->s_inodes_per_group);
266 GroupDesc* descriptor = m_pGroupDescriptors[group];
267 descriptor->bg_used_dirs_count =
268 HOST_TO_LITTLE16(LITTLE_TO_HOST16(descriptor->bg_used_dirs_count) - 1);
269 const uint32_t descriptorBlock = LITTLE_TO_HOST32(m_pSuperblock->s_first_data_block) + 1;
270 writeBlock(descriptorBlock + (group *
sizeof(
GroupDesc)) / m_BlockSize);
272 }
else if (replaced) {
276 releaseInode(node->getInodeNumber(), node);
278 if (parentRecord.entry) {
279 increaseInodeRefcount(newDirectory->getInodeNumber());
280 releaseInode(oldDirectory->getInodeNumber(), oldDirectory);