forked from Bananymous/banan-os
				
			
			update main #1
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -83,10 +83,16 @@ namespace Kernel
 | 
			
		|||
	class TmpSymlinkInode : public TmpInode
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<TmpSymlinkInode>> create_new(TmpFileSystem&, mode_t, uid_t, gid_t, BAN::StringView target);
 | 
			
		||||
		~TmpSymlinkInode();
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> set_link_target(BAN::StringView);
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		TmpSymlinkInode(TmpFileSystem&, ino_t, const TmpInodeInfo&, BAN::StringView target);
 | 
			
		||||
		TmpSymlinkInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class TmpDirectoryInode : public TmpInode
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,6 +215,86 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* SYMLINK INODE */
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<TmpSymlinkInode>> TmpSymlinkInode::create_new(TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid, BAN::StringView target)
 | 
			
		||||
	{
 | 
			
		||||
		auto info = create_inode_info(Mode::IFLNK | mode, uid, gid);
 | 
			
		||||
		ino_t ino = TRY(fs.allocate_inode(info));
 | 
			
		||||
 | 
			
		||||
		auto* inode_ptr = new TmpSymlinkInode(fs, ino, info);
 | 
			
		||||
		if (inode_ptr == nullptr)
 | 
			
		||||
			return BAN::Error::from_errno(ENOMEM);
 | 
			
		||||
		auto inode = BAN::RefPtr<TmpSymlinkInode>::adopt(inode_ptr);
 | 
			
		||||
 | 
			
		||||
		TRY(inode->set_link_target(target));
 | 
			
		||||
 | 
			
		||||
		return inode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TmpSymlinkInode::TmpSymlinkInode(TmpFileSystem& fs, ino_t ino, const TmpInodeInfo& info)
 | 
			
		||||
		: TmpInode(fs, ino, info)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(mode().iflnk());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TmpSymlinkInode::~TmpSymlinkInode()
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> TmpSymlinkInode::set_link_target(BAN::StringView new_target)
 | 
			
		||||
	{
 | 
			
		||||
		free_all_blocks();
 | 
			
		||||
		m_inode_info.size = 0;
 | 
			
		||||
 | 
			
		||||
		if (new_target.size() <= sizeof(TmpInodeInfo::block))
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(m_inode_info.block.data(), new_target.data(), new_target.size());
 | 
			
		||||
			m_inode_info.size = new_target.size();
 | 
			
		||||
			return {};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const size_t blocks_needed = BAN::Math::div_round_up<size_t>(new_target.size(), blksize());
 | 
			
		||||
		for (size_t i = 0; i < blocks_needed; i++)
 | 
			
		||||
		{
 | 
			
		||||
			const size_t block_index = TRY(block_index_with_allocation(i));
 | 
			
		||||
			const size_t byte_count = BAN::Math::min<size_t>(new_target.size() - i * blksize(), blksize());
 | 
			
		||||
 | 
			
		||||
			m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
 | 
			
		||||
				memcpy(bytespan.data(), new_target.data() + i * blksize(), byte_count);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			m_inode_info.size += byte_count;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::String> TmpSymlinkInode::link_target_impl()
 | 
			
		||||
	{
 | 
			
		||||
		BAN::String result;
 | 
			
		||||
		TRY(result.resize(size()));
 | 
			
		||||
 | 
			
		||||
		if ((size_t)size() <= sizeof(TmpInodeInfo::block))
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(result.data(), m_inode_info.block.data(), size());
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const size_t data_block_count = BAN::Math::div_round_up<size_t>(size(), blksize());
 | 
			
		||||
		for (size_t i = 0; i < data_block_count; i++)
 | 
			
		||||
		{
 | 
			
		||||
			const size_t block_index = TRY(block_index_with_allocation(i));
 | 
			
		||||
			const size_t byte_count = BAN::Math::min<size_t>(size() - i * blksize(), blksize());
 | 
			
		||||
 | 
			
		||||
			m_fs.with_block_buffer(block_index, [&](BAN::ByteSpan bytespan) {
 | 
			
		||||
				memcpy(result.data() + i * blksize(), bytespan.data(), byte_count);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* DIRECTORY INODE */
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<TmpDirectoryInode>> TmpDirectoryInode::create_root(TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue