Kernel: Rewrite all read/write functions to use BAN::ByteSpan
This allows us to not work with raw pointers and use sized containers for reading and writing.
This commit is contained in:
		
							parent
							
								
									db5c24b2a5
								
							
						
					
					
						commit
						5bfeb9f3ca
					
				| 
						 | 
				
			
			@ -62,7 +62,7 @@ namespace LibELF
 | 
			
		|||
			return BAN::Error::from_errno(ENOEXEC);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t nread = TRY(m_inode->read(0, &m_file_header, sizeof(m_file_header)));
 | 
			
		||||
		size_t nread = TRY(m_inode->read(0, BAN::ByteSpan::from(m_file_header)));
 | 
			
		||||
		ASSERT(nread == sizeof(m_file_header));
 | 
			
		||||
 | 
			
		||||
		if (m_file_header.e_ident[EI_MAG0] != ELFMAG0 || 
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ namespace LibELF
 | 
			
		|||
		TRY(m_program_headers.resize(m_file_header.e_phnum));
 | 
			
		||||
		for (size_t i = 0; i < m_file_header.e_phnum; i++)
 | 
			
		||||
		{
 | 
			
		||||
			TRY(m_inode->read(m_file_header.e_phoff + m_file_header.e_phentsize * i, &m_program_headers[i], m_file_header.e_phentsize));
 | 
			
		||||
			TRY(m_inode->read(m_file_header.e_phoff + m_file_header.e_phentsize * i, BAN::ByteSpan::from(m_program_headers[i])));
 | 
			
		||||
 | 
			
		||||
			const auto& pheader = m_program_headers[i];
 | 
			
		||||
			if (pheader.p_type != PT_NULL && pheader.p_type != PT_LOAD)
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ namespace LibELF
 | 
			
		|||
							file_offset = vaddr - program_header.p_vaddr;
 | 
			
		||||
 | 
			
		||||
						size_t bytes = BAN::Math::min<size_t>(PAGE_SIZE - vaddr_offset, program_header.p_filesz - file_offset);
 | 
			
		||||
						TRY(m_inode->read(program_header.p_offset + file_offset, (void*)(vaddr + vaddr_offset), bytes));
 | 
			
		||||
						TRY(m_inode->read(program_header.p_offset + file_offset, { (uint8_t*)vaddr + vaddr_offset, bytes }));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					return {};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,8 @@ namespace Kernel
 | 
			
		|||
			, m_rdev(rdev)
 | 
			
		||||
		{ }
 | 
			
		||||
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override { return 0; }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t size) override { return size; };
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override { return 0; }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); };
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const dev_t m_rdev;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,8 +18,8 @@ namespace Kernel
 | 
			
		|||
			, m_rdev(rdev)
 | 
			
		||||
		{ }
 | 
			
		||||
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t size) override { return size; };
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return buffer.size(); };
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const dev_t m_rdev;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,9 @@ namespace Kernel
 | 
			
		|||
			uint8_t* data() { return m_buffer.data(); }
 | 
			
		||||
			const uint8_t* data() const { return m_buffer.data(); }
 | 
			
		||||
 | 
			
		||||
			BAN::ByteSpan span() { return m_buffer; }
 | 
			
		||||
			BAN::ConstByteSpan span() const { return m_buffer.as_const(); }
 | 
			
		||||
 | 
			
		||||
			uint8_t& operator[](size_t index) { return m_buffer[index]; }
 | 
			
		||||
			uint8_t operator[](size_t index) const { return m_buffer[index]; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,8 +34,8 @@ namespace Kernel
 | 
			
		|||
		
 | 
			
		||||
		virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
 | 
			
		||||
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <BAN/ByteSpan.h>
 | 
			
		||||
#include <BAN/RefPtr.h>
 | 
			
		||||
#include <BAN/String.h>
 | 
			
		||||
#include <BAN/StringView.h>
 | 
			
		||||
#include <BAN/WeakPtr.h>
 | 
			
		||||
#include <BAN/Vector.h>
 | 
			
		||||
#include <BAN/WeakPtr.h>
 | 
			
		||||
 | 
			
		||||
#include <kernel/API/DirectoryEntry.h>
 | 
			
		||||
#include <kernel/Credentials.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -95,8 +96,8 @@ namespace Kernel
 | 
			
		|||
		BAN::ErrorOr<BAN::String> link_target();
 | 
			
		||||
 | 
			
		||||
		// General API
 | 
			
		||||
		BAN::ErrorOr<size_t> read(off_t, void*, size_t);
 | 
			
		||||
		BAN::ErrorOr<size_t> write(off_t, const void*, size_t);
 | 
			
		||||
		BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
 | 
			
		||||
		BAN::ErrorOr<size_t> write(off_t, BAN::ConstByteSpan buffer);
 | 
			
		||||
		BAN::ErrorOr<void> truncate(size_t);
 | 
			
		||||
		bool has_data() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,8 +112,8 @@ namespace Kernel
 | 
			
		|||
		virtual BAN::ErrorOr<BAN::String> link_target_impl()				{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
 | 
			
		||||
		// General API
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t)		{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan)		{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
		virtual BAN::ErrorOr<void> truncate_impl(size_t)					{ return BAN::Error::from_errno(ENOTSUP); }
 | 
			
		||||
		virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,8 +31,8 @@ namespace Kernel
 | 
			
		|||
		virtual dev_t rdev() const override { return 0; } // FIXME
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Pipe(const Credentials&);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,23 +23,23 @@ namespace Kernel
 | 
			
		|||
	class ProcROInode final : public RamInode
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<ProcROInode>> create(Process&, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem&, mode_t, uid_t, gid_t);
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<ProcROInode>> create(Process&, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, RamFileSystem&, mode_t, uid_t, gid_t);
 | 
			
		||||
		~ProcROInode() = default;
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
 | 
			
		||||
		// You may not write here and this is always non blocking
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t)	override	{ return BAN::Error::from_errno(EINVAL); }
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan)	override	{ return BAN::Error::from_errno(EINVAL); }
 | 
			
		||||
		virtual BAN::ErrorOr<void> truncate_impl(size_t) override						{ return BAN::Error::from_errno(EINVAL); }
 | 
			
		||||
		virtual bool has_data_impl() const override										{ return true; }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ProcROInode(Process&, size_t (Process::*)(off_t, void*, size_t) const, RamFileSystem&, const FullInodeInfo&);
 | 
			
		||||
		ProcROInode(Process&, size_t (Process::*)(off_t, BAN::ByteSpan) const, RamFileSystem&, const FullInodeInfo&);
 | 
			
		||||
	
 | 
			
		||||
	private:
 | 
			
		||||
		Process& m_process;
 | 
			
		||||
		size_t (Process::*m_callback)(off_t, void*, size_t) const;
 | 
			
		||||
		size_t (Process::*m_callback)(off_t, BAN::ByteSpan) const;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,8 +70,8 @@ namespace Kernel
 | 
			
		|||
	protected:
 | 
			
		||||
		RamFileInode(RamFileSystem&, const FullInodeInfo&);
 | 
			
		||||
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ namespace Kernel::Input
 | 
			
		|||
		virtual dev_t rdev() const override { return m_rdev; }
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const dev_t m_rdev;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,8 +41,8 @@ namespace Kernel
 | 
			
		|||
		void close_all();
 | 
			
		||||
		void close_cloexec();
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<size_t> read(int fd, void* buffer, size_t count);
 | 
			
		||||
		BAN::ErrorOr<size_t> write(int fd, const void* buffer, size_t count);
 | 
			
		||||
		BAN::ErrorOr<size_t> read(int fd, BAN::ByteSpan);
 | 
			
		||||
		BAN::ErrorOr<size_t> write(int fd, BAN::ConstByteSpan);
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,9 +139,9 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		PageTable& page_table() { return m_page_table ? *m_page_table : PageTable::kernel(); }
 | 
			
		||||
 | 
			
		||||
		size_t proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
		size_t proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
		size_t proc_environ(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
		size_t proc_meminfo(off_t offset, BAN::ByteSpan) const;
 | 
			
		||||
		size_t proc_cmdline(off_t offset, BAN::ByteSpan) const;
 | 
			
		||||
		size_t proc_environ(off_t offset, BAN::ByteSpan) const;
 | 
			
		||||
 | 
			
		||||
		bool is_userspace() const { return m_is_userspace; }
 | 
			
		||||
		const userspace_info_t& userspace_info() const { return m_userspace_info; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,8 @@ namespace Kernel
 | 
			
		|||
		BAN::ErrorOr<void> rebase();
 | 
			
		||||
		BAN::ErrorOr<void> read_identify_data();
 | 
			
		||||
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, uint8_t* buffer) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint64_t sector_count, const uint8_t* buffer) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan) override;
 | 
			
		||||
		BAN::ErrorOr<void> send_command_and_block(uint64_t lba, uint64_t sector_count, Command command);
 | 
			
		||||
 | 
			
		||||
		BAN::Optional<uint32_t> find_free_command_slot();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <BAN/ByteSpan.h>
 | 
			
		||||
#include <BAN/RefPtr.h>
 | 
			
		||||
#include <BAN/Vector.h>
 | 
			
		||||
#include <kernel/InterruptController.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -22,8 +23,8 @@ namespace Kernel
 | 
			
		|||
	public:
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<ATABus>> create(uint16_t base, uint16_t ctrl, uint8_t irq);
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> read(ATADevice&, uint64_t, uint8_t, uint8_t*);
 | 
			
		||||
		BAN::ErrorOr<void> write(ATADevice&, uint64_t, uint8_t, const uint8_t*);
 | 
			
		||||
		BAN::ErrorOr<void> read(ATADevice&, uint64_t lba, uint64_t sector_count, BAN::ByteSpan);
 | 
			
		||||
		BAN::ErrorOr<void> write(ATADevice&, uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan);
 | 
			
		||||
 | 
			
		||||
		virtual void handle_irq() override;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,8 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
			virtual dev_t rdev() const override { return m_rdev; }
 | 
			
		||||
 | 
			
		||||
			virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
			virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t) override;
 | 
			
		||||
			virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
			virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
 | 
			
		||||
 | 
			
		||||
		protected:
 | 
			
		||||
			ATABaseDevice();
 | 
			
		||||
| 
						 | 
				
			
			@ -63,8 +63,8 @@ namespace Kernel
 | 
			
		|||
	private:
 | 
			
		||||
		ATADevice(BAN::RefPtr<ATABus>, ATABus::DeviceType, bool is_secodary);
 | 
			
		||||
		
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t, uint64_t, uint8_t*) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t, uint64_t, const uint8_t*) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t, uint64_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t, uint64_t, BAN::ConstByteSpan) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		BAN::RefPtr<ATABus> m_bus;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <BAN/Array.h>
 | 
			
		||||
#include <BAN/ByteSpan.h>
 | 
			
		||||
#include <kernel/Memory/Types.h>
 | 
			
		||||
#include <kernel/SpinLock.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,8 +16,8 @@ namespace Kernel
 | 
			
		|||
		DiskCache(size_t sector_size, StorageDevice&);
 | 
			
		||||
		~DiskCache();
 | 
			
		||||
 | 
			
		||||
		bool read_from_cache(uint64_t sector, uint8_t* buffer);
 | 
			
		||||
		BAN::ErrorOr<void> write_to_cache(uint64_t sector, const uint8_t* buffer, bool dirty);
 | 
			
		||||
		bool read_from_cache(uint64_t sector, BAN::ByteSpan);
 | 
			
		||||
		BAN::ErrorOr<void> write_to_cache(uint64_t sector, BAN::ConstByteSpan, bool dirty);
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> sync();
 | 
			
		||||
		size_t release_clean_pages(size_t);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,8 +30,8 @@ namespace Kernel
 | 
			
		|||
		const char* label() const { return m_label; }
 | 
			
		||||
		const StorageDevice& device() const { return m_device; }
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer);
 | 
			
		||||
		BAN::ErrorOr<void> write_sectors(uint64_t lba, uint8_t sector_count, const uint8_t* buffer);
 | 
			
		||||
		BAN::ErrorOr<void> read_sectors(uint64_t lba, uint8_t sector_count, BAN::ByteSpan);
 | 
			
		||||
		BAN::ErrorOr<void> write_sectors(uint64_t lba, uint8_t sector_count, BAN::ConstByteSpan);
 | 
			
		||||
		
 | 
			
		||||
		virtual BAN::StringView name() const override { return m_name; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ namespace Kernel
 | 
			
		|||
		virtual dev_t rdev() const override { return m_rdev; }
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		const dev_t m_rdev;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,8 +73,8 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		BAN::ErrorOr<void> initialize_partitions();
 | 
			
		||||
 | 
			
		||||
		BAN::ErrorOr<void> read_sectors(uint64_t lba, uint64_t sector_count, uint8_t* buffer);
 | 
			
		||||
		BAN::ErrorOr<void> write_sectors(uint64_t lba, uint64_t sector_count, const uint8_t* buffer);
 | 
			
		||||
		BAN::ErrorOr<void> read_sectors(uint64_t lba, uint64_t sector_count, BAN::ByteSpan);
 | 
			
		||||
		BAN::ErrorOr<void> write_sectors(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan);
 | 
			
		||||
 | 
			
		||||
		virtual uint32_t sector_size() const = 0;
 | 
			
		||||
		virtual uint64_t total_size() const = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,8 +86,8 @@ namespace Kernel
 | 
			
		|||
		virtual bool is_storage_device() const override { return true; }
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, uint8_t* buffer) = 0;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint64_t sector_count, const uint8_t* buffer) = 0;
 | 
			
		||||
		virtual BAN::ErrorOr<void> read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan) = 0;
 | 
			
		||||
		virtual BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan) = 0;
 | 
			
		||||
		void add_disk_cache();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,8 +49,8 @@ namespace Kernel
 | 
			
		|||
		{ }
 | 
			
		||||
 | 
			
		||||
		virtual void putchar_impl(uint8_t ch) = 0;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, const void*, size_t) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void do_backspace();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,10 +12,10 @@ namespace Kernel
 | 
			
		|||
		return BAN::RefPtr<ZeroDevice>::adopt(result);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> ZeroDevice::read_impl(off_t, void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> ZeroDevice::read_impl(off_t, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		memset(buffer, 0, bytes);
 | 
			
		||||
		return bytes;
 | 
			
		||||
		memset(buffer.data(), 0, buffer.size());
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ namespace Kernel
 | 
			
		|||
			BAN::Vector<uint8_t> superblock_buffer;
 | 
			
		||||
			TRY(superblock_buffer.resize(sector_count * sector_size));
 | 
			
		||||
 | 
			
		||||
			TRY(m_partition.read_sectors(lba, sector_count, superblock_buffer.data()));
 | 
			
		||||
			TRY(m_partition.read_sectors(lba, sector_count, superblock_buffer.span()));
 | 
			
		||||
 | 
			
		||||
			memcpy(&m_superblock, superblock_buffer.data(), sizeof(Ext2::Superblock));
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +223,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		ASSERT(block >= 2);
 | 
			
		||||
		ASSERT(buffer.size() >= block_size);
 | 
			
		||||
		MUST(m_partition.read_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.data()));
 | 
			
		||||
		MUST(m_partition.read_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ext2FS::write_block(uint32_t block, const BlockBufferWrapper& buffer)
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		ASSERT(block >= 2);
 | 
			
		||||
		ASSERT(buffer.size() >= block_size);
 | 
			
		||||
		MUST(m_partition.write_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.data()));
 | 
			
		||||
		MUST(m_partition.write_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ext2FS::sync_superblock()
 | 
			
		||||
| 
						 | 
				
			
			@ -258,11 +258,11 @@ namespace Kernel
 | 
			
		|||
		BAN::Vector<uint8_t> superblock_buffer;
 | 
			
		||||
		MUST(superblock_buffer.resize(sector_count * sector_size));
 | 
			
		||||
 | 
			
		||||
		MUST(m_partition.read_sectors(lba, sector_count, superblock_buffer.data()));
 | 
			
		||||
		MUST(m_partition.read_sectors(lba, sector_count, superblock_buffer.span()));
 | 
			
		||||
		if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes))
 | 
			
		||||
		{
 | 
			
		||||
			memcpy(superblock_buffer.data(), &m_superblock, superblock_bytes);
 | 
			
		||||
			MUST(m_partition.write_sectors(lba, sector_count, superblock_buffer.data()));
 | 
			
		||||
			MUST(m_partition.write_sectors(lba, sector_count, superblock_buffer.span()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,19 +100,21 @@ namespace Kernel
 | 
			
		|||
		return BAN::Error::from_errno(ENOTSUP);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Ext2Inode::read_impl(off_t offset, void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> Ext2Inode::read_impl(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		// FIXME: update atime if needed
 | 
			
		||||
 | 
			
		||||
		ASSERT(!mode().ifdir());
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
 | 
			
		||||
		if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX)
 | 
			
		||||
		if (offset >= UINT32_MAX || buffer.size() >= UINT32_MAX || buffer.size() >= (size_t)(UINT32_MAX - offset))
 | 
			
		||||
			return BAN::Error::from_errno(EOVERFLOW);
 | 
			
		||||
 | 
			
		||||
		if (offset >= m_inode.size)
 | 
			
		||||
			return 0;
 | 
			
		||||
		if (offset + count > m_inode.size)
 | 
			
		||||
		
 | 
			
		||||
		uint32_t count = buffer.size();
 | 
			
		||||
		if (offset + buffer.size() > m_inode.size)
 | 
			
		||||
			count = m_inode.size - offset;
 | 
			
		||||
 | 
			
		||||
		const uint32_t block_size = blksize();
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +133,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
			uint32_t copy_offset = (offset + n_read) % block_size;
 | 
			
		||||
			uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - copy_offset, count - n_read);
 | 
			
		||||
			memcpy((uint8_t*)buffer + n_read, block_buffer.data() + copy_offset, to_copy);
 | 
			
		||||
			memcpy(buffer.data() + n_read, block_buffer.data() + copy_offset, to_copy);
 | 
			
		||||
 | 
			
		||||
			n_read += to_copy;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,26 +141,25 @@ namespace Kernel
 | 
			
		|||
		return n_read;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Ext2Inode::write_impl(off_t offset, const void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> Ext2Inode::write_impl(off_t offset, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		// FIXME: update atime if needed
 | 
			
		||||
 | 
			
		||||
		ASSERT(!mode().ifdir());
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
 | 
			
		||||
		if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX)
 | 
			
		||||
		if (offset >= UINT32_MAX || buffer.size() >= UINT32_MAX || buffer.size() >= (size_t)(UINT32_MAX - offset))
 | 
			
		||||
			return BAN::Error::from_errno(EOVERFLOW);
 | 
			
		||||
 | 
			
		||||
		if (m_inode.size < offset + count)
 | 
			
		||||
			TRY(truncate_impl(offset + count));
 | 
			
		||||
		if (m_inode.size < offset + buffer.size())
 | 
			
		||||
			TRY(truncate_impl(offset + buffer.size()));
 | 
			
		||||
 | 
			
		||||
		const uint32_t block_size = blksize();
 | 
			
		||||
 | 
			
		||||
		auto block_buffer = m_fs.get_block_buffer();
 | 
			
		||||
 | 
			
		||||
		const uint8_t* u8buffer = (const uint8_t*)buffer;
 | 
			
		||||
 | 
			
		||||
		size_t to_write = count;
 | 
			
		||||
		size_t written = 0;
 | 
			
		||||
		size_t to_write = buffer.size();
 | 
			
		||||
 | 
			
		||||
		// Write partial block
 | 
			
		||||
		if (offset % block_size)
 | 
			
		||||
| 
						 | 
				
			
			@ -169,10 +170,10 @@ namespace Kernel
 | 
			
		|||
			uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - block_offset, to_write);
 | 
			
		||||
 | 
			
		||||
			m_fs.read_block(block_index, block_buffer);
 | 
			
		||||
			memcpy(block_buffer.data() + block_offset, u8buffer, to_copy);
 | 
			
		||||
			memcpy(block_buffer.data() + block_offset, buffer.data(), to_copy);
 | 
			
		||||
			m_fs.write_block(block_index, block_buffer);
 | 
			
		||||
 | 
			
		||||
			u8buffer += to_copy;
 | 
			
		||||
			written += to_copy;
 | 
			
		||||
			offset += to_copy;
 | 
			
		||||
			to_write -= to_copy;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -181,10 +182,10 @@ namespace Kernel
 | 
			
		|||
		{
 | 
			
		||||
			uint32_t block_index = fs_block_of_data_block_index(offset / block_size);
 | 
			
		||||
 | 
			
		||||
			memcpy(block_buffer.data(), u8buffer, block_buffer.size());
 | 
			
		||||
			memcpy(block_buffer.data(), buffer.data() + written, block_buffer.size());
 | 
			
		||||
			m_fs.write_block(block_index, block_buffer);
 | 
			
		||||
 | 
			
		||||
			u8buffer += block_size;
 | 
			
		||||
			written += block_size;
 | 
			
		||||
			offset += block_size;
 | 
			
		||||
			to_write -= block_size;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -194,11 +195,11 @@ namespace Kernel
 | 
			
		|||
			uint32_t block_index = fs_block_of_data_block_index(offset / block_size);
 | 
			
		||||
 | 
			
		||||
			m_fs.read_block(block_index, block_buffer);
 | 
			
		||||
			memcpy(block_buffer.data(), u8buffer, to_write);
 | 
			
		||||
			memcpy(block_buffer.data(), buffer.data() + written, to_write);
 | 
			
		||||
			m_fs.write_block(block_index, block_buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return count;
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> Ext2Inode::truncate_impl(size_t new_size)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,22 +102,22 @@ namespace Kernel
 | 
			
		|||
		return link_target_impl();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Inode::read(off_t offset, void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
		if (mode().ifdir())
 | 
			
		||||
			return BAN::Error::from_errno(EISDIR);
 | 
			
		||||
		return read_impl(offset, buffer, bytes);
 | 
			
		||||
		return read_impl(offset, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Inode::write(off_t offset, const void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> Inode::write(off_t offset, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
		if (mode().ifdir())
 | 
			
		||||
			return BAN::Error::from_errno(EISDIR);
 | 
			
		||||
		return write_impl(offset, buffer, bytes);
 | 
			
		||||
		return write_impl(offset, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> Inode::truncate(size_t size)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ namespace Kernel
 | 
			
		|||
			m_semaphore.unblock();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Pipe::read_impl(off_t, void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		while (m_buffer.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -51,8 +51,8 @@ namespace Kernel
 | 
			
		|||
			m_lock.lock();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(count, m_buffer.size());
 | 
			
		||||
		memcpy(buffer, m_buffer.data(), to_copy);
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer.size());
 | 
			
		||||
		memcpy(buffer.data(), m_buffer.data(), to_copy);
 | 
			
		||||
 | 
			
		||||
		memmove(m_buffer.data(), m_buffer.data() + to_copy, m_buffer.size() - to_copy);
 | 
			
		||||
		MUST(m_buffer.resize(m_buffer.size() - to_copy));
 | 
			
		||||
| 
						 | 
				
			
			@ -64,14 +64,14 @@ namespace Kernel
 | 
			
		|||
		return to_copy;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Pipe::write_impl(off_t, const void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
 | 
			
		||||
		size_t old_size = m_buffer.size();
 | 
			
		||||
 | 
			
		||||
		TRY(m_buffer.resize(old_size + count));
 | 
			
		||||
		memcpy(m_buffer.data() + old_size, buffer, count);
 | 
			
		||||
		TRY(m_buffer.resize(old_size + buffer.size()));
 | 
			
		||||
		memcpy(m_buffer.data() + old_size, buffer.data(), buffer.size());
 | 
			
		||||
 | 
			
		||||
		timespec current_time = SystemTimer::get().real_time();
 | 
			
		||||
		m_mtime = current_time;
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +79,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		m_semaphore.unblock();
 | 
			
		||||
 | 
			
		||||
		return count;
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ namespace Kernel
 | 
			
		|||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<ProcROInode>> ProcROInode::create(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<ProcROInode>> ProcROInode::create(Process& process, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
 | 
			
		||||
	{
 | 
			
		||||
		FullInodeInfo inode_info(fs, mode, uid, gid);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ namespace Kernel
 | 
			
		|||
		return BAN::RefPtr<ProcROInode>::adopt(inode_ptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ProcROInode::ProcROInode(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, const FullInodeInfo& inode_info)
 | 
			
		||||
	ProcROInode::ProcROInode(Process& process, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, RamFileSystem& fs, const FullInodeInfo& inode_info)
 | 
			
		||||
		: RamInode(fs, inode_info)
 | 
			
		||||
		, m_process(process)
 | 
			
		||||
		, m_callback(callback)
 | 
			
		||||
| 
						 | 
				
			
			@ -43,12 +43,12 @@ namespace Kernel
 | 
			
		|||
		m_inode_info.mode |= Inode::Mode::IFREG;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> ProcROInode::read_impl(off_t offset, void* buffer, size_t buffer_size)
 | 
			
		||||
	BAN::ErrorOr<size_t> ProcROInode::read_impl(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if ((size_t)offset >= sizeof(proc_meminfo_t))
 | 
			
		||||
			return 0;
 | 
			
		||||
		return (m_process.*m_callback)(offset, buffer, buffer_size);
 | 
			
		||||
		return (m_process.*m_callback)(offset, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,23 +48,23 @@ namespace Kernel
 | 
			
		|||
		m_inode_info.mode |= Inode::Mode::IFREG;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> RamFileInode::read_impl(off_t offset, void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> RamFileInode::read_impl(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if (offset >= size())
 | 
			
		||||
			return 0;
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(m_inode_info.size - offset, bytes);
 | 
			
		||||
		memcpy(buffer, m_data.data(), to_copy);
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(m_inode_info.size - offset, buffer.size());
 | 
			
		||||
		memcpy(buffer.data(), m_data.data(), to_copy);
 | 
			
		||||
		return to_copy;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> RamFileInode::write_impl(off_t offset, const void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> RamFileInode::write_impl(off_t offset, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if (offset + bytes > (size_t)size())
 | 
			
		||||
			TRY(truncate_impl(offset + bytes));
 | 
			
		||||
		memcpy(m_data.data() + offset, buffer, bytes);
 | 
			
		||||
		return bytes;
 | 
			
		||||
		if (offset + buffer.size() > (size_t)size())
 | 
			
		||||
			TRY(truncate_impl(offset + buffer.size()));
 | 
			
		||||
		memcpy(m_data.data() + offset, buffer.data(), buffer.size());
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> RamFileInode::truncate_impl(size_t new_size)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ namespace Kernel
 | 
			
		|||
		BAN::Vector<uint8_t> file_data;
 | 
			
		||||
		TRY(file_data.resize(inode->size()));
 | 
			
		||||
	
 | 
			
		||||
		TRY(inode->read(0, file_data.data(), file_data.size()));
 | 
			
		||||
		TRY(inode->read(0, file_data.span()));
 | 
			
		||||
 | 
			
		||||
		if (file_data.size() < 4)
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Font_FileTooSmall);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,9 +217,9 @@ namespace Kernel::Input
 | 
			
		|||
		append_command_queue(Command::SET_LEDS, new_leds);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, void* buffer, size_t size)
 | 
			
		||||
	BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		if (size < sizeof(KeyEvent))
 | 
			
		||||
		if (buffer.size() < sizeof(KeyEvent))
 | 
			
		||||
			return BAN::Error::from_errno(ENOBUFS);
 | 
			
		||||
 | 
			
		||||
		while (true)
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +231,7 @@ namespace Kernel::Input
 | 
			
		|||
			if (m_event_queue.empty())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			*(KeyEvent*)buffer = m_event_queue.front();
 | 
			
		||||
			buffer.as<KeyEvent>() = m_event_queue.front();
 | 
			
		||||
			m_event_queue.pop();
 | 
			
		||||
 | 
			
		||||
			return sizeof(KeyEvent);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ namespace Kernel
 | 
			
		|||
				page_table.unmap_page(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (auto ret = inode->write(i * PAGE_SIZE, page_buffer, PAGE_SIZE); ret.is_error())
 | 
			
		||||
			if (auto ret = inode->write(i * PAGE_SIZE, BAN::ConstByteSpan::from(page_buffer)); ret.is_error())
 | 
			
		||||
				dwarnln("{}", ret.error());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
			// Zero out the new page
 | 
			
		||||
			if (&PageTable::current() == &m_page_table)
 | 
			
		||||
				read_ret = m_inode->read(file_offset, (void*)vaddr, bytes);
 | 
			
		||||
				read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)vaddr, bytes));
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				auto& page_table = PageTable::current();
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ namespace Kernel
 | 
			
		|||
				ASSERT(page_table.is_page_free(0));
 | 
			
		||||
 | 
			
		||||
				page_table.map_page_at(paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
 | 
			
		||||
				read_ret = m_inode->read(file_offset, (void*)0, bytes);
 | 
			
		||||
				read_ret = m_inode->read(file_offset, BAN::ByteSpan((uint8_t*)0, bytes));
 | 
			
		||||
				memset((void*)0, 0x00, PAGE_SIZE);
 | 
			
		||||
				page_table.unmap_page(0);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +156,7 @@ namespace Kernel
 | 
			
		|||
				size_t offset = vaddr - m_vaddr;
 | 
			
		||||
				size_t bytes = BAN::Math::min<size_t>(m_size - offset, PAGE_SIZE);
 | 
			
		||||
 | 
			
		||||
				TRY(m_inode->read(offset, m_shared_data->page_buffer, bytes));
 | 
			
		||||
				TRY(m_inode->read(offset, BAN::ByteSpan(m_shared_data->page_buffer, bytes)));
 | 
			
		||||
 | 
			
		||||
				auto& page_table = PageTable::current();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,24 +264,24 @@ namespace Kernel
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> OpenFileDescriptorSet::read(int fd, void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> OpenFileDescriptorSet::read(int fd, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		TRY(validate_fd(fd));
 | 
			
		||||
		auto& open_file = m_open_files[fd];
 | 
			
		||||
		if ((open_file->flags & O_NONBLOCK) && !open_file->inode->has_data())
 | 
			
		||||
			return 0;
 | 
			
		||||
		size_t nread = TRY(open_file->inode->read(open_file->offset, buffer, count));
 | 
			
		||||
		size_t nread = TRY(open_file->inode->read(open_file->offset, buffer));
 | 
			
		||||
		open_file->offset += nread;
 | 
			
		||||
		return nread;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> OpenFileDescriptorSet::write(int fd, const void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> OpenFileDescriptorSet::write(int fd, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		TRY(validate_fd(fd));
 | 
			
		||||
		auto& open_file = m_open_files[fd];
 | 
			
		||||
		if (open_file->flags & O_APPEND)
 | 
			
		||||
			open_file->offset = open_file->inode->size();
 | 
			
		||||
		size_t nwrite = TRY(open_file->inode->write(open_file->offset, buffer, count));
 | 
			
		||||
		size_t nwrite = TRY(open_file->inode->write(open_file->offset, buffer));
 | 
			
		||||
		open_file->offset += nwrite;
 | 
			
		||||
		return nwrite;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,7 +260,7 @@ namespace Kernel
 | 
			
		|||
			thread->set_terminating();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t Process::proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	size_t Process::proc_meminfo(off_t offset, BAN::ByteSpan buffer) const
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if ((size_t)offset >= sizeof(proc_meminfo_t))
 | 
			
		||||
| 
						 | 
				
			
			@ -290,12 +290,12 @@ namespace Kernel
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t bytes = BAN::Math::min<size_t>(sizeof(proc_meminfo_t) - offset, buffer_size);
 | 
			
		||||
		memcpy(buffer, (uint8_t*)&meminfo + offset, bytes);
 | 
			
		||||
		size_t bytes = BAN::Math::min<size_t>(sizeof(proc_meminfo_t) - offset, buffer.size());
 | 
			
		||||
		memcpy(buffer.data(), (uint8_t*)&meminfo + offset, bytes);
 | 
			
		||||
		return bytes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static size_t read_from_vec_of_str(const BAN::Vector<BAN::String>& container, size_t start, void* buffer, size_t buffer_size)
 | 
			
		||||
	static size_t read_from_vec_of_str(const BAN::Vector<BAN::String>& container, size_t start, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		size_t offset = 0;
 | 
			
		||||
		size_t written = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,11 +307,11 @@ namespace Kernel
 | 
			
		|||
				if (offset < start)
 | 
			
		||||
					elem_offset = start - offset;
 | 
			
		||||
 | 
			
		||||
				size_t bytes = BAN::Math::min<size_t>(elem.size() + 1 - elem_offset, buffer_size - written);
 | 
			
		||||
				memcpy((uint8_t*)buffer + written, elem.data() + elem_offset, bytes);
 | 
			
		||||
				size_t bytes = BAN::Math::min<size_t>(elem.size() + 1 - elem_offset, buffer.size() - written);
 | 
			
		||||
				memcpy(buffer.data() + written, elem.data() + elem_offset, bytes);
 | 
			
		||||
 | 
			
		||||
				written += bytes;
 | 
			
		||||
				if (written >= buffer_size)
 | 
			
		||||
				if (written >= buffer.size())
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			offset += elem.size() + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -319,16 +319,16 @@ namespace Kernel
 | 
			
		|||
		return written;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t Process::proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	size_t Process::proc_cmdline(off_t offset, BAN::ByteSpan buffer) const
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		return read_from_vec_of_str(m_cmdline, offset, buffer, buffer_size);
 | 
			
		||||
		return read_from_vec_of_str(m_cmdline, offset, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t Process::proc_environ(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	size_t Process::proc_environ(off_t offset, BAN::ByteSpan buffer) const
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		return read_from_vec_of_str(m_environ, offset, buffer, buffer_size);
 | 
			
		||||
		return read_from_vec_of_str(m_environ, offset, buffer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<long> Process::sys_exit(int status)
 | 
			
		||||
| 
						 | 
				
			
			@ -723,14 +723,14 @@ namespace Kernel
 | 
			
		|||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		validate_pointer_access(buffer, count);
 | 
			
		||||
		return TRY(m_open_file_descriptors.read(fd, buffer, count));
 | 
			
		||||
		return TRY(m_open_file_descriptors.read(fd, BAN::ByteSpan((uint8_t*)buffer, count)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<long> Process::sys_write(int fd, const void* buffer, size_t count)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		validate_pointer_access(buffer, count);
 | 
			
		||||
		return TRY(m_open_file_descriptors.write(fd, buffer, count));
 | 
			
		||||
		return TRY(m_open_file_descriptors.write(fd, BAN::ByteSpan((uint8_t*)buffer, count)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,28 +158,30 @@ namespace Kernel
 | 
			
		|||
			__builtin_ia32_pause();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> AHCIDevice::read_sectors_impl(uint64_t lba, uint64_t sector_count, uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> AHCIDevice::read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
		const size_t sectors_per_page = PAGE_SIZE / sector_size();
 | 
			
		||||
		for (uint64_t sector_off = 0; sector_off < sector_count; sector_off += sectors_per_page)
 | 
			
		||||
		{
 | 
			
		||||
			uint64_t to_read = BAN::Math::min<uint64_t>(sector_count - sector_off, sectors_per_page);
 | 
			
		||||
 | 
			
		||||
			TRY(send_command_and_block(lba + sector_off, to_read, Command::Read));
 | 
			
		||||
			memcpy(buffer + sector_off * sector_size(), (void*)m_data_dma_region->vaddr(), to_read * sector_size());
 | 
			
		||||
			memcpy(buffer.data() + sector_off * sector_size(), (void*)m_data_dma_region->vaddr(), to_read * sector_size());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> AHCIDevice::write_sectors_impl(uint64_t lba, uint64_t sector_count, const uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> AHCIDevice::write_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
		const size_t sectors_per_page = PAGE_SIZE / sector_size();
 | 
			
		||||
		for (uint64_t sector_off = 0; sector_off < sector_count; sector_off += sectors_per_page)
 | 
			
		||||
		{
 | 
			
		||||
			uint64_t to_read = BAN::Math::min<uint64_t>(sector_count - sector_off, sectors_per_page);
 | 
			
		||||
 | 
			
		||||
			memcpy((void*)m_data_dma_region->vaddr(), buffer + sector_off * sector_size(), to_read * sector_size());
 | 
			
		||||
			memcpy((void*)m_data_dma_region->vaddr(), buffer.data() + sector_off * sector_size(), to_read * sector_size());
 | 
			
		||||
			TRY(send_command_and_block(lba + sector_off, to_read, Command::Write));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,8 +228,10 @@ namespace Kernel
 | 
			
		|||
		return BAN::Error::from_error_code(ErrorCode::None);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> ATABus::read(ATADevice& device, uint64_t lba, uint8_t sector_count, uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> ATABus::read(ATADevice& device, uint64_t lba, uint64_t sector_count, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(sector_count <= 0xFF);
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * device.sector_size());
 | 
			
		||||
		if (lba + sector_count > device.sector_count())
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -251,7 +253,7 @@ namespace Kernel
 | 
			
		|||
			for (uint32_t sector = 0; sector < sector_count; sector++)
 | 
			
		||||
			{
 | 
			
		||||
				block_until_irq();
 | 
			
		||||
				read_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device.words_per_sector(), device.words_per_sector());
 | 
			
		||||
				read_buffer(ATA_PORT_DATA, (uint16_t*)buffer.data() + sector * device.words_per_sector(), device.words_per_sector());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -263,8 +265,10 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> ATABus::write(ATADevice& device, uint64_t lba, uint8_t sector_count, const uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> ATABus::write(ATADevice& device, uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(sector_count <= 0xFF);
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * device.sector_size());
 | 
			
		||||
		if (lba + sector_count > device.sector_count())
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +289,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
			for (uint32_t sector = 0; sector < sector_count; sector++)
 | 
			
		||||
			{
 | 
			
		||||
				write_buffer(ATA_PORT_DATA, (uint16_t*)buffer + sector * device.words_per_sector(), device.words_per_sector());
 | 
			
		||||
				write_buffer(ATA_PORT_DATA, (uint16_t*)buffer.data() + sector * device.words_per_sector(), device.words_per_sector());
 | 
			
		||||
				block_until_irq();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,24 +82,24 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> detail::ATABaseDevice::read_impl(off_t offset, void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> detail::ATABaseDevice::read_impl(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		if (offset % sector_size())
 | 
			
		||||
			return BAN::Error::from_errno(EINVAL);
 | 
			
		||||
		if (bytes % sector_size())
 | 
			
		||||
		if (buffer.size() % sector_size())
 | 
			
		||||
			return BAN::Error::from_errno(EINVAL);
 | 
			
		||||
		TRY(read_sectors(offset / sector_size(), bytes / sector_size(), (uint8_t*)buffer));
 | 
			
		||||
		return bytes;
 | 
			
		||||
		TRY(read_sectors(offset / sector_size(), buffer.size() / sector_size(), buffer));
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> detail::ATABaseDevice::write_impl(off_t offset, const void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> detail::ATABaseDevice::write_impl(off_t offset, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		if (offset % sector_size())
 | 
			
		||||
			return BAN::Error::from_errno(EINVAL);
 | 
			
		||||
		if (bytes % sector_size())
 | 
			
		||||
		if (buffer.size() % sector_size())
 | 
			
		||||
			return BAN::Error::from_errno(EINVAL);
 | 
			
		||||
		TRY(write_sectors(offset / sector_size(), bytes / sector_size(), (const uint8_t*)buffer));
 | 
			
		||||
		return bytes;
 | 
			
		||||
		TRY(write_sectors(offset / sector_size(), buffer.size() / sector_size(), buffer));
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<ATADevice>> ATADevice::create(BAN::RefPtr<ATABus> bus, ATABus::DeviceType type, bool is_secondary, BAN::Span<const uint16_t> identify_data)
 | 
			
		||||
| 
						 | 
				
			
			@ -118,14 +118,16 @@ namespace Kernel
 | 
			
		|||
		, m_is_secondary(is_secondary)
 | 
			
		||||
	{ }
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> ATADevice::read_sectors_impl(uint64_t lba, uint64_t sector_count, uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> ATADevice::read_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
		TRY(m_bus->read(*this, lba, sector_count, buffer));
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> ATADevice::write_sectors_impl(uint64_t lba, uint64_t sector_count, const uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> ATADevice::write_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
		TRY(m_bus->write(*this, lba, sector_count, buffer));
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,10 @@ namespace Kernel
 | 
			
		|||
		release_all_pages();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool DiskCache::read_from_cache(uint64_t sector, uint8_t* buffer)
 | 
			
		||||
	bool DiskCache::read_from_cache(uint64_t sector, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= m_sector_size);
 | 
			
		||||
 | 
			
		||||
		uint64_t sectors_per_page = PAGE_SIZE / m_sector_size;
 | 
			
		||||
		uint64_t page_cache_offset = sector % sectors_per_page;
 | 
			
		||||
		uint64_t page_cache_start = sector - page_cache_offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +48,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
			CriticalScope _;
 | 
			
		||||
			page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
 | 
			
		||||
			memcpy(buffer, (void*)(page_cache_offset * m_sector_size), m_sector_size);
 | 
			
		||||
			memcpy(buffer.data(), (void*)(page_cache_offset * m_sector_size), m_sector_size);
 | 
			
		||||
			page_table.unmap_page(0);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,8 +57,9 @@ namespace Kernel
 | 
			
		|||
		return false;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> DiskCache::write_to_cache(uint64_t sector, const uint8_t* buffer, bool dirty)
 | 
			
		||||
	BAN::ErrorOr<void> DiskCache::write_to_cache(uint64_t sector, BAN::ConstByteSpan buffer, bool dirty)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= m_sector_size);
 | 
			
		||||
		uint64_t sectors_per_page = PAGE_SIZE / m_sector_size;
 | 
			
		||||
		uint64_t page_cache_offset = sector % sectors_per_page;
 | 
			
		||||
		uint64_t page_cache_start = sector - page_cache_offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +83,7 @@ namespace Kernel
 | 
			
		|||
			{
 | 
			
		||||
				CriticalScope _;
 | 
			
		||||
				page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
 | 
			
		||||
				memcpy((void*)(page_cache_offset * m_sector_size), buffer, m_sector_size);
 | 
			
		||||
				memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
 | 
			
		||||
				page_table.unmap_page(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -110,8 +113,8 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		{
 | 
			
		||||
			CriticalScope _;
 | 
			
		||||
			page_table.map_page_at(cache.paddr, 0, PageTable::Flags::Present);
 | 
			
		||||
			memcpy((void*)(page_cache_offset * m_sector_size), buffer, m_sector_size);
 | 
			
		||||
			page_table.map_page_at(cache.paddr, 0, PageTable::Flags::ReadWrite | PageTable::Flags::Present);
 | 
			
		||||
			memcpy((void*)(page_cache_offset * m_sector_size), buffer.data(), m_sector_size);
 | 
			
		||||
			page_table.unmap_page(0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +152,8 @@ namespace Kernel
 | 
			
		|||
				else
 | 
			
		||||
				{
 | 
			
		||||
					dprintln_if(DEBUG_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
 | 
			
		||||
					TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, m_sync_cache.data() + sector_start * m_sector_size));
 | 
			
		||||
					auto data_slice = m_sync_cache.span().slice(sector_start * m_sector_size, sector_count * m_sector_size);
 | 
			
		||||
					TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, data_slice));
 | 
			
		||||
					sector_start += sector_count + 1;
 | 
			
		||||
					sector_count = 0;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +162,8 @@ namespace Kernel
 | 
			
		|||
			if (sector_count > 0)
 | 
			
		||||
			{
 | 
			
		||||
				dprintln_if(DEBUG_SYNC, "syncing {}->{}", cache.first_sector + sector_start, cache.first_sector + sector_start + sector_count);
 | 
			
		||||
				TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, m_sync_cache.data() + sector_start * m_sector_size));
 | 
			
		||||
				auto data_slice = m_sync_cache.span().slice(sector_start * m_sector_size, sector_count * m_sector_size);
 | 
			
		||||
				TRY(m_device.write_sectors_impl(cache.first_sector + sector_start, sector_count, data_slice));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cache.dirty_mask = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,8 +153,10 @@ namespace Kernel
 | 
			
		|||
		if (total_size() < sizeof(GPTHeader))
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_GPTHeader);
 | 
			
		||||
 | 
			
		||||
		BAN::Vector<uint8_t> lba1(sector_size());
 | 
			
		||||
		TRY(read_sectors(1, 1, lba1.data()));
 | 
			
		||||
		BAN::Vector<uint8_t> lba1;
 | 
			
		||||
		TRY(lba1.resize(sector_size()));
 | 
			
		||||
 | 
			
		||||
		TRY(read_sectors(1, 1, lba1.span()));
 | 
			
		||||
 | 
			
		||||
		const GPTHeader& header = *(const GPTHeader*)lba1.data();
 | 
			
		||||
		if (!is_valid_gpt_header(header, sector_size()))
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +171,7 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		BAN::Vector<uint8_t> entry_array;
 | 
			
		||||
		TRY(entry_array.resize(size));
 | 
			
		||||
		TRY(read_sectors(header.partition_entry_lba, size / sector_size(), entry_array.data()));
 | 
			
		||||
		TRY(read_sectors(header.partition_entry_lba, size / sector_size(), entry_array.span()));
 | 
			
		||||
 | 
			
		||||
		if (!is_valid_gpt_crc32(header, lba1, entry_array))
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_GPTHeader);
 | 
			
		||||
| 
						 | 
				
			
			@ -226,8 +228,9 @@ namespace Kernel
 | 
			
		|||
		memcpy(m_label, label, sizeof(m_label));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> Partition::read_sectors(uint64_t lba, uint8_t sector_count, uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> Partition::read_sectors(uint64_t lba, uint8_t sector_count, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * m_device.sector_size());
 | 
			
		||||
		const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
 | 
			
		||||
		if (lba + sector_count > sectors_in_partition)
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
 | 
			
		||||
| 
						 | 
				
			
			@ -235,8 +238,9 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> Partition::write_sectors(uint64_t lba, uint8_t sector_count, const uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> Partition::write_sectors(uint64_t lba, uint8_t sector_count, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * m_device.sector_size());
 | 
			
		||||
		const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
 | 
			
		||||
		if (lba + sector_count > sectors_in_partition)
 | 
			
		||||
			return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
 | 
			
		||||
| 
						 | 
				
			
			@ -244,23 +248,23 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> Partition::read_impl(off_t offset, void* buffer, size_t bytes)
 | 
			
		||||
	BAN::ErrorOr<size_t> Partition::read_impl(off_t offset, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
 | 
			
		||||
		if (offset % m_device.sector_size() || bytes % m_device.sector_size())
 | 
			
		||||
		if (offset % m_device.sector_size() || buffer.size() % m_device.sector_size())
 | 
			
		||||
			return BAN::Error::from_errno(ENOTSUP);
 | 
			
		||||
 | 
			
		||||
		const uint32_t sectors_in_partition = m_lba_end - m_lba_start;
 | 
			
		||||
		uint32_t lba = offset / m_device.sector_size();
 | 
			
		||||
		uint32_t sector_count = bytes / m_device.sector_size();
 | 
			
		||||
		uint32_t sector_count = buffer.size() / m_device.sector_size();
 | 
			
		||||
 | 
			
		||||
		if (lba == sectors_in_partition)
 | 
			
		||||
			return 0;
 | 
			
		||||
		if (lba + sector_count > sectors_in_partition)
 | 
			
		||||
			sector_count = sectors_in_partition - lba;
 | 
			
		||||
 | 
			
		||||
		TRY(read_sectors(lba, sector_count, (uint8_t*)buffer));
 | 
			
		||||
		TRY(read_sectors(lba, sector_count, buffer));
 | 
			
		||||
		return sector_count * m_device.sector_size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -283,36 +287,51 @@ namespace Kernel
 | 
			
		|||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> StorageDevice::read_sectors(uint64_t lba, uint64_t sector_count, uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> StorageDevice::read_sectors(uint64_t lba, uint64_t sector_count, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			LockGuard _(m_lock);
 | 
			
		||||
			Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
			if (!m_disk_cache.has_value())
 | 
			
		||||
				return read_sectors_impl(lba, sector_count, buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (uint64_t offset = 0; offset < sector_count; offset++)
 | 
			
		||||
		{
 | 
			
		||||
			LockGuard _(m_lock);
 | 
			
		||||
			Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
 | 
			
		||||
			uint8_t* buffer_ptr = buffer + offset * sector_size();
 | 
			
		||||
			if (m_disk_cache.has_value())
 | 
			
		||||
				if (m_disk_cache->read_from_cache(lba + offset, buffer_ptr))
 | 
			
		||||
					continue;
 | 
			
		||||
			TRY(read_sectors_impl(lba + offset, 1, buffer_ptr));
 | 
			
		||||
			if (m_disk_cache.has_value())
 | 
			
		||||
				(void)m_disk_cache->write_to_cache(lba + offset, buffer_ptr, false);
 | 
			
		||||
			auto sector_buffer = buffer.slice(offset * sector_size(), sector_size());
 | 
			
		||||
			if (m_disk_cache->read_from_cache(lba + offset, sector_buffer))
 | 
			
		||||
				continue;
 | 
			
		||||
			TRY(read_sectors_impl(lba + offset, 1, sector_buffer));
 | 
			
		||||
			(void)m_disk_cache->write_to_cache(lba + offset, sector_buffer, false);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return {};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<void> StorageDevice::write_sectors(uint64_t lba, uint64_t sector_count, const uint8_t* buffer)
 | 
			
		||||
	BAN::ErrorOr<void> StorageDevice::write_sectors(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		// TODO: use disk cache for dirty pages. I don't wanna think about how to do it safely now
 | 
			
		||||
		ASSERT(buffer.size() >= sector_count * sector_size());
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			LockGuard _(m_lock);
 | 
			
		||||
			Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
			if (!m_disk_cache.has_value())
 | 
			
		||||
				return write_sectors_impl(lba, sector_count, buffer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (uint8_t offset = 0; offset < sector_count; offset++)
 | 
			
		||||
		{
 | 
			
		||||
			LockGuard _(m_lock);
 | 
			
		||||
			Thread::TerminateBlocker blocker(Thread::current());
 | 
			
		||||
 | 
			
		||||
			const uint8_t* buffer_ptr = buffer + offset * sector_size();
 | 
			
		||||
			if (!m_disk_cache.has_value() || m_disk_cache->write_to_cache(lba + offset, buffer_ptr, true).is_error())
 | 
			
		||||
				TRY(write_sectors_impl(lba + offset, 1, buffer_ptr));
 | 
			
		||||
			auto sector_buffer = buffer.slice(offset * sector_size(), sector_size());
 | 
			
		||||
			if (m_disk_cache->write_to_cache(lba + offset, sector_buffer, true).is_error())
 | 
			
		||||
				TRY(write_sectors_impl(lba + offset, 1, sector_buffer));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return {};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ namespace Kernel
 | 
			
		|||
						TTY::current()->m_tty_ctrl.semaphore.block();
 | 
			
		||||
 | 
			
		||||
					Input::KeyEvent event;
 | 
			
		||||
					size_t read = MUST(inode->read(0, &event, sizeof(event)));
 | 
			
		||||
					size_t read = MUST(inode->read(0, BAN::ByteSpan::from(event)));
 | 
			
		||||
					ASSERT(read == sizeof(event));
 | 
			
		||||
					TTY::current()->on_key_event(event);
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +298,7 @@ namespace Kernel
 | 
			
		|||
			putchar_impl(ch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> TTY::read_impl(off_t, void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> TTY::read_impl(off_t, BAN::ByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		while (!m_output.flush)
 | 
			
		||||
| 
						 | 
				
			
			@ -314,8 +314,8 @@ namespace Kernel
 | 
			
		|||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(count, m_output.bytes);
 | 
			
		||||
		memcpy(buffer, m_output.buffer.data(), to_copy);
 | 
			
		||||
		size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_output.bytes);
 | 
			
		||||
		memcpy(buffer.data(), m_output.buffer.data(), to_copy);
 | 
			
		||||
 | 
			
		||||
		memmove(m_output.buffer.data(), m_output.buffer.data() + to_copy, m_output.bytes - to_copy);
 | 
			
		||||
		m_output.bytes -= to_copy;
 | 
			
		||||
| 
						 | 
				
			
			@ -328,12 +328,12 @@ namespace Kernel
 | 
			
		|||
		return to_copy;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> TTY::write_impl(off_t, const void* buffer, size_t count)
 | 
			
		||||
	BAN::ErrorOr<size_t> TTY::write_impl(off_t, BAN::ConstByteSpan buffer)
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		for (size_t i = 0; i < count; i++)
 | 
			
		||||
			putchar(((uint8_t*)buffer)[i]);
 | 
			
		||||
		return count;
 | 
			
		||||
		for (size_t i = 0; i < buffer.size(); i++)
 | 
			
		||||
			putchar(buffer[i]);
 | 
			
		||||
		return buffer.size();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool TTY::has_data_impl() const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue