diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-22 16:34:24 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-22 16:34:24 +0100 |
commit | 05f18febb6cd21fb15ab7a3af7ea715c6b653e08 (patch) | |
tree | 6450e17ca8d24412f4508533bb120da0b0b2f9e0 | |
parent | bda0c935c26867f3a613723fd3bc7a84aef110ba (diff) | |
download | serenity-05f18febb6cd21fb15ab7a3af7ea715c6b653e08.zip |
Ext2FS: Delete inodes when their link count goes to zero.
-rw-r--r-- | Kernel/IDEDiskDevice.cpp | 2 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 4 | ||||
-rw-r--r-- | VirtualFileSystem/Ext2FileSystem.cpp | 37 | ||||
-rw-r--r-- | VirtualFileSystem/Ext2FileSystem.h | 2 |
4 files changed, 35 insertions, 10 deletions
diff --git a/Kernel/IDEDiskDevice.cpp b/Kernel/IDEDiskDevice.cpp index f1fcc53393..e8123fa716 100644 --- a/Kernel/IDEDiskDevice.cpp +++ b/Kernel/IDEDiskDevice.cpp @@ -223,11 +223,13 @@ bool IDEDiskDevice::read_sectors(dword start_sector, word count, byte* outbuf) bool IDEDiskDevice::write_sectors(dword start_sector, word count, const byte* data) { LOCKER(m_lock); +#ifdef DISK_DEBUG dbgprintf("%s(%u): IDEDiskDevice::write_sectors request (%u sector(s) @ %u)\n", current->name().characters(), current->pid(), count, start_sector); +#endif disable_irq(); auto chs = lba_to_chs(start_sector); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index 1131b82910..7ded9f4938 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -6,6 +6,7 @@ #include <LibC/gui.h> #include <LibC/stdio.h> #include <LibC/stdlib.h> +#include <LibC/unistd.h> #include <AK/HashMap.h> static HashMap<int, GWindow*>* s_windows; @@ -67,6 +68,9 @@ void GWindow::set_title(String&& title) void GWindow::set_rect(const Rect& rect) { + // FIXME: This is a hack to fudge the race with WSWindowManager trying to display @ old rect. + sleep(10); + dbgprintf("GWindow::set_rect %d,%d %dx%d\n", m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height()); GUI_WindowParameters params; int rc = gui_get_window_parameters(m_window_id, ¶ms); diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index 4f4759ba51..6fca4bae7e 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -1,6 +1,7 @@ #include "Ext2FileSystem.h" #include "ext2_fs.h" #include "UnixTypes.h" +#include "RTC.h" #include <AK/Bitmap.h> #include <AK/StdLibExtras.h> #include <AK/kmalloc.h> @@ -150,7 +151,7 @@ ByteBuffer Ext2FS::read_block_containing_inode(unsigned inode, unsigned& blockIn return readBlock(blockIndex); } -Vector<unsigned> Ext2FS::block_list_for_inode(const ext2_inode& e2inode) const +Vector<unsigned> Ext2FS::block_list_for_inode(const ext2_inode& e2inode, bool include_block_list_blocks) const { unsigned entriesPerBlock = EXT2_ADDR_PER_BLOCK(&super_block()); @@ -158,7 +159,12 @@ Vector<unsigned> Ext2FS::block_list_for_inode(const ext2_inode& e2inode) const unsigned blockCount = e2inode.i_blocks / (blockSize() / 512); unsigned blocksRemaining = blockCount; Vector<unsigned> list; - list.ensure_capacity(blocksRemaining); + if (include_block_list_blocks) { + // This seems like an excessive over-estimate but w/e. + list.ensure_capacity(blocksRemaining * 2); + } else { + list.ensure_capacity(blocksRemaining); + } unsigned directCount = min(blockCount, (unsigned)EXT2_NDIR_BLOCKS); for (unsigned i = 0; i < directCount; ++i) { @@ -170,6 +176,8 @@ Vector<unsigned> Ext2FS::block_list_for_inode(const ext2_inode& e2inode) const return list; auto processBlockArray = [&] (unsigned arrayBlockIndex, auto&& callback) { + if (include_block_list_blocks) + callback(arrayBlockIndex); auto arrayBlock = readBlock(arrayBlockIndex); ASSERT(arrayBlock); auto* array = reinterpret_cast<const __u32*>(arrayBlock.pointer()); @@ -219,11 +227,21 @@ Ext2FSInode::Ext2FSInode(Ext2FS& fs, unsigned index, const ext2_inode& raw_inode Ext2FSInode::~Ext2FSInode() { - if (m_raw_inode.i_links_count == 0) { - dbgprintf("Ext2FS: inode %u has no more links, time to delete!\n", index()); - // FIXME: Implement! - ASSERT_NOT_REACHED(); - } + if (m_raw_inode.i_links_count != 0) + return; + + dbgprintf("Ext2FS: inode %u has no more links, time to delete!\n", index()); + + m_raw_inode.i_dtime = RTC::now(); + fs().write_ext2_inode(index(), m_raw_inode); + + auto block_list = fs().block_list_for_inode(m_raw_inode, true); + + auto group_index = fs().group_index_from_inode(index()); + for (auto block_index : block_list) + fs().set_block_allocation_state(group_index, block_index, false); + + fs().set_inode_allocation_state(index(), false); } InodeMetadata Ext2FSInode::metadata() const @@ -804,6 +822,7 @@ bool Ext2FS::set_inode_allocation_state(unsigned index, bool newState) bool Ext2FS::set_block_allocation_state(GroupIndex group, BlockIndex bi, bool newState) { + dbgprintf("Ext2FS: set_block_allocation_state(group=%u, block=%u, state=%u)\n", group, bi, newState); auto& bgd = group_descriptor(group); // Update block bitmap @@ -812,9 +831,9 @@ bool Ext2FS::set_block_allocation_state(GroupIndex group, BlockIndex bi, bool ne unsigned bitIndex = (bi - 1) % blocksPerBitmapBlock; auto block = readBlock(bgd.bg_block_bitmap + bitmapBlockIndex); ASSERT(block); - auto bitmap = Bitmap::wrap(block.pointer(), block.size()); + auto bitmap = Bitmap::wrap(block.pointer(), blocksPerBitmapBlock); bool currentState = bitmap.get(bitIndex); - dbgprintf("Ext2FS: setBlockAllocationState(%u) %u -> %u\n", bi, currentState, newState); + dbgprintf("Ext2FS: block %u state: %u -> %u\n", bi, currentState, newState); if (currentState == newState) return true; diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index 74d57ecee7..49ee9dab80 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -92,7 +92,7 @@ private: Vector<BlockIndex> allocate_blocks(unsigned group, unsigned count); unsigned group_index_from_inode(unsigned) const; - Vector<unsigned> block_list_for_inode(const ext2_inode&) const; + Vector<unsigned> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const; void dump_block_bitmap(unsigned groupIndex) const; void dump_inode_bitmap(unsigned groupIndex) const; |