Kernel: Implement read/write/truncate for TmpFileInode
This commit is contained in:
parent
f9bf47ab30
commit
8164c15b6c
|
@ -28,6 +28,9 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<TmpInode>> open_inode(ino_t ino);
|
||||
|
||||
// FIXME: read_block and write_block should not require external buffer
|
||||
// probably some wrapper like PageTable::with_fast_page could work?
|
||||
|
||||
void read_inode(ino_t ino, TmpInodeInfo& out);
|
||||
void write_inode(ino_t ino, const TmpInodeInfo&);
|
||||
void delete_inode(ino_t ino);
|
||||
|
|
|
@ -53,6 +53,11 @@ namespace Kernel
|
|||
static BAN::ErrorOr<BAN::RefPtr<TmpFileInode>> create(TmpFileSystem&, mode_t, uid_t, gid_t);
|
||||
~TmpFileInode();
|
||||
|
||||
protected:
|
||||
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:
|
||||
TmpFileInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
||||
|
||||
|
|
|
@ -130,6 +130,79 @@ namespace Kernel
|
|||
m_fs.delete_inode(ino());
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> TmpFileInode::read_impl(off_t offset, BAN::ByteSpan buffer)
|
||||
{
|
||||
if (offset >= size() || buffer.size() == 0)
|
||||
return 0;
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(blksize()));
|
||||
|
||||
const size_t bytes_to_read = BAN::Math::min<size_t>(size() - offset, buffer.size());
|
||||
|
||||
size_t read_done = 0;
|
||||
while (read_done < bytes_to_read)
|
||||
{
|
||||
const size_t data_block_index = (read_done + offset) / blksize();
|
||||
const size_t block_offset = (read_done + offset) % blksize();
|
||||
|
||||
const size_t block_index = this->block_index(data_block_index);
|
||||
|
||||
const size_t bytes = BAN::Math::min<size_t>(bytes_to_read - read_done, blksize() - block_offset);
|
||||
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
|
||||
memcpy(buffer.data() + read_done, block_buffer.data() + block_offset, bytes);
|
||||
|
||||
read_done += bytes;
|
||||
}
|
||||
|
||||
return read_done;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> TmpFileInode::write_impl(off_t offset, BAN::ConstByteSpan buffer)
|
||||
{
|
||||
// FIXME: handle overflow
|
||||
|
||||
if (offset + buffer.size() > (size_t)size())
|
||||
TRY(truncate_impl(offset + buffer.size()));
|
||||
|
||||
BAN::Vector<uint8_t> block_buffer;
|
||||
TRY(block_buffer.resize(blksize()));
|
||||
|
||||
const size_t bytes_to_write = buffer.size();
|
||||
|
||||
size_t write_done = 0;
|
||||
while (write_done < bytes_to_write)
|
||||
{
|
||||
const size_t data_block_index = (write_done + offset) / blksize();
|
||||
const size_t block_offset = (write_done + offset) % blksize();
|
||||
|
||||
const size_t block_index = this->block_index(data_block_index);
|
||||
|
||||
const size_t bytes = BAN::Math::min<size_t>(bytes_to_write - write_done, blksize() - block_offset);
|
||||
|
||||
if (bytes < (size_t)blksize())
|
||||
m_fs.read_block(block_index, block_buffer.span());
|
||||
memcpy(block_buffer.data() + block_offset, buffer.data() + write_done, bytes);
|
||||
|
||||
m_fs.write_block(block_index, block_buffer.span());
|
||||
|
||||
write_done += bytes;
|
||||
}
|
||||
|
||||
return write_done;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> TmpFileInode::truncate_impl(size_t new_size)
|
||||
{
|
||||
size_t start_block = size() / blksize() * blksize();
|
||||
for (size_t off = start_block; off < new_size; off += blksize())
|
||||
TRY(block_index_with_allocation(off / blksize()));
|
||||
m_inode_info.size = new_size;
|
||||
return {};
|
||||
}
|
||||
|
||||
/* 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