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);
|
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 read_inode(ino_t ino, TmpInodeInfo& out);
|
||||||
void write_inode(ino_t ino, const TmpInodeInfo&);
|
void write_inode(ino_t ino, const TmpInodeInfo&);
|
||||||
void delete_inode(ino_t ino);
|
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);
|
static BAN::ErrorOr<BAN::RefPtr<TmpFileInode>> create(TmpFileSystem&, mode_t, uid_t, gid_t);
|
||||||
~TmpFileInode();
|
~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:
|
private:
|
||||||
TmpFileInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
TmpFileInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,79 @@ namespace Kernel
|
||||||
m_fs.delete_inode(ino());
|
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 */
|
/* DIRECTORY INODE */
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<TmpDirectoryInode>> TmpDirectoryInode::create_root(TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
BAN::ErrorOr<BAN::RefPtr<TmpDirectoryInode>> TmpDirectoryInode::create_root(TmpFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||||
|
|
Loading…
Reference in New Issue