Kernel: Start work on making inodes more thread safe
All inode operations are now locked and thread blocked
This commit is contained in:
parent
9e4a87021c
commit
7e08f0fb66
|
@ -1,4 +1,3 @@
|
|||
#include <BAN/UniqPtr.h>
|
||||
#include <kernel/Device/Device.h>
|
||||
|
||||
namespace Kernel
|
||||
|
@ -11,14 +10,14 @@ namespace Kernel
|
|||
|
||||
virtual dev_t rdev() const override { return m_rdev; }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override { return 0; }
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t size) override { return size; };
|
||||
|
||||
protected:
|
||||
NullDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev)
|
||||
: CharacterDevice(mode, uid, gid)
|
||||
, 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; };
|
||||
|
||||
private:
|
||||
const dev_t m_rdev;
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace Kernel
|
|||
uint32_t block_size() const { return 1024 << superblock().log_block_size; }
|
||||
|
||||
private:
|
||||
RecursiveSpinLock m_lock;
|
||||
|
||||
Partition& m_partition;
|
||||
|
||||
BAN::RefPtr<Inode> m_root_inode;
|
||||
|
|
|
@ -27,16 +27,16 @@ namespace Kernel
|
|||
virtual dev_t dev() const override { return 0; }
|
||||
virtual dev_t rdev() const override { return 0; }
|
||||
|
||||
virtual BAN::ErrorOr<BAN::String> link_target() override;
|
||||
protected:
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) 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> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override;
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) override;
|
||||
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
virtual BAN::ErrorOr<void> truncate(size_t) override;
|
||||
|
||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t) 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<void> truncate_impl(size_t) override;
|
||||
|
||||
private:
|
||||
BAN::ErrorOr<void> for_data_block_index(uint32_t, const BAN::Function<void(uint32_t&)>&, bool allocate);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <kernel/API/DirectoryEntry.h>
|
||||
#include <kernel/Credentials.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
@ -80,18 +81,37 @@ namespace Kernel
|
|||
virtual bool is_pipe() const { return false; }
|
||||
virtual bool is_tty() const { return false; }
|
||||
|
||||
virtual BAN::ErrorOr<BAN::String> link_target() { ASSERT_NOT_REACHED(); }
|
||||
// Directory API
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode(BAN::StringView);
|
||||
BAN::ErrorOr<void> list_next_inodes(off_t, DirectoryEntryList*, size_t);
|
||||
BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t);
|
||||
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<void> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
// Link API
|
||||
BAN::ErrorOr<BAN::String> link_target();
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual bool has_data() const { dwarnln("nonblock not supported"); return true; }
|
||||
|
||||
virtual BAN::ErrorOr<void> truncate(size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); return BAN::Error::from_errno(ENOTSUP); }
|
||||
// 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<void> truncate(size_t);
|
||||
bool has_data() const;
|
||||
|
||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
protected:
|
||||
// Directory API
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) { 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); }
|
||||
|
||||
// Link API
|
||||
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<void> truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
|
||||
|
||||
private:
|
||||
mutable RecursiveSpinLock m_lock;
|
||||
};
|
||||
|
||||
}
|
|
@ -30,8 +30,9 @@ namespace Kernel
|
|||
virtual dev_t dev() const override { return 0; } // FIXME
|
||||
virtual dev_t rdev() const override { return 0; } // FIXME
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
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;
|
||||
|
||||
private:
|
||||
Pipe(const Credentials&);
|
||||
|
|
|
@ -29,16 +29,15 @@ namespace Kernel
|
|||
virtual dev_t dev() const override { return m_inode_info.dev; }
|
||||
virtual dev_t rdev() const override { return m_inode_info.rdev; }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
|
||||
virtual BAN::ErrorOr<void> truncate(size_t) override;
|
||||
|
||||
void add_link() { m_inode_info.nlink++; }
|
||||
|
||||
protected:
|
||||
RamInode(RamFileSystem& fs, mode_t, uid_t, gid_t);
|
||||
|
||||
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<void> truncate_impl(size_t) override;
|
||||
|
||||
protected:
|
||||
struct FullInodeInfo
|
||||
{
|
||||
|
@ -72,12 +71,13 @@ namespace Kernel
|
|||
static BAN::ErrorOr<BAN::RefPtr<RamDirectoryInode>> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t);
|
||||
~RamDirectoryInode() = default;
|
||||
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_inode(BAN::StringView) override;
|
||||
virtual BAN::ErrorOr<void> directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override;
|
||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t) override;
|
||||
|
||||
BAN::ErrorOr<void> add_inode(BAN::StringView, BAN::RefPtr<RamInode>);
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) 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;
|
||||
|
||||
private:
|
||||
RamDirectoryInode(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t);
|
||||
|
||||
|
@ -105,8 +105,10 @@ namespace Kernel
|
|||
|
||||
virtual off_t size() const override { return m_target.size(); }
|
||||
|
||||
virtual BAN::ErrorOr<BAN::String> link_target() override;
|
||||
BAN::ErrorOr<void> set_link_target(BAN::StringView);
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
|
||||
|
||||
private:
|
||||
RamSymlinkInode(RamFileSystem&, mode_t, uid_t, gid_t);
|
||||
|
|
|
@ -39,9 +39,9 @@ namespace Kernel
|
|||
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
FileSystem* m_root_fs = nullptr;
|
||||
BAN::Vector<MountPoint> m_mount_points;
|
||||
SpinLock m_lock;
|
||||
FileSystem* m_root_fs = nullptr;
|
||||
BAN::Vector<MountPoint> m_mount_points;
|
||||
};
|
||||
|
||||
}
|
|
@ -61,7 +61,9 @@ namespace Kernel::Input
|
|||
|
||||
public:
|
||||
virtual dev_t rdev() const override { return m_rdev; }
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
|
||||
|
||||
private:
|
||||
const dev_t m_rdev;
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace Kernel
|
|||
virtual gid_t gid() const override { return 0; }
|
||||
virtual dev_t rdev() const override { return m_rdev; }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
private:
|
||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
|
||||
|
||||
public:
|
||||
const dev_t m_rdev;
|
||||
|
|
|
@ -50,7 +50,8 @@ namespace Kernel
|
|||
virtual gid_t gid() const override { return 0; }
|
||||
virtual dev_t rdev() const override { return m_rdev; }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
protected:
|
||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
|
||||
|
||||
private:
|
||||
const dev_t m_rdev;
|
||||
|
|
|
@ -33,9 +33,6 @@ namespace Kernel
|
|||
|
||||
virtual bool is_tty() const override { return true; }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
|
||||
virtual uint32_t height() const = 0;
|
||||
virtual uint32_t width() const = 0;
|
||||
virtual void putchar(uint8_t ch) = 0;
|
||||
|
@ -47,6 +44,9 @@ namespace Kernel
|
|||
: CharacterDevice(mode, uid, gid)
|
||||
{ }
|
||||
|
||||
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::StringView name() const = 0;
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <BAN/ScopeGuard.h>
|
||||
#include <kernel/FS/Ext2/FileSystem.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
|
||||
#define EXT2_DEBUG_PRINT 0
|
||||
#define EXT2_VERIFY_INODE 0
|
||||
|
@ -135,6 +136,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<uint32_t> Ext2FS::create_inode(const Ext2::Inode& ext2_inode)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
ASSERT(ext2_inode.size == 0);
|
||||
|
||||
if (m_superblock.free_inodes_count == 0)
|
||||
|
@ -213,6 +216,8 @@ namespace Kernel
|
|||
|
||||
void Ext2FS::read_block(uint32_t block, BAN::Span<uint8_t> buffer)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
const uint32_t sector_size = m_partition.device().sector_size();
|
||||
const uint32_t block_size = this->block_size();
|
||||
const uint32_t sectors_per_block = block_size / sector_size;
|
||||
|
@ -225,6 +230,8 @@ namespace Kernel
|
|||
|
||||
void Ext2FS::write_block(uint32_t block, BAN::Span<const uint8_t> buffer)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
const uint32_t sector_size = m_partition.device().sector_size();
|
||||
const uint32_t block_size = this->block_size();
|
||||
const uint32_t sectors_per_block = block_size / sector_size;
|
||||
|
@ -237,6 +244,8 @@ namespace Kernel
|
|||
|
||||
void Ext2FS::sync_superblock()
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
const uint32_t sector_size = m_partition.device().sector_size();
|
||||
ASSERT(1024 % sector_size == 0);
|
||||
|
||||
|
@ -261,6 +270,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<uint32_t> Ext2FS::reserve_free_block(uint32_t primary_bgd)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
if (m_superblock.r_blocks_count >= m_superblock.free_blocks_count)
|
||||
return BAN::Error::from_errno(ENOSPC);
|
||||
|
||||
|
@ -325,6 +336,8 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<Ext2FS::BlockLocation> Ext2FS::locate_inode(uint32_t ino)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
ASSERT(ino <= superblock().inodes_count);
|
||||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
@ -366,6 +379,8 @@ namespace Kernel
|
|||
|
||||
Ext2FS::BlockLocation Ext2FS::locate_block_group_descriptior(uint32_t group_index)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
const uint32_t block_size = this->block_size();
|
||||
|
||||
const uint32_t block_group_count = BAN::Math::div_round_up(superblock().inodes_count, superblock().inodes_per_group);
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace Kernel
|
|||
return result;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::String> Ext2Inode::link_target()
|
||||
BAN::ErrorOr<BAN::String> Ext2Inode::link_target_impl()
|
||||
{
|
||||
ASSERT(mode().iflnk());
|
||||
if (m_inode.size < sizeof(m_inode.block))
|
||||
|
@ -167,12 +167,15 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Ext2Inode::read(size_t offset, void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> Ext2Inode::read_impl(off_t offset, void* buffer, size_t count)
|
||||
{
|
||||
// FIXME: update atime if needed
|
||||
|
||||
if (mode().ifdir())
|
||||
return BAN::Error::from_errno(EISDIR);
|
||||
ASSERT(!mode().ifdir());
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX)
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
if (offset >= m_inode.size)
|
||||
return 0;
|
||||
|
@ -204,16 +207,18 @@ namespace Kernel
|
|||
return n_read;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Ext2Inode::write(size_t offset, const void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> Ext2Inode::write_impl(off_t offset, const void* buffer, size_t count)
|
||||
{
|
||||
if (offset >= UINT32_MAX || count == UINT32_MAX || offset + count >= UINT32_MAX)
|
||||
// FIXME: update atime if needed
|
||||
|
||||
ASSERT(!mode().ifdir());
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX)
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
if (mode().ifdir())
|
||||
return BAN::Error::from_errno(EISDIR);
|
||||
|
||||
if (m_inode.size < offset + count)
|
||||
TRY(truncate(offset + count));
|
||||
TRY(truncate_impl(offset + count));
|
||||
|
||||
const uint32_t block_size = blksize();
|
||||
|
||||
|
@ -222,6 +227,8 @@ namespace Kernel
|
|||
|
||||
const uint8_t* u8buffer = (const uint8_t*)buffer;
|
||||
|
||||
size_t written = 0;
|
||||
|
||||
// Write partial block
|
||||
if (offset % block_size)
|
||||
{
|
||||
|
@ -229,7 +236,7 @@ namespace Kernel
|
|||
uint32_t block_offset = offset % block_size;
|
||||
|
||||
uint32_t data_block_index = TRY(this->data_block_index(block_index));
|
||||
uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - block_offset, count);
|
||||
uint32_t to_copy = BAN::Math::min<uint32_t>(block_size - block_offset, written);
|
||||
|
||||
m_fs.read_block(data_block_index, block_buffer.span());
|
||||
memcpy(block_buffer.data() + block_offset, buffer, to_copy);
|
||||
|
@ -237,10 +244,10 @@ namespace Kernel
|
|||
|
||||
u8buffer += to_copy;
|
||||
offset += to_copy;
|
||||
count -= to_copy;
|
||||
written -= to_copy;
|
||||
}
|
||||
|
||||
while (count >= block_size)
|
||||
while (written >= block_size)
|
||||
{
|
||||
uint32_t data_block_index = TRY(this->data_block_index(offset / block_size));
|
||||
|
||||
|
@ -248,22 +255,22 @@ namespace Kernel
|
|||
|
||||
u8buffer += block_size;
|
||||
offset += block_size;
|
||||
count -= block_size;
|
||||
written -= block_size;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
if (written > 0)
|
||||
{
|
||||
uint32_t data_block_index = TRY(this->data_block_index(offset / block_size));
|
||||
|
||||
m_fs.read_block(data_block_index, block_buffer.span());
|
||||
memcpy(block_buffer.data(), u8buffer, count);
|
||||
memcpy(block_buffer.data(), u8buffer, written);
|
||||
m_fs.write_block(data_block_index, block_buffer.span());
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Ext2Inode::truncate(size_t new_size)
|
||||
BAN::ErrorOr<void> Ext2Inode::truncate_impl(size_t new_size)
|
||||
{
|
||||
if (m_inode.size == new_size)
|
||||
return {};
|
||||
|
@ -304,10 +311,10 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Ext2Inode::directory_read_next_entries(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)
|
||||
{
|
||||
if (!mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
ASSERT(mode().ifdir());
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
const uint32_t data_block_count = blocks();
|
||||
if (offset >= data_block_count)
|
||||
|
@ -369,7 +376,7 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Ext2Inode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)
|
||||
BAN::ErrorOr<void> Ext2Inode::create_file_impl(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
if (!this->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
|
@ -386,7 +393,7 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
auto error_or = directory_find_inode(name);
|
||||
auto error_or = find_inode_impl(name);
|
||||
if (!error_or.is_error())
|
||||
return BAN::Error::from_errno(EEXISTS);
|
||||
if (error_or.error().get_error_code() != ENOENT)
|
||||
|
@ -424,7 +431,7 @@ namespace Kernel
|
|||
|
||||
auto write_inode = [&](uint32_t entry_offset, uint32_t entry_rec_len)
|
||||
{
|
||||
auto typed_mode = Mode { mode };
|
||||
auto typed_mode = Mode(mode);
|
||||
uint8_t file_type = (m_fs.superblock().rev_level == Ext2::Enum::GOOD_OLD_REV) ? 0
|
||||
: typed_mode.ifreg() ? Ext2::Enum::REG_FILE
|
||||
: typed_mode.ifdir() ? Ext2::Enum::DIR
|
||||
|
@ -542,10 +549,9 @@ needs_new_block:
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::directory_find_inode(BAN::StringView file_name)
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::find_inode_impl(BAN::StringView file_name)
|
||||
{
|
||||
if (!mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
ASSERT(mode().ifdir());
|
||||
|
||||
const uint32_t block_size = blksize();
|
||||
const uint32_t data_block_count = blocks();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/LockGuard.h>
|
||||
#include <kernel/Thread.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
|
@ -55,4 +57,74 @@ namespace Kernel
|
|||
return true;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Inode::find_inode(BAN::StringView name)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (!mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
return find_inode_impl(name);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::list_next_inodes(off_t offset, DirectoryEntryList* list, size_t list_len)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (!mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
return list_next_inodes_impl(offset, list, list_len);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (!this->mode().ifdir())
|
||||
return BAN::Error::from_errno(ENOTDIR);
|
||||
return create_file_impl(name, mode, uid, gid);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::String> Inode::link_target()
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (!mode().iflnk())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
return link_target_impl();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Inode::read(off_t offset, void* buffer, size_t bytes)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (mode().ifdir())
|
||||
return BAN::Error::from_errno(EISDIR);
|
||||
return read_impl(offset, buffer, bytes);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Inode::write(off_t offset, const void* buffer, size_t bytes)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (mode().ifdir())
|
||||
return BAN::Error::from_errno(EISDIR);
|
||||
return write_impl(offset, buffer, bytes);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Inode::truncate(size_t size)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
if (mode().ifdir())
|
||||
return BAN::Error::from_errno(EISDIR);
|
||||
return truncate_impl(size);
|
||||
}
|
||||
|
||||
bool Inode::has_data() const
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
Thread::TerminateBlocker blocker(Thread::current());
|
||||
return has_data_impl();
|
||||
}
|
||||
|
||||
}
|
|
@ -39,9 +39,9 @@ namespace Kernel
|
|||
m_semaphore.unblock();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Pipe::read(size_t, void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, void* buffer, size_t count)
|
||||
{
|
||||
m_lock.lock();
|
||||
LockGuard _(m_lock);
|
||||
while (m_buffer.empty())
|
||||
{
|
||||
if (m_writing_count == 0)
|
||||
|
@ -61,12 +61,10 @@ namespace Kernel
|
|||
|
||||
m_semaphore.unblock();
|
||||
|
||||
m_lock.unlock();
|
||||
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Pipe::write(size_t, const void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, const void* buffer, size_t count)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<RamInode>> RamInode::create(RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
ASSERT(Mode{ mode }.ifreg());
|
||||
ASSERT(Mode(mode).ifreg());
|
||||
auto* ram_inode = new RamInode(fs, mode, uid, gid);
|
||||
if (ram_inode == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
@ -40,26 +40,26 @@ namespace Kernel
|
|||
m_inode_info.rdev = 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> RamInode::read(size_t offset, void* buffer, size_t bytes)
|
||||
BAN::ErrorOr<size_t> RamInode::read_impl(off_t offset, void* buffer, size_t bytes)
|
||||
{
|
||||
if (offset >= (size_t)size())
|
||||
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);
|
||||
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> RamInode::write(size_t offset, const void* buffer, size_t bytes)
|
||||
BAN::ErrorOr<size_t> RamInode::write_impl(off_t offset, const void* buffer, size_t bytes)
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
if (offset + bytes > (size_t)size())
|
||||
TRY(truncate(offset + bytes));
|
||||
TRY(truncate_impl(offset + bytes));
|
||||
memcpy(m_data.data() + offset, buffer, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> RamInode::truncate(size_t new_size)
|
||||
BAN::ErrorOr<void> RamInode::truncate_impl(size_t new_size)
|
||||
{
|
||||
TRY(m_data.resize(new_size, 0));
|
||||
m_inode_info.size = m_data.size();
|
||||
|
@ -75,7 +75,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<RamDirectoryInode>> RamDirectoryInode::create(RamFileSystem& fs, ino_t parent, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
ASSERT(Mode{ mode }.ifdir());
|
||||
ASSERT(Mode(mode).ifdir());
|
||||
auto* ram_inode = new RamDirectoryInode(fs, parent, mode, uid, gid);
|
||||
if (ram_inode == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
@ -101,7 +101,7 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> RamDirectoryInode::directory_find_inode(BAN::StringView name)
|
||||
BAN::ErrorOr<BAN::RefPtr<Inode>> RamDirectoryInode::find_inode_impl(BAN::StringView name)
|
||||
{
|
||||
if (name == "."sv)
|
||||
{
|
||||
|
@ -127,8 +127,10 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOENT);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> RamDirectoryInode::directory_read_next_entries(off_t offset, DirectoryEntryList* list, size_t list_size)
|
||||
BAN::ErrorOr<void> RamDirectoryInode::list_next_inodes_impl(off_t offset, DirectoryEntryList* list, size_t list_size)
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
// TODO: don't require memory for all entries on single call
|
||||
if (offset != 0)
|
||||
{
|
||||
|
@ -175,12 +177,12 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> RamDirectoryInode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)
|
||||
BAN::ErrorOr<void> RamDirectoryInode::create_file_impl(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
BAN::RefPtr<RamInode> inode;
|
||||
if (Mode{ mode }.ifreg())
|
||||
if (Mode(mode).ifreg())
|
||||
inode = TRY(RamInode::create(m_fs, mode, uid, gid));
|
||||
else if (Mode{ mode }.ifdir())
|
||||
else if (Mode(mode).ifdir())
|
||||
inode = TRY(RamDirectoryInode::create(m_fs, ino(), mode, uid, gid));
|
||||
else
|
||||
ASSERT_NOT_REACHED();
|
||||
|
@ -222,7 +224,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::RefPtr<RamSymlinkInode>> RamSymlinkInode::create(RamFileSystem& fs, BAN::StringView target, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
ASSERT(Mode{ mode }.iflnk());
|
||||
ASSERT(Mode(mode).iflnk());
|
||||
auto* ram_inode = new RamSymlinkInode(fs, mode, uid, gid);
|
||||
if (ram_inode == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
@ -235,7 +237,7 @@ namespace Kernel
|
|||
: RamInode(fs, mode, uid, gid)
|
||||
{ }
|
||||
|
||||
BAN::ErrorOr<BAN::String> RamSymlinkInode::link_target()
|
||||
BAN::ErrorOr<BAN::String> RamSymlinkInode::link_target_impl()
|
||||
{
|
||||
BAN::String result;
|
||||
TRY(result.append(m_target));
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Kernel
|
|||
ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);;
|
||||
root = root.substring(5);
|
||||
|
||||
auto partition_inode = MUST(DevFileSystem::get().root_inode()->directory_find_inode(root));
|
||||
auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root));
|
||||
s_instance->m_root_fs = MUST(Ext2FS::create(*(Partition*)partition_inode.ptr()));
|
||||
|
||||
Credentials root_creds { 0, 0, 0, 0 };
|
||||
|
@ -119,9 +119,9 @@ namespace Kernel
|
|||
else if (path_part == ".."sv)
|
||||
{
|
||||
if (auto* mount_point = mount_from_root_inode(inode))
|
||||
inode = TRY(mount_point->host.inode->directory_find_inode(".."sv));
|
||||
inode = TRY(mount_point->host.inode->find_inode(".."sv));
|
||||
else
|
||||
inode = TRY(inode->directory_find_inode(".."sv));
|
||||
inode = TRY(inode->find_inode(".."sv));
|
||||
|
||||
if (!canonical_path.empty())
|
||||
{
|
||||
|
@ -136,7 +136,7 @@ namespace Kernel
|
|||
if (!inode->can_access(credentials, O_SEARCH))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
|
||||
inode = TRY(inode->directory_find_inode(path_part));
|
||||
inode = TRY(inode->find_inode(path_part));
|
||||
|
||||
if (auto* mount_point = mount_from_host_inode(inode))
|
||||
inode = mount_point->target->root_inode();
|
||||
|
|
|
@ -242,7 +242,7 @@ namespace Kernel::Input
|
|||
append_command_queue(Command::SET_LEDS, new_leds);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> PS2Keyboard::read(size_t, void* buffer, size_t size)
|
||||
BAN::ErrorOr<size_t> PS2Keyboard::read_impl(off_t, void* buffer, size_t size)
|
||||
{
|
||||
if (size < sizeof(KeyEvent))
|
||||
return BAN::Error::from_errno(ENOBUFS);
|
||||
|
|
|
@ -290,7 +290,7 @@ namespace Kernel
|
|||
auto& open_file = m_open_files[fd];
|
||||
if (!(open_file->flags & O_RDONLY))
|
||||
return BAN::Error::from_errno(EACCES);
|
||||
TRY(open_file->inode->directory_read_next_entries(open_file->offset, list, list_size));
|
||||
TRY(open_file->inode->list_next_inodes(open_file->offset, list, list_size));
|
||||
open_file->offset++;
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -72,11 +72,12 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> ATADevice::read(size_t offset, void* buffer, size_t bytes)
|
||||
BAN::ErrorOr<size_t> ATADevice::read_impl(off_t offset, void* buffer, size_t bytes)
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
if (offset % sector_size() || bytes % sector_size())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
if (offset == total_size())
|
||||
if ((size_t)offset == total_size())
|
||||
return 0;
|
||||
TRY(read_sectors(offset / sector_size(), bytes / sector_size(), (uint8_t*)buffer));
|
||||
return bytes;
|
||||
|
|
|
@ -231,8 +231,10 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> Partition::read(size_t offset, void* buffer, size_t bytes)
|
||||
BAN::ErrorOr<size_t> Partition::read_impl(off_t offset, void* buffer, size_t bytes)
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
|
||||
if (offset % m_device.sector_size() || bytes % m_device.sector_size())
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Kernel
|
|||
{
|
||||
s_tty = this;
|
||||
|
||||
auto inode_or_error = DevFileSystem::get().root_inode()->directory_find_inode("tty");
|
||||
auto inode_or_error = DevFileSystem::get().root_inode()->find_inode("tty");
|
||||
if (inode_or_error.is_error())
|
||||
{
|
||||
if (inode_or_error.error().get_error_code() == ENOENT)
|
||||
|
@ -249,7 +249,7 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> TTY::read(size_t, void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> TTY::read_impl(off_t, void* buffer, size_t count)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
while (!m_output.flush)
|
||||
|
@ -279,7 +279,7 @@ namespace Kernel
|
|||
return to_copy;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> TTY::write(size_t, const void* buffer, size_t count)
|
||||
BAN::ErrorOr<size_t> TTY::write_impl(off_t, const void* buffer, size_t count)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
for (size_t i = 0; i < count; i++)
|
||||
|
|
|
@ -144,10 +144,6 @@ extern "C" void kernel_main()
|
|||
auto vtty = MUST(VirtualTTY::create(terminal_driver));
|
||||
dprintln("Virtual TTY initialized");
|
||||
|
||||
auto console = MUST(DevFileSystem::get().root_inode()->directory_find_inode(cmdline.console));
|
||||
ASSERT(console->is_tty());
|
||||
((TTY*)console.ptr())->set_as_current();
|
||||
|
||||
MUST(Scheduler::initialize());
|
||||
dprintln("Scheduler initialized");
|
||||
|
||||
|
@ -165,6 +161,10 @@ static void init2(void*)
|
|||
|
||||
dprintln("Scheduler started");
|
||||
|
||||
auto console = MUST(DevFileSystem::get().root_inode()->find_inode(cmdline.console));
|
||||
ASSERT(console->is_tty());
|
||||
((TTY*)console.ptr())->set_as_current();
|
||||
|
||||
DevFileSystem::get().initialize_device_updater();
|
||||
|
||||
PCI::initialize();
|
||||
|
|
Loading…
Reference in New Issue