forked from Bananymous/banan-os
				
			BAN: Implement Ext2 file unlinking
Ext2 inodes can now be unlinked from directories and after last inode closes (destructor gets called) we check if link count is 0 and cleanup the inode from filesystem
This commit is contained in:
		
							parent
							
								
									3566ddab00
								
							
						
					
					
						commit
						b7007016c0
					
				|  | @ -58,7 +58,7 @@ namespace Kernel | ||||||
| 		BAN::ErrorOr<void> initialize_root_inode(); | 		BAN::ErrorOr<void> initialize_root_inode(); | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<uint32_t> create_inode(const Ext2::Inode&); | 		BAN::ErrorOr<uint32_t> create_inode(const Ext2::Inode&); | ||||||
| 		BAN::ErrorOr<void> delete_inode(uint32_t); | 		void delete_inode(uint32_t); | ||||||
| 		BAN::ErrorOr<void> resize_inode(uint32_t, size_t); | 		BAN::ErrorOr<void> resize_inode(uint32_t, size_t); | ||||||
| 
 | 
 | ||||||
| 		void read_block(uint32_t, BlockBufferWrapper&); | 		void read_block(uint32_t, BlockBufferWrapper&); | ||||||
|  | @ -68,6 +68,7 @@ namespace Kernel | ||||||
| 		BlockBufferWrapper get_block_buffer(); | 		BlockBufferWrapper get_block_buffer(); | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd); | 		BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd); | ||||||
|  | 		void release_block(uint32_t block); | ||||||
| 
 | 
 | ||||||
| 		BAN::HashMap<ino_t, BAN::RefPtr<Ext2Inode>>& inode_cache() { return m_inode_cache; } | 		BAN::HashMap<ino_t, BAN::RefPtr<Ext2Inode>>& inode_cache() { return m_inode_cache; } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ namespace Kernel | ||||||
| 	class Ext2Inode final : public Inode | 	class Ext2Inode final : public Inode | ||||||
| 	{ | 	{ | ||||||
| 	public: | 	public: | ||||||
|  | 		~Ext2Inode(); | ||||||
|  | 
 | ||||||
| 		virtual ino_t ino() const override { return m_ino; }; | 		virtual ino_t ino() const override { return m_ino; }; | ||||||
| 		virtual Mode mode() const override { return { m_inode.mode }; } | 		virtual Mode mode() const override { return { m_inode.mode }; } | ||||||
| 		virtual nlink_t nlink() const override { return m_inode.links_count; } | 		virtual nlink_t nlink() const override { return m_inode.links_count; } | ||||||
|  | @ -32,6 +34,7 @@ namespace Kernel | ||||||
| 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; | 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; | ||||||
| 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | ||||||
| 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | ||||||
|  | 		virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override; | ||||||
| 		 | 		 | ||||||
| 		virtual BAN::ErrorOr<BAN::String> link_target_impl() override; | 		virtual BAN::ErrorOr<BAN::String> link_target_impl() override; | ||||||
| 
 | 
 | ||||||
|  | @ -45,6 +48,8 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name); | 		BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name); | ||||||
| 
 | 
 | ||||||
|  | 		void cleanup_from_fs(); | ||||||
|  | 
 | ||||||
| 		BAN::ErrorOr<uint32_t> allocate_new_block(); | 		BAN::ErrorOr<uint32_t> allocate_new_block(); | ||||||
| 		BAN::ErrorOr<void> sync(); | 		BAN::ErrorOr<void> sync(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -91,7 +91,7 @@ namespace Kernel | ||||||
| 		BAN::ErrorOr<void> list_next_inodes(off_t, DirectoryEntryList*, size_t); | 		BAN::ErrorOr<void> list_next_inodes(off_t, DirectoryEntryList*, size_t); | ||||||
| 		BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t); | 		BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t); | ||||||
| 		BAN::ErrorOr<void> create_directory(BAN::StringView, mode_t, uid_t, gid_t); | 		BAN::ErrorOr<void> create_directory(BAN::StringView, mode_t, uid_t, gid_t); | ||||||
| 		BAN::ErrorOr<void> delete_inode(BAN::StringView); | 		BAN::ErrorOr<void> unlink(BAN::StringView); | ||||||
| 
 | 
 | ||||||
| 		// Link API
 | 		// Link API
 | ||||||
| 		BAN::ErrorOr<BAN::String> link_target(); | 		BAN::ErrorOr<BAN::String> link_target(); | ||||||
|  | @ -109,7 +109,7 @@ namespace Kernel | ||||||
| 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t)	{ return BAN::Error::from_errno(ENOTSUP); } | 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t)	{ return BAN::Error::from_errno(ENOTSUP); } | ||||||
| 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t)		{ return BAN::Error::from_errno(ENOTSUP); } | 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t)		{ return BAN::Error::from_errno(ENOTSUP); } | ||||||
| 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t)	{ return BAN::Error::from_errno(ENOTSUP); } | 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t)	{ return BAN::Error::from_errno(ENOTSUP); } | ||||||
| 		virtual BAN::ErrorOr<void> delete_inode_impl(BAN::StringView)							{ return BAN::Error::from_errno(ENOTSUP); } | 		virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView)									{ return BAN::Error::from_errno(ENOTSUP); } | ||||||
| 
 | 
 | ||||||
| 		// Link API
 | 		// Link API
 | ||||||
| 		virtual BAN::ErrorOr<BAN::String> link_target_impl()				{ return BAN::Error::from_errno(ENOTSUP); } | 		virtual BAN::ErrorOr<BAN::String> link_target_impl()				{ return BAN::Error::from_errno(ENOTSUP); } | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ namespace Kernel | ||||||
| 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; | 		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; | ||||||
| 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | 		virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | ||||||
| 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | 		virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override; | ||||||
| 		virtual BAN::ErrorOr<void> delete_inode_impl(BAN::StringView) override; | 		virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override; | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		static constexpr size_t m_name_max = NAME_MAX; | 		static constexpr size_t m_name_max = NAME_MAX; | ||||||
|  |  | ||||||
|  | @ -212,6 +212,40 @@ namespace Kernel | ||||||
| 		return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted); | 		return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Ext2FS::delete_inode(uint32_t ino) | ||||||
|  | 	{ | ||||||
|  | 		LockGuard _(m_lock); | ||||||
|  | 
 | ||||||
|  | 		ASSERT(ino <= superblock().inodes_count); | ||||||
|  | 
 | ||||||
|  | 		auto bgd_buffer = get_block_buffer(); | ||||||
|  | 		auto bitmap_buffer = get_block_buffer(); | ||||||
|  | 
 | ||||||
|  | 		const uint32_t inode_group = (ino - 1) / superblock().inodes_per_group; | ||||||
|  | 		const uint32_t inode_index = (ino - 1) % superblock().inodes_per_group; | ||||||
|  | 
 | ||||||
|  | 		auto bgd_location = locate_block_group_descriptior(inode_group); | ||||||
|  | 		read_block(bgd_location.block, bgd_buffer); | ||||||
|  | 
 | ||||||
|  | 		auto& bgd = bgd_buffer.span().slice(bgd_location.offset).as<Ext2::BlockGroupDescriptor>(); | ||||||
|  | 		read_block(bgd.inode_bitmap, bitmap_buffer); | ||||||
|  | 
 | ||||||
|  | 		const uint32_t byte = inode_index / 8; | ||||||
|  | 		const uint32_t bit = inode_index % 8; | ||||||
|  | 		ASSERT(bitmap_buffer[byte] & (1 << bit)); | ||||||
|  | 
 | ||||||
|  | 		bitmap_buffer[byte] &= ~(1 << bit); | ||||||
|  | 		write_block(bgd.inode_bitmap, bitmap_buffer); | ||||||
|  | 
 | ||||||
|  | 		bgd.free_inodes_count++; | ||||||
|  | 		write_block(bgd_location.block, bgd_buffer); | ||||||
|  | 
 | ||||||
|  | 		if (m_inode_cache.contains(ino)) | ||||||
|  | 			m_inode_cache.remove(ino); | ||||||
|  | 
 | ||||||
|  | 		dprintln("succesfully deleted inode {}", ino); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void Ext2FS::read_block(uint32_t block, BlockBufferWrapper& buffer) | 	void Ext2FS::read_block(uint32_t block, BlockBufferWrapper& buffer) | ||||||
| 	{ | 	{ | ||||||
| 		LockGuard _(m_lock); | 		LockGuard _(m_lock); | ||||||
|  | @ -255,8 +289,7 @@ namespace Kernel | ||||||
| 		const uint32_t lba = 1024 / sector_size; | 		const uint32_t lba = 1024 / sector_size; | ||||||
| 		const uint32_t sector_count = BAN::Math::div_round_up<uint32_t>(superblock_bytes, sector_size); | 		const uint32_t sector_count = BAN::Math::div_round_up<uint32_t>(superblock_bytes, sector_size); | ||||||
| 
 | 
 | ||||||
| 		BAN::Vector<uint8_t> superblock_buffer; | 		auto superblock_buffer = get_block_buffer(); | ||||||
| 		MUST(superblock_buffer.resize(sector_count * sector_size)); |  | ||||||
| 
 | 
 | ||||||
| 		MUST(m_partition.read_sectors(lba, sector_count, superblock_buffer.span())); | 		MUST(m_partition.read_sectors(lba, sector_count, superblock_buffer.span())); | ||||||
| 		if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes)) | 		if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes)) | ||||||
|  | @ -266,7 +299,6 @@ namespace Kernel | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	Ext2FS::BlockBufferWrapper Ext2FS::get_block_buffer() | 	Ext2FS::BlockBufferWrapper Ext2FS::get_block_buffer() | ||||||
| 	{ | 	{ | ||||||
| 		LockGuard _(m_lock); | 		LockGuard _(m_lock); | ||||||
|  | @ -334,6 +366,38 @@ namespace Kernel | ||||||
| 		return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted); | 		return BAN::Error::from_error_code(ErrorCode::Ext2_Corrupted); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Ext2FS::release_block(uint32_t block) | ||||||
|  | 	{ | ||||||
|  | 		LockGuard _(m_lock); | ||||||
|  | 
 | ||||||
|  | 		ASSERT(block >= m_superblock.first_data_block); | ||||||
|  | 		ASSERT(block < m_superblock.blocks_count); | ||||||
|  | 
 | ||||||
|  | 		const uint32_t block_group = (block - m_superblock.first_data_block) / m_superblock.blocks_per_group; | ||||||
|  | 		const uint32_t block_offset = (block - m_superblock.first_data_block) % m_superblock.blocks_per_group; | ||||||
|  | 
 | ||||||
|  | 		auto bgd_buffer = get_block_buffer(); | ||||||
|  | 		auto bitmap_buffer = get_block_buffer(); | ||||||
|  | 
 | ||||||
|  | 		auto bgd_location = locate_block_group_descriptior(block_group); | ||||||
|  | 		read_block(bgd_location.block, bgd_buffer); | ||||||
|  | 
 | ||||||
|  | 		auto& bgd = bgd_buffer.span().slice(bgd_location.offset).as<Ext2::BlockGroupDescriptor>(); | ||||||
|  | 		read_block(bgd.block_bitmap, bitmap_buffer); | ||||||
|  | 
 | ||||||
|  | 		const uint32_t byte = block_offset / 8; | ||||||
|  | 		const uint32_t bit  = block_offset % 8; | ||||||
|  | 		ASSERT(bitmap_buffer[byte] & (1 << bit)); | ||||||
|  | 
 | ||||||
|  | 		bitmap_buffer[byte] &= ~(1 << bit); | ||||||
|  | 		write_block(bgd.block_bitmap, bitmap_buffer); | ||||||
|  | 
 | ||||||
|  | 		bgd.free_blocks_count++; | ||||||
|  | 		write_block(bgd_location.block, bgd_buffer); | ||||||
|  | 
 | ||||||
|  | 		dprintln("successfully freed block {}", block); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	Ext2FS::BlockLocation Ext2FS::locate_inode(uint32_t ino) | 	Ext2FS::BlockLocation Ext2FS::locate_inode(uint32_t ino) | ||||||
| 	{ | 	{ | ||||||
| 		LockGuard _(m_lock); | 		LockGuard _(m_lock); | ||||||
|  |  | ||||||
|  | @ -41,6 +41,12 @@ namespace Kernel | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	Ext2Inode::~Ext2Inode() | ||||||
|  | 	{ | ||||||
|  | 		if ((mode().ifdir() && m_inode.links_count == 1) || m_inode.links_count == 0) | ||||||
|  | 			cleanup_from_fs(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| #define VERIFY_AND_READ_BLOCK(expr) do { const uint32_t block_index = expr; ASSERT(block_index); m_fs.read_block(block_index, block_buffer); } while (false) | #define VERIFY_AND_READ_BLOCK(expr) do { const uint32_t block_index = expr; ASSERT(block_index); m_fs.read_block(block_index, block_buffer); } while (false) | ||||||
| #define VERIFY_AND_RETURN(expr) ({ const uint32_t result = expr; ASSERT(result); return result; }) | #define VERIFY_AND_RETURN(expr) ({ const uint32_t result = expr; ASSERT(result); return result; }) | ||||||
| 
 | 
 | ||||||
|  | @ -252,6 +258,21 @@ namespace Kernel | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void Ext2Inode::cleanup_from_fs() | ||||||
|  | 	{ | ||||||
|  | 		if (mode().ifdir()) | ||||||
|  | 		{ | ||||||
|  | 			// FIXME: cleanup entires '.' and '..' and verify
 | ||||||
|  | 			//        there are no other entries
 | ||||||
|  | 			ASSERT_NOT_REACHED(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		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)); | ||||||
|  | 		m_fs.delete_inode(ino()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	BAN::ErrorOr<void> Ext2Inode::list_next_inodes_impl(off_t offset, DirectoryEntryList* list, size_t list_size) | 	BAN::ErrorOr<void> Ext2Inode::list_next_inodes_impl(off_t offset, DirectoryEntryList* list, size_t list_size) | ||||||
| 	{ | 	{ | ||||||
| 		ASSERT(mode().ifdir()); | 		ASSERT(mode().ifdir()); | ||||||
|  | @ -371,9 +392,16 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		const uint32_t new_ino = TRY(m_fs.create_inode(initialize_new_inode_info(mode, uid, gid))); | 		const uint32_t new_ino = TRY(m_fs.create_inode(initialize_new_inode_info(mode, uid, gid))); | ||||||
| 
 | 
 | ||||||
| 		auto inode = MUST(Ext2Inode::create(m_fs, new_ino)); | 		auto inode_or_error = Ext2Inode::create(m_fs, new_ino); | ||||||
|  | 		if (inode_or_error.is_error()) | ||||||
|  | 		{ | ||||||
|  | 			m_fs.delete_inode(new_ino); | ||||||
|  | 			return inode_or_error.release_error(); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		MUST(link_inode_to_directory(*inode, name)); | 		auto inode = inode_or_error.release_value(); | ||||||
|  | 
 | ||||||
|  | 		TRY(link_inode_to_directory(*inode, name)); | ||||||
| 
 | 
 | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
|  | @ -387,11 +415,18 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		const uint32_t new_ino = TRY(m_fs.create_inode(initialize_new_inode_info(mode, uid, gid))); | 		const uint32_t new_ino = TRY(m_fs.create_inode(initialize_new_inode_info(mode, uid, gid))); | ||||||
| 
 | 
 | ||||||
| 		auto inode = MUST(Ext2Inode::create(m_fs, new_ino)); | 		auto inode_or_error = Ext2Inode::create(m_fs, new_ino); | ||||||
| 		MUST(inode->link_inode_to_directory(*inode, "."sv)); | 		if (inode_or_error.is_error()) | ||||||
| 		MUST(inode->link_inode_to_directory(*this, ".."sv)); | 		{ | ||||||
|  | 			m_fs.delete_inode(new_ino); | ||||||
|  | 			return inode_or_error.release_error(); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		MUST(link_inode_to_directory(*inode, name)); | 		auto inode = inode_or_error.release_value(); | ||||||
|  | 		TRY(inode->link_inode_to_directory(*inode, "."sv)); | ||||||
|  | 		TRY(inode->link_inode_to_directory(*this, ".."sv)); | ||||||
|  | 		 | ||||||
|  | 		TRY(link_inode_to_directory(*inode, name)); | ||||||
| 
 | 
 | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
|  | @ -496,6 +531,42 @@ needs_new_block: | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	BAN::ErrorOr<void> Ext2Inode::unlink_impl(BAN::StringView name) | ||||||
|  | 	{ | ||||||
|  | 		ASSERT(mode().ifdir()); | ||||||
|  | 
 | ||||||
|  | 		auto block_buffer = m_fs.get_block_buffer(); | ||||||
|  | 
 | ||||||
|  | 		for (uint32_t i = 0; i < blocks(); i++) | ||||||
|  | 		{ | ||||||
|  | 			const uint32_t block = fs_block_of_data_block_index(i); | ||||||
|  | 			m_fs.read_block(block, block_buffer); | ||||||
|  | 
 | ||||||
|  | 			blksize_t offset = 0; | ||||||
|  | 			while (offset < blksize()) | ||||||
|  | 			{ | ||||||
|  | 				auto& entry = block_buffer.span().slice(offset).as<Ext2::LinkedDirectoryEntry>(); | ||||||
|  | 				if (entry.inode && name == entry.name) | ||||||
|  | 				{ | ||||||
|  | 					auto inode = TRY(Ext2Inode::create(m_fs, entry.inode)); | ||||||
|  | 					if (inode->nlink() == 0) | ||||||
|  | 						dprintln("Corrupted filesystem. Deleting inode with 0 links"); | ||||||
|  | 					else | ||||||
|  | 						inode->m_inode.links_count--; | ||||||
|  | 
 | ||||||
|  | 					TRY(sync()); | ||||||
|  | 
 | ||||||
|  | 					// FIXME: This should expand the last inode if exists
 | ||||||
|  | 					entry.inode = 0; | ||||||
|  | 					m_fs.write_block(block, block_buffer);					 | ||||||
|  | 				} | ||||||
|  | 				offset += entry.rec_len; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return {}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| #define READ_OR_ALLOCATE_BASE_BLOCK(index_)											\ | #define READ_OR_ALLOCATE_BASE_BLOCK(index_)											\ | ||||||
| 	do {																			\ | 	do {																			\ | ||||||
| 		if (m_inode.block[index_] != 0)												\ | 		if (m_inode.block[index_] != 0)												\ | ||||||
|  |  | ||||||
|  | @ -97,13 +97,13 @@ namespace Kernel | ||||||
| 		return create_directory_impl(name, mode, uid, gid); | 		return create_directory_impl(name, mode, uid, gid); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<void> Inode::delete_inode(BAN::StringView name) | 	BAN::ErrorOr<void> Inode::unlink(BAN::StringView name) | ||||||
| 	{ | 	{ | ||||||
| 		LockGuard _(m_lock); | 		LockGuard _(m_lock); | ||||||
| 		Thread::TerminateBlocker blocker(Thread::current()); | 		Thread::TerminateBlocker blocker(Thread::current()); | ||||||
| 		if (!mode().ifdir()) | 		if (!mode().ifdir()) | ||||||
| 			return BAN::Error::from_errno(ENOTDIR); | 			return BAN::Error::from_errno(ENOTDIR); | ||||||
| 		return delete_inode_impl(name); | 		return unlink_impl(name); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<BAN::String> Inode::link_target() | 	BAN::ErrorOr<BAN::String> Inode::link_target() | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ namespace Kernel | ||||||
| 	void ProcFileSystem::on_process_delete(Process& process) | 	void ProcFileSystem::on_process_delete(Process& process) | ||||||
| 	{ | 	{ | ||||||
| 		auto path = BAN::String::formatted("{}", process.pid()); | 		auto path = BAN::String::formatted("{}", process.pid()); | ||||||
| 		MUST(m_root_inode->delete_inode(path)); | 		MUST(m_root_inode->unlink(path)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -263,8 +263,9 @@ namespace Kernel | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<void> RamDirectoryInode::delete_inode_impl(BAN::StringView name) | 	BAN::ErrorOr<void> RamDirectoryInode::unlink_impl(BAN::StringView name) | ||||||
| 	{ | 	{ | ||||||
|  | 		// FIXME: delete inodes contents only after they are closed
 | ||||||
| 		for (size_t i = 0; i < m_entries.size(); i++) | 		for (size_t i = 0; i < m_entries.size(); i++) | ||||||
| 		{ | 		{ | ||||||
| 			if (name == m_entries[i].name) | 			if (name == m_entries[i].name) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue