forked from Bananymous/banan-os
				
			
			update main #1
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -49,6 +49,7 @@ namespace Kernel
 | 
			
		|||
		BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name);
 | 
			
		||||
		BAN::ErrorOr<bool> is_directory_empty();
 | 
			
		||||
 | 
			
		||||
		void cleanup_indirect_block(uint32_t block, uint32_t depth);
 | 
			
		||||
		BAN::ErrorOr<void> cleanup_default_links();
 | 
			
		||||
		void cleanup_from_fs();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
 | 
			
		||||
#define EXT2_DEBUG_PRINT 0
 | 
			
		||||
#define EXT2_VERIFY_INODE 0
 | 
			
		||||
#define EXT2_VERIFY_NO_BLOCKS 1
 | 
			
		||||
 | 
			
		||||
namespace Kernel
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +245,10 @@ namespace Kernel
 | 
			
		|||
		auto inode_location = locate_inode(ino);
 | 
			
		||||
		read_block(inode_location.block, inode_buffer);
 | 
			
		||||
		auto& inode = inode_buffer.span().slice(inode_location.offset).as<Ext2::Inode>();
 | 
			
		||||
#if EXT2_VERIFY_NO_BLOCKS
 | 
			
		||||
		static const char zero_buffer[sizeof(inode.block)] {};
 | 
			
		||||
		ASSERT(memcmp(inode.block, zero_buffer, sizeof(inode.block)) == 0);
 | 
			
		||||
#endif
 | 
			
		||||
		bool is_directory = Inode::Mode(inode.mode).ifdir();
 | 
			
		||||
		memset(&inode, 0x00, m_superblock.inode_size);
 | 
			
		||||
		write_block(inode_location.block, inode_buffer);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -259,11 +259,54 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ext2Inode::cleanup_indirect_block(uint32_t block, uint32_t depth)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(block);
 | 
			
		||||
 | 
			
		||||
		if (depth == 0)
 | 
			
		||||
		{
 | 
			
		||||
			m_fs.release_block(block);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto block_buffer = m_fs.get_block_buffer();
 | 
			
		||||
		m_fs.read_block(block, block_buffer);
 | 
			
		||||
 | 
			
		||||
		const uint32_t ids_per_block = blksize() / sizeof(uint32_t);
 | 
			
		||||
		for (uint32_t i = 0; i < ids_per_block; i++)
 | 
			
		||||
		{
 | 
			
		||||
			const uint32_t idx = ((uint32_t*)block_buffer.data())[i];
 | 
			
		||||
			if (idx > 0)
 | 
			
		||||
				cleanup_indirect_block(idx, depth - 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_fs.release_block(block);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ext2Inode::cleanup_from_fs()
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(m_inode.links_count == 0);
 | 
			
		||||
		for (uint32_t i = 0; i < blocks(); i++)
 | 
			
		||||
			m_fs.release_block(fs_block_of_data_block_index(i));
 | 
			
		||||
 | 
			
		||||
		// cleanup direct blocks
 | 
			
		||||
		for (uint32_t i = 0; i < 12; i++)
 | 
			
		||||
			if (m_inode.block[i])
 | 
			
		||||
				m_fs.release_block(m_inode.block[i]);
 | 
			
		||||
 | 
			
		||||
		// cleanup indirect blocks
 | 
			
		||||
		if (m_inode.block[12])
 | 
			
		||||
			cleanup_indirect_block(m_inode.block[12], 1);
 | 
			
		||||
		if (m_inode.block[13])
 | 
			
		||||
			cleanup_indirect_block(m_inode.block[13], 2);
 | 
			
		||||
		if (m_inode.block[14])
 | 
			
		||||
			cleanup_indirect_block(m_inode.block[14], 3);
 | 
			
		||||
		
 | 
			
		||||
		// mark blocks as deleted
 | 
			
		||||
		memset(m_inode.block, 0x00, sizeof(m_inode.block));
 | 
			
		||||
 | 
			
		||||
		// FIXME: this is only required since fs does not get
 | 
			
		||||
		//        deleting inode from its cache
 | 
			
		||||
		sync();
 | 
			
		||||
	
 | 
			
		||||
		m_fs.delete_inode(ino());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue