forked from Bananymous/banan-os
				
			Kernel: Add comparison operator for inodes
This commit is contained in:
		
							parent
							
								
									5224df321e
								
							
						
					
					
						commit
						76d5364a55
					
				| 
						 | 
					@ -135,26 +135,34 @@ namespace Kernel
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() override;
 | 
							virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() override;
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) override;
 | 
							virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual Type type() const override { return Type::Ext2; }
 | 
				
			||||||
 | 
							virtual bool operator==(const Inode& other) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		BAN::ErrorOr<uint32_t> data_block_index(uint32_t);
 | 
							BAN::ErrorOr<uint32_t> data_block_index(uint32_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		using block_callback_t = BAN::ErrorOr<bool>(*)(const BAN::Vector<uint8_t>&, void*);
 | 
							using block_callback_t = BAN::ErrorOr<bool>(*)(const BAN::Vector<uint8_t>&, void*);
 | 
				
			||||||
		BAN::ErrorOr<void> for_each_block(block_callback_t, void*);
 | 
							BAN::ErrorOr<void> for_each_block(block_callback_t, void*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t index() const { return m_index; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		Ext2Inode() {}
 | 
							Ext2Inode(Ext2FS& fs, Ext2::Inode inode, BAN::StringView name, uint32_t index)
 | 
				
			||||||
		Ext2Inode(Ext2FS* fs, Ext2::Inode inode, BAN::StringView name)
 | 
					 | 
				
			||||||
			: m_fs(fs)
 | 
								: m_fs(fs)
 | 
				
			||||||
			, m_inode(inode) 
 | 
								, m_inode(inode) 
 | 
				
			||||||
			, m_name(name)
 | 
								, m_name(name)
 | 
				
			||||||
 | 
								, m_index(index)
 | 
				
			||||||
		{}
 | 
							{}
 | 
				
			||||||
 | 
							static BAN::ErrorOr<BAN::RefPtr<Inode>> create(Ext2FS&, uint32_t, BAN::StringView);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		Ext2FS* m_fs = nullptr;
 | 
							Ext2FS& m_fs;
 | 
				
			||||||
		Ext2::Inode m_inode;
 | 
							Ext2::Inode m_inode;
 | 
				
			||||||
		BAN::String m_name;
 | 
							BAN::String m_name;
 | 
				
			||||||
 | 
							uint32_t m_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		friend class Ext2FS;
 | 
							friend class Ext2FS;
 | 
				
			||||||
 | 
							friend class BAN::RefPtr<Ext2Inode>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class Ext2FS : public FileSystem
 | 
						class Ext2FS : public FileSystem
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,12 @@ namespace Kernel
 | 
				
			||||||
			uint16_t mode;
 | 
								uint16_t mode;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							enum class Type
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								General,
 | 
				
			||||||
 | 
								Ext2,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		virtual ~Inode() {}
 | 
							virtual ~Inode() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +58,9 @@ namespace Kernel
 | 
				
			||||||
		virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) = 0;
 | 
							virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) = 0;
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() = 0;
 | 
							virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() = 0;
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) = 0;
 | 
							virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual Type type() const { return Type::General; }
 | 
				
			||||||
 | 
							virtual bool operator==(const Inode&) const = 0;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,8 +2,6 @@
 | 
				
			||||||
#include <BAN/StringView.h>
 | 
					#include <BAN/StringView.h>
 | 
				
			||||||
#include <kernel/FS/Ext2.h>
 | 
					#include <kernel/FS/Ext2.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <kernel/kprint.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define EXT2_DEBUG_PRINT 0
 | 
					#define EXT2_DEBUG_PRINT 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel
 | 
					namespace Kernel
 | 
				
			||||||
| 
						 | 
					@ -138,10 +136,19 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::create(Ext2FS& fs, uint32_t inode, BAN::StringView name)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Ext2::Inode ext2_inode = TRY(fs.read_inode(inode));
 | 
				
			||||||
 | 
							Ext2Inode* result = new Ext2Inode(fs, ext2_inode, name, inode);
 | 
				
			||||||
 | 
							if (result == nullptr)
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(ENOMEM);
 | 
				
			||||||
 | 
							return BAN::RefPtr<Inode>::adopt(result);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<uint32_t> Ext2Inode::data_block_index(uint32_t asked_data_block)
 | 
						BAN::ErrorOr<uint32_t> Ext2Inode::data_block_index(uint32_t asked_data_block)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uint32_t data_blocks_count = m_inode.blocks / (2 << m_fs->superblock().log_block_size);
 | 
							uint32_t data_blocks_count = m_inode.blocks / (2 << m_fs.superblock().log_block_size);
 | 
				
			||||||
		uint32_t blocks_per_array = (1024 << m_fs->superblock().log_block_size) / sizeof(uint32_t);
 | 
							uint32_t blocks_per_array = (1024 << m_fs.superblock().log_block_size) / sizeof(uint32_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (asked_data_block >= data_blocks_count)
 | 
							if (asked_data_block >= data_blocks_count)
 | 
				
			||||||
			return BAN::Error::from_c_string("Ext2: no such block");
 | 
								return BAN::Error::from_c_string("Ext2: no such block");
 | 
				
			||||||
| 
						 | 
					@ -162,7 +169,7 @@ namespace Kernel
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (m_inode.block[12] == 0)
 | 
								if (m_inode.block[12] == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
			auto block_array = TRY(m_fs->read_block(m_inode.block[12]));
 | 
								auto block_array = TRY(m_fs.read_block(m_inode.block[12]));
 | 
				
			||||||
			uint32_t block = ((uint32_t*)block_array.data())[asked_data_block];
 | 
								uint32_t block = ((uint32_t*)block_array.data())[asked_data_block];
 | 
				
			||||||
			if (block == 0)
 | 
								if (block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
| 
						 | 
					@ -174,11 +181,11 @@ namespace Kernel
 | 
				
			||||||
		// Doubly indirect blocks
 | 
							// Doubly indirect blocks
 | 
				
			||||||
		if (asked_data_block < blocks_per_array * blocks_per_array)
 | 
							if (asked_data_block < blocks_per_array * blocks_per_array)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto singly_indirect_array = TRY(m_fs->read_block(m_inode.block[13]));
 | 
								auto singly_indirect_array = TRY(m_fs.read_block(m_inode.block[13]));
 | 
				
			||||||
			uint32_t direct_block = ((uint32_t*)singly_indirect_array.data())[asked_data_block / blocks_per_array];
 | 
								uint32_t direct_block = ((uint32_t*)singly_indirect_array.data())[asked_data_block / blocks_per_array];
 | 
				
			||||||
			if (direct_block == 0)
 | 
								if (direct_block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
			auto block_array = TRY(m_fs->read_block(direct_block));
 | 
								auto block_array = TRY(m_fs.read_block(direct_block));
 | 
				
			||||||
			uint32_t block = ((uint32_t*)block_array.data())[asked_data_block % blocks_per_array];
 | 
								uint32_t block = ((uint32_t*)block_array.data())[asked_data_block % blocks_per_array];
 | 
				
			||||||
			if (block == 0)
 | 
								if (block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
| 
						 | 
					@ -190,15 +197,15 @@ namespace Kernel
 | 
				
			||||||
		// Triply indirect blocks
 | 
							// Triply indirect blocks
 | 
				
			||||||
		if (asked_data_block < blocks_per_array * blocks_per_array * blocks_per_array)
 | 
							if (asked_data_block < blocks_per_array * blocks_per_array * blocks_per_array)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			auto doubly_indirect_array = TRY(m_fs->read_block(m_inode.block[14]));
 | 
								auto doubly_indirect_array = TRY(m_fs.read_block(m_inode.block[14]));
 | 
				
			||||||
			uint32_t singly_indirect_block = ((uint32_t*)doubly_indirect_array.data())[asked_data_block / (blocks_per_array * blocks_per_array)];
 | 
								uint32_t singly_indirect_block = ((uint32_t*)doubly_indirect_array.data())[asked_data_block / (blocks_per_array * blocks_per_array)];
 | 
				
			||||||
			if (singly_indirect_block == 0)
 | 
								if (singly_indirect_block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
			auto singly_indirect_array = TRY(m_fs->read_block(singly_indirect_block));
 | 
								auto singly_indirect_array = TRY(m_fs.read_block(singly_indirect_block));
 | 
				
			||||||
			uint32_t direct_block = ((uint32_t*)singly_indirect_array.data())[(asked_data_block / blocks_per_array) % blocks_per_array];
 | 
								uint32_t direct_block = ((uint32_t*)singly_indirect_array.data())[(asked_data_block / blocks_per_array) % blocks_per_array];
 | 
				
			||||||
			if (direct_block == 0)
 | 
								if (direct_block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
			auto block_array = TRY(m_fs->read_block(direct_block));
 | 
								auto block_array = TRY(m_fs.read_block(direct_block));
 | 
				
			||||||
			uint32_t block = ((uint32_t*)block_array.data())[asked_data_block % blocks_per_array];
 | 
								uint32_t block = ((uint32_t*)block_array.data())[asked_data_block % blocks_per_array];
 | 
				
			||||||
			if (block == 0)
 | 
								if (block == 0)
 | 
				
			||||||
				return BAN::Error::from_errno(EIO);
 | 
									return BAN::Error::from_errno(EIO);
 | 
				
			||||||
| 
						 | 
					@ -210,12 +217,12 @@ namespace Kernel
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	BAN::ErrorOr<void> Ext2Inode::for_each_block(block_callback_t callback, void* callback_data)
 | 
						BAN::ErrorOr<void> Ext2Inode::for_each_block(block_callback_t callback, void* callback_data)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uint32_t data_block_count = m_inode.blocks / (2 << m_fs->superblock().log_block_size);
 | 
							uint32_t data_block_count = m_inode.blocks / (2 << m_fs.superblock().log_block_size);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		for (uint32_t i = 0; i < data_block_count; i++)
 | 
							for (uint32_t i = 0; i < data_block_count; i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			uint32_t data_block_index = TRY(this->data_block_index(i));
 | 
								uint32_t data_block_index = TRY(this->data_block_index(i));
 | 
				
			||||||
			auto block_data = TRY(m_fs->read_block(data_block_index));
 | 
								auto block_data = TRY(m_fs.read_block(data_block_index));
 | 
				
			||||||
			if (!TRY(callback(block_data, callback_data)))
 | 
								if (!TRY(callback(block_data, callback_data)))
 | 
				
			||||||
				return {};
 | 
									return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -233,7 +240,7 @@ namespace Kernel
 | 
				
			||||||
		if (offset + count > m_inode.size)
 | 
							if (offset + count > m_inode.size)
 | 
				
			||||||
			count = m_inode.size - offset;
 | 
								count = m_inode.size - offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const uint32_t block_size = 1024 << m_fs->superblock().log_block_size;
 | 
							const uint32_t block_size = 1024 << m_fs.superblock().log_block_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ASSERT(offset % block_size == 0);
 | 
							ASSERT(offset % block_size == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,7 +252,7 @@ namespace Kernel
 | 
				
			||||||
		for (uint32_t block = first_block; block < last_block; block++)
 | 
							for (uint32_t block = first_block; block < last_block; block++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			uint32_t data_block = TRY(data_block_index(block));
 | 
								uint32_t data_block = TRY(data_block_index(block));
 | 
				
			||||||
			auto block_data = TRY(m_fs->read_block(data_block));
 | 
								auto block_data = TRY(m_fs.read_block(data_block));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			uint32_t to_copy = BAN::Math::min<uint32_t>(block_data.size(), count - n_read);
 | 
								uint32_t to_copy = BAN::Math::min<uint32_t>(block_data.size(), count - n_read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -271,7 +278,7 @@ namespace Kernel
 | 
				
			||||||
		search_info info;
 | 
							search_info info;
 | 
				
			||||||
		info.file_name = file_name;
 | 
							info.file_name = file_name;
 | 
				
			||||||
		info.result = {};
 | 
							info.result = {};
 | 
				
			||||||
		info.fs = m_fs;
 | 
							info.fs = &m_fs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		block_callback_t function =
 | 
							block_callback_t function =
 | 
				
			||||||
			[](const BAN::Vector<uint8_t>& block_data, void* info_) -> BAN::ErrorOr<bool>
 | 
								[](const BAN::Vector<uint8_t>& block_data, void* info_) -> BAN::ErrorOr<bool>
 | 
				
			||||||
| 
						 | 
					@ -286,10 +293,7 @@ namespace Kernel
 | 
				
			||||||
					BAN::StringView entry_name = BAN::StringView(entry->name, entry->name_len);
 | 
										BAN::StringView entry_name = BAN::StringView(entry->name, entry->name_len);
 | 
				
			||||||
					if (entry->inode && info.file_name == entry_name)
 | 
										if (entry->inode && info.file_name == entry_name)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						Ext2Inode* inode = new Ext2Inode(info.fs, TRY(info.fs->read_inode(entry->inode)), entry_name);
 | 
											info.result = TRY(Ext2Inode::create(*info.fs, entry->inode, entry_name));
 | 
				
			||||||
						if (inode == nullptr)
 | 
					 | 
				
			||||||
							return BAN::Error::from_errno(ENOMEM);
 | 
					 | 
				
			||||||
						info.result = BAN::RefPtr<Inode>::adopt(inode);
 | 
					 | 
				
			||||||
						return false;
 | 
											return false;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					entry_addr += entry->rec_len;
 | 
										entry_addr += entry->rec_len;
 | 
				
			||||||
| 
						 | 
					@ -316,7 +320,7 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		directory_info info;
 | 
							directory_info info;
 | 
				
			||||||
		info.inodes = {};
 | 
							info.inodes = {};
 | 
				
			||||||
		info.fs = m_fs;
 | 
							info.fs = &m_fs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		block_callback_t function =
 | 
							block_callback_t function =
 | 
				
			||||||
			[](const BAN::Vector<uint8_t>& block_data, void* info_) -> BAN::ErrorOr<bool>
 | 
								[](const BAN::Vector<uint8_t>& block_data, void* info_) -> BAN::ErrorOr<bool>
 | 
				
			||||||
| 
						 | 
					@ -330,13 +334,9 @@ namespace Kernel
 | 
				
			||||||
					Ext2::LinkedDirectoryEntry* entry = (Ext2::LinkedDirectoryEntry*)entry_addr;
 | 
										Ext2::LinkedDirectoryEntry* entry = (Ext2::LinkedDirectoryEntry*)entry_addr;
 | 
				
			||||||
					if (entry->inode)
 | 
										if (entry->inode)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						BAN::StringView entry_name = BAN::StringView(entry->name, entry->name_len);
 | 
											auto entry_name = BAN::StringView(entry->name, entry->name_len);
 | 
				
			||||||
						Ext2::Inode current_inode = TRY(info.fs->read_inode(entry->inode));
 | 
											auto inode = TRY(Ext2Inode::create(*info.fs, entry->inode, entry_name));
 | 
				
			||||||
 | 
											TRY(info.inodes.push_back(inode));
 | 
				
			||||||
						Ext2Inode* inode = new Ext2Inode(info.fs, BAN::move(current_inode), entry_name);
 | 
					 | 
				
			||||||
						if (inode == nullptr)
 | 
					 | 
				
			||||||
							return BAN::Error::from_errno(ENOMEM);
 | 
					 | 
				
			||||||
						TRY(info.inodes.push_back(BAN::RefPtr<Inode>::adopt(inode)));
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					entry_addr += entry->rec_len;
 | 
										entry_addr += entry->rec_len;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -348,6 +348,17 @@ namespace Kernel
 | 
				
			||||||
		return info.inodes;
 | 
							return info.inodes;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool Ext2Inode::operator==(const Inode& other) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (type() != other.type())
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							Ext2Inode& ext2_other = (Ext2Inode&)other;
 | 
				
			||||||
 | 
							if (&m_fs != &ext2_other.m_fs)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							return index() == ext2_other.index();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<Ext2FS*> Ext2FS::create(StorageDevice::Partition& partition)
 | 
						BAN::ErrorOr<Ext2FS*> Ext2FS::create(StorageDevice::Partition& partition)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Ext2FS* ext2fs = new Ext2FS(partition);
 | 
							Ext2FS* ext2fs = new Ext2FS(partition);
 | 
				
			||||||
| 
						 | 
					@ -453,10 +464,7 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<void> Ext2FS::initialize_root_inode()
 | 
						BAN::ErrorOr<void> Ext2FS::initialize_root_inode()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Ext2Inode* root_inode = new Ext2Inode(this, TRY(read_inode(Ext2::Enum::ROOT_INO)), "");
 | 
							m_root_inode = TRY(Ext2Inode::create(*this, Ext2::Enum::ROOT_INO, ""));
 | 
				
			||||||
		if (root_inode == nullptr)
 | 
					 | 
				
			||||||
			return BAN::Error::from_errno(ENOMEM);
 | 
					 | 
				
			||||||
		m_root_inode = BAN::RefPtr<Inode>::adopt(root_inode);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if EXT2_DEBUG_PRINT
 | 
					#if EXT2_DEBUG_PRINT
 | 
				
			||||||
		dprintln("root inode:");
 | 
							dprintln("root inode:");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue