mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-03 17:58:49 +00:00
Add support for removing directories.
It's really only supported in Ext2FS since SynthFS doesn't really want you mucking around with its files. This is pretty neat though :^) I ran into some trouble with HashMap while working on this but opted to work around it and leave that for a separate investigation.
This commit is contained in:
parent
031c62a21e
commit
c95228b128
Notes:
sideshowbarker
2024-07-19 15:55:42 +09:00
Author: https://github.com/awesomekling
Commit: c95228b128
19 changed files with 185 additions and 40 deletions
|
@ -313,6 +313,20 @@ void Ext2FS::free_inode(Ext2FSInode& inode)
|
|||
set_block_allocation_state(group_index, block_index, false);
|
||||
|
||||
set_inode_allocation_state(inode.index(), false);
|
||||
|
||||
if (inode.is_directory()) {
|
||||
auto& bgd = const_cast<ext2_group_desc&>(group_descriptor(group_index_from_inode(inode.index())));
|
||||
--bgd.bg_used_dirs_count;
|
||||
dbgprintf("Ext2FS: decremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
|
||||
flush_block_group_descriptor_table();
|
||||
}
|
||||
}
|
||||
|
||||
void Ext2FS::flush_block_group_descriptor_table()
|
||||
{
|
||||
unsigned blocks_to_write = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned first_block_of_bgdt = blockSize() == 1024 ? 2 : 1;
|
||||
writeBlocks(first_block_of_bgdt, blocks_to_write, m_cached_group_descriptor_table);
|
||||
}
|
||||
|
||||
Ext2FSInode::Ext2FSInode(Ext2FS& fs, unsigned index, const ext2_inode& raw_inode)
|
||||
|
@ -356,9 +370,15 @@ void Ext2FSInode::flush_metadata()
|
|||
dbgprintf("Ext2FSInode: flush_metadata for inode %u\n", index());
|
||||
fs().write_ext2_inode(index(), m_raw_inode);
|
||||
if (is_directory()) {
|
||||
// FIXME: This invalidation is way too hardcore.
|
||||
LOCKER(m_lock);
|
||||
m_lookup_cache.clear();
|
||||
// Unless we're about to go away permanently, invalidate the lookup cache.
|
||||
if (m_raw_inode.i_links_count != 0) {
|
||||
LOCKER(m_lock);
|
||||
// FIXME: Something isn't working right when we hit this code path.
|
||||
// I've seen crashes inside HashMap::clear() all the way down in DoublyLinkedList::clear().
|
||||
// My guess would be a HashTable bug.
|
||||
// FIXME: This invalidation is way too hardcore. It's sad to throw away the whole cache.
|
||||
m_lookup_cache.clear();
|
||||
}
|
||||
}
|
||||
set_metadata_dirty(false);
|
||||
}
|
||||
|
@ -401,7 +421,7 @@ RetainPtr<Inode> Ext2FS::get_inode(InodeIdentifier inode) const
|
|||
return new_inode;
|
||||
}
|
||||
|
||||
ssize_t Ext2FSInode::read_bytes(off_t offset, size_t count, byte* buffer, FileDescriptor*)
|
||||
ssize_t Ext2FSInode::read_bytes(off_t offset, size_t count, byte* buffer, FileDescriptor*) const
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
if (m_raw_inode.i_size == 0)
|
||||
|
@ -550,7 +570,7 @@ ssize_t Ext2FSInode::write_bytes(off_t offset, size_t count, const byte* data, F
|
|||
return nwritten;
|
||||
}
|
||||
|
||||
bool Ext2FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)> callback)
|
||||
bool Ext2FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)> callback) const
|
||||
{
|
||||
ASSERT(metadata().isDirectory());
|
||||
|
||||
|
@ -610,6 +630,9 @@ bool Ext2FSInode::add_child(InodeIdentifier child_id, const String& name, byte f
|
|||
|
||||
bool Ext2FSInode::remove_child(const String& name, int& error)
|
||||
{
|
||||
#ifdef EXT2_DEBUG
|
||||
dbgprintf("Ext2FSInode::remove_child(%s) in inode %u\n", name.characters(), index());
|
||||
#endif
|
||||
ASSERT(is_directory());
|
||||
|
||||
unsigned child_inode_index;
|
||||
|
@ -710,7 +733,9 @@ bool Ext2FS::write_directory_inode(unsigned directoryInode, Vector<DirectoryEntr
|
|||
kprintf("\n");
|
||||
#endif
|
||||
|
||||
return get_inode({ fsid(), directoryInode })->write_bytes(0, directoryData.size(), directoryData.pointer(), nullptr);
|
||||
auto directory_inode = get_inode({ fsid(), directoryInode });
|
||||
ssize_t nwritten = directory_inode->write_bytes(0, directoryData.size(), directoryData.pointer(), nullptr);
|
||||
return nwritten == directoryData.size();
|
||||
}
|
||||
|
||||
unsigned Ext2FS::inodes_per_block() const
|
||||
|
@ -955,10 +980,7 @@ bool Ext2FS::set_inode_allocation_state(unsigned index, bool newState)
|
|||
++mutableBGD.bg_free_inodes_count;
|
||||
dbgprintf("Ext2FS: group free inode count %u -> %u\n", bgd.bg_free_inodes_count, bgd.bg_free_inodes_count - 1);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
writeBlocks(firstBlockOfBGDT, blocksToWrite, m_cached_group_descriptor_table);
|
||||
|
||||
flush_block_group_descriptor_table();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1000,10 +1022,7 @@ bool Ext2FS::set_block_allocation_state(GroupIndex group, BlockIndex bi, bool ne
|
|||
++mutableBGD.bg_free_blocks_count;
|
||||
dbgprintf("Ext2FS: group free block count %u -> %u\n", bgd.bg_free_blocks_count, bgd.bg_free_blocks_count - 1);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
writeBlocks(firstBlockOfBGDT, blocksToWrite, m_cached_group_descriptor_table);
|
||||
|
||||
flush_block_group_descriptor_table();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1040,9 +1059,7 @@ RetainPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const Strin
|
|||
++bgd.bg_used_dirs_count;
|
||||
dbgprintf("Ext2FS: incremented bg_used_dirs_count %u -> %u\n", bgd.bg_used_dirs_count - 1, bgd.bg_used_dirs_count);
|
||||
|
||||
unsigned blocksToWrite = ceilDiv(m_blockGroupCount * (unsigned)sizeof(ext2_group_desc), blockSize());
|
||||
unsigned firstBlockOfBGDT = blockSize() == 1024 ? 2 : 1;
|
||||
writeBlocks(firstBlockOfBGDT, blocksToWrite, m_cached_group_descriptor_table);
|
||||
flush_block_group_descriptor_table();
|
||||
|
||||
error = 0;
|
||||
return inode;
|
||||
|
@ -1165,7 +1182,7 @@ RetainPtr<Inode> Ext2FSInode::parent() const
|
|||
return fs().get_inode(m_parent_id);
|
||||
}
|
||||
|
||||
void Ext2FSInode::populate_lookup_cache()
|
||||
void Ext2FSInode::populate_lookup_cache() const
|
||||
{
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
|
@ -1267,3 +1284,11 @@ void Ext2FS::uncache_inode(InodeIndex index)
|
|||
LOCKER(m_inode_cache_lock);
|
||||
m_inode_cache.remove(index);
|
||||
}
|
||||
|
||||
size_t Ext2FSInode::directory_entry_count() const
|
||||
{
|
||||
ASSERT(is_directory());
|
||||
populate_lookup_cache();
|
||||
LOCKER(m_lock);
|
||||
return m_lookup_cache.size();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue