mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 17:31:58 -05:00
Kernel/FATFS: Implement remove_child
This commit is contained in:
parent
3b39a2f71b
commit
511b298a1d
2 changed files with 59 additions and 2 deletions
|
@ -604,9 +604,64 @@ ErrorOr<void> FATInode::add_child(Inode& inode, StringView name, mode_t mode)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> FATInode::remove_child(StringView)
|
||||
ErrorOr<void> FATInode::remove_child(StringView name)
|
||||
{
|
||||
return EROFS;
|
||||
MutexLocker locker(m_inode_lock);
|
||||
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_child(): removing inode \"{}\"", identifier(), name);
|
||||
|
||||
VERIFY(has_flag(m_entry.attributes, FATAttributes::Directory));
|
||||
|
||||
Vector<FATLongFileNameEntry> lfn_entries;
|
||||
TRY(lfn_entries.try_ensure_capacity(ceil_div(max_filename_length, characters_per_lfn_entry)));
|
||||
|
||||
Vector<FATEntryLocation> lfn_entry_locations;
|
||||
TRY(lfn_entry_locations.try_ensure_capacity(ceil_div(max_filename_length, characters_per_lfn_entry)));
|
||||
|
||||
auto block_list = TRY(get_block_list());
|
||||
auto block_buffer = TRY(read_block_list());
|
||||
|
||||
for (u32 i = 0; i < block_buffer->size() / sizeof(FATEntry); i++) {
|
||||
auto* entry = bit_cast<FATEntry*>(block_buffer->data() + i * sizeof(FATEntry));
|
||||
|
||||
auto entry_number_bytes = i * sizeof(FATEntry);
|
||||
auto block = block_list[entry_number_bytes / fs().logical_block_size()];
|
||||
|
||||
auto entries_per_sector = fs().logical_block_size() / sizeof(FATEntry);
|
||||
u32 block_entry = i % entries_per_sector;
|
||||
|
||||
if (entry->filename[0] == end_entry_byte) {
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_child(): Found end entry", identifier());
|
||||
return ENOENT;
|
||||
} else if (static_cast<u8>(entry->filename[0]) == unused_entry_byte) {
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_child(): Found unused entry", identifier());
|
||||
lfn_entries.clear_with_capacity();
|
||||
lfn_entry_locations.clear_with_capacity();
|
||||
} else if (entry->attributes == FATAttributes::LongFileName) {
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_child(): Found LFN entry", identifier());
|
||||
lfn_entries.unchecked_append(*bit_cast<FATLongFileNameEntry*>(entry));
|
||||
lfn_entry_locations.unchecked_append({ block, block_entry });
|
||||
} else {
|
||||
dbgln_if(FAT_DEBUG, "FATInode[{}]::remove_child(): Found 8.3 entry at block {}, entry {}", identifier(), block, block_entry);
|
||||
lfn_entries.reverse();
|
||||
auto filename = TRY(compute_filename(*entry, lfn_entries));
|
||||
if (filename->view() == name) {
|
||||
// FIXME: If it's the last entry move the end entry instead of unused entries
|
||||
FATEntry unused_entry {};
|
||||
unused_entry.filename[0] = unused_entry_byte;
|
||||
TRY(fs().write_block(block, UserOrKernelBuffer::for_kernel_buffer(bit_cast<u8*>(&unused_entry)), sizeof(FATEntry), block_entry * sizeof(FATEntry)));
|
||||
|
||||
for (auto const& lfn_entry_location : lfn_entry_locations)
|
||||
TRY(fs().write_block(lfn_entry_location.block, UserOrKernelBuffer::for_kernel_buffer(bit_cast<u8*>(&unused_entry)), sizeof(FATEntry), lfn_entry_location.entry * sizeof(FATEntry)));
|
||||
|
||||
return {};
|
||||
}
|
||||
lfn_entries.clear_with_capacity();
|
||||
lfn_entry_locations.clear_with_capacity();
|
||||
}
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ErrorOr<void> FATInode::chmod(mode_t)
|
||||
|
|
|
@ -51,6 +51,8 @@ private:
|
|||
static constexpr size_t characters_per_lfn_entry = lfn_entry_characters_part_1_length + lfn_entry_characters_part_2_length + lfn_entry_characters_part_3_length;
|
||||
static constexpr u8 last_lfn_entry_mask = 0x40;
|
||||
|
||||
static constexpr size_t max_filename_length = 255;
|
||||
|
||||
static ErrorOr<NonnullOwnPtr<KString>> compute_filename(FATEntry&, Vector<FATLongFileNameEntry> const& = {});
|
||||
static StringView byte_terminated_string(StringView, u8);
|
||||
static u8 lfn_entry_checksum(FATEntry const& entry);
|
||||
|
|
Loading…
Reference in a new issue