Browse Source

Ext2FS: Delete inodes when their link count goes to zero.

Andreas Kling 6 năm trước cách đây
mục cha
commit
05f18febb6

+ 2 - 0
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);

+ 4 - 0
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, &params);

+ 28 - 9
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;

+ 1 - 1
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;