forked from Bananymous/banan-os
Kernel: Add basic mounting to VFS.
This commit is contained in:
parent
0c582b4490
commit
39b560fde3
14
disk.sh
14
disk.sh
|
@ -15,6 +15,10 @@ sed -e 's/\s*\([-\+[:alnum:]]*\).*/\1/' << EOF | fdisk $DISK_NAME
|
||||||
# default (from the beginning of the disk)
|
# default (from the beginning of the disk)
|
||||||
+1MiB # bios boot partiton size
|
+1MiB # bios boot partiton size
|
||||||
n # new partition
|
n # new partition
|
||||||
|
3 # partition number 3
|
||||||
|
# default (right after bios boot partition)
|
||||||
|
+10Mib# partition size
|
||||||
|
n # new partition
|
||||||
2 # partition number 2
|
2 # partition number 2
|
||||||
# default (right after bios boot partition)
|
# default (right after bios boot partition)
|
||||||
# default (to the end of disk)
|
# default (to the end of disk)
|
||||||
|
@ -26,6 +30,9 @@ sed -e 's/\s*\([-\+[:alnum:]]*\).*/\1/' << EOF | fdisk $DISK_NAME
|
||||||
20 # Linux filesystem
|
20 # Linux filesystem
|
||||||
x # expert menu
|
x # expert menu
|
||||||
n # partition name
|
n # partition name
|
||||||
|
3 # ... of partition 3
|
||||||
|
mount-test
|
||||||
|
n # partition name
|
||||||
2 # ... of partition 2
|
2 # ... of partition 2
|
||||||
banan-root
|
banan-root
|
||||||
r # back to main menu
|
r # back to main menu
|
||||||
|
@ -37,6 +44,7 @@ sudo partprobe $LOOP_DEV
|
||||||
|
|
||||||
PARTITION1=${LOOP_DEV}p1
|
PARTITION1=${LOOP_DEV}p1
|
||||||
PARTITION2=${LOOP_DEV}p2
|
PARTITION2=${LOOP_DEV}p2
|
||||||
|
PARTITION3=${LOOP_DEV}p3
|
||||||
|
|
||||||
sudo mkfs.ext2 $PARTITION2
|
sudo mkfs.ext2 $PARTITION2
|
||||||
|
|
||||||
|
@ -64,4 +72,10 @@ menuentry "banan-os (no apic, no serial)" {
|
||||||
' | sudo tee ${MOUNT_DIR}/boot/grub/grub.cfg
|
' | sudo tee ${MOUNT_DIR}/boot/grub/grub.cfg
|
||||||
|
|
||||||
sudo umount $MOUNT_DIR
|
sudo umount $MOUNT_DIR
|
||||||
|
|
||||||
|
sudo mkfs.ext2 $PARTITION3
|
||||||
|
sudo mount $PARTITION3 $MOUNT_DIR
|
||||||
|
echo 'hello' | sudo tee ${MOUNT_DIR}/hello.txt
|
||||||
|
sudo umount $MOUNT_DIR
|
||||||
|
|
||||||
sudo losetup -d $LOOP_DEV
|
sudo losetup -d $LOOP_DEV
|
||||||
|
|
|
@ -42,6 +42,7 @@ kernel/CPUID.o \
|
||||||
kernel/Debug.o \
|
kernel/Debug.o \
|
||||||
kernel/Font.o \
|
kernel/Font.o \
|
||||||
kernel/FS/Ext2.o \
|
kernel/FS/Ext2.o \
|
||||||
|
kernel/FS/Inode.o \
|
||||||
kernel/FS/VirtualFileSystem.o \
|
kernel/FS/VirtualFileSystem.o \
|
||||||
kernel/Input.o \
|
kernel/Input.o \
|
||||||
kernel/InterruptController.o \
|
kernel/InterruptController.o \
|
||||||
|
|
|
@ -132,12 +132,14 @@ namespace Kernel
|
||||||
virtual BAN::StringView name() const override { return m_name; }
|
virtual BAN::StringView name() const override { return m_name; }
|
||||||
|
|
||||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||||
virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() override;
|
|
||||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) override;
|
|
||||||
|
|
||||||
virtual Type type() const override { return Type::Ext2; }
|
virtual Type type() const override { return Type::Ext2; }
|
||||||
virtual bool operator==(const Inode& other) const override;
|
virtual bool operator==(const Inode& other) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes_impl() override;
|
||||||
|
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_impl(BAN::StringView) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::ErrorOr<uint32_t> data_block_index(uint32_t);
|
BAN::ErrorOr<uint32_t> data_block_index(uint32_t);
|
||||||
|
|
||||||
|
@ -170,7 +172,7 @@ namespace Kernel
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<Ext2FS*> create(StorageDevice::Partition&);
|
static BAN::ErrorOr<Ext2FS*> create(StorageDevice::Partition&);
|
||||||
|
|
||||||
virtual const BAN::RefPtr<Inode> root_inode() const override { return m_root_inode; }
|
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ext2FS(StorageDevice::Partition& partition)
|
Ext2FS(StorageDevice::Partition& partition)
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Kernel
|
||||||
class FileSystem
|
class FileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual const BAN::RefPtr<Inode> root_inode() const = 0;
|
virtual BAN::RefPtr<Inode> root_inode() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <BAN/ForwardList.h>
|
|
||||||
#include <BAN/Memory.h>
|
#include <BAN/Memory.h>
|
||||||
|
#include <BAN/String.h>
|
||||||
#include <stdint.h>
|
#include <BAN/Vector.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
@ -37,7 +36,6 @@ namespace Kernel
|
||||||
|
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
General,
|
|
||||||
Ext2,
|
Ext2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,12 +53,17 @@ namespace Kernel
|
||||||
|
|
||||||
virtual BAN::StringView name() const = 0;
|
virtual BAN::StringView name() const = 0;
|
||||||
|
|
||||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) = 0;
|
BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes();
|
||||||
virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes() = 0;
|
BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView);
|
||||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find(BAN::StringView) = 0;
|
|
||||||
|
|
||||||
virtual Type type() const { return Type::General; }
|
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) = 0;
|
||||||
|
|
||||||
|
virtual Type type() const = 0;
|
||||||
virtual bool operator==(const Inode&) const = 0;
|
virtual bool operator==(const Inode&) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> directory_inodes_impl() = 0;
|
||||||
|
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> directory_find_impl(BAN::StringView) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <BAN/HashMap.h>
|
#include <BAN/HashMap.h>
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
|
#include <BAN/StringView.h>
|
||||||
#include <kernel/FS/FileSystem.h>
|
#include <kernel/FS/FileSystem.h>
|
||||||
#include <kernel/Storage/StorageController.h>
|
#include <kernel/Storage/StorageController.h>
|
||||||
|
|
||||||
|
@ -15,7 +16,9 @@ namespace Kernel
|
||||||
static VirtualFileSystem& get();
|
static VirtualFileSystem& get();
|
||||||
virtual ~VirtualFileSystem() {};
|
virtual ~VirtualFileSystem() {};
|
||||||
|
|
||||||
virtual const BAN::RefPtr<Inode> root_inode() const override { return m_root_inode; }
|
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> mount_test();
|
||||||
|
|
||||||
struct File
|
struct File
|
||||||
{
|
{
|
||||||
|
@ -24,12 +27,20 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView);
|
BAN::ErrorOr<File> file_from_absolute_path(BAN::StringView);
|
||||||
|
|
||||||
|
struct MountPoint
|
||||||
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
FileSystem* target;
|
||||||
|
};
|
||||||
|
const BAN::Vector<MountPoint>& mount_points() const { return m_mount_points; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualFileSystem() = default;
|
VirtualFileSystem() = default;
|
||||||
BAN::ErrorOr<void> initialize_impl();
|
BAN::ErrorOr<void> initialize_impl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::RefPtr<Inode> m_root_inode;
|
BAN::RefPtr<Inode> m_root_inode;
|
||||||
|
BAN::Vector<MountPoint> m_mount_points;
|
||||||
BAN::Vector<StorageController*> m_storage_controllers;
|
BAN::Vector<StorageController*> m_storage_controllers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace Kernel
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::directory_find(BAN::StringView file_name)
|
BAN::ErrorOr<BAN::RefPtr<Inode>> Ext2Inode::directory_find_impl(BAN::StringView file_name)
|
||||||
{
|
{
|
||||||
if (!ifdir())
|
if (!ifdir())
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
@ -307,45 +307,42 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ENOENT);
|
return BAN::Error::from_errno(ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> Ext2Inode::directory_inodes()
|
BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> Ext2Inode::directory_inodes_impl()
|
||||||
{
|
{
|
||||||
if (!ifdir())
|
if (!ifdir())
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
struct directory_info
|
uint32_t data_block_count = m_inode.blocks / (2 << m_fs.superblock().log_block_size);
|
||||||
{
|
|
||||||
BAN::Vector<BAN::RefPtr<Inode>> inodes;
|
BAN::Vector<BAN::RefPtr<Inode>> inodes;
|
||||||
Ext2FS* fs;
|
|
||||||
};
|
|
||||||
|
|
||||||
directory_info info;
|
for (uint32_t i = 0; i < data_block_count; i++)
|
||||||
info.inodes = {};
|
|
||||||
info.fs = &m_fs;
|
|
||||||
|
|
||||||
block_callback_t function =
|
|
||||||
[](const BAN::Vector<uint8_t>& block_data, void* info_) -> BAN::ErrorOr<bool>
|
|
||||||
{
|
{
|
||||||
directory_info& info = *(directory_info*)info_;
|
auto data_block_index_or_error = data_block_index(i);
|
||||||
|
if (data_block_index_or_error.is_error())
|
||||||
|
{
|
||||||
|
dprintln("{}", data_block_index_or_error.error());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t block_data_end = (uintptr_t)block_data.data() + block_data.size();
|
auto block_data = TRY(m_fs.read_block(data_block_index_or_error.value()));
|
||||||
uintptr_t entry_addr = (uintptr_t)block_data.data();
|
|
||||||
|
uint8_t* block_data_end = block_data.data() + block_data.size();
|
||||||
|
uint8_t* entry_addr = block_data.data();
|
||||||
while (entry_addr < block_data_end)
|
while (entry_addr < block_data_end)
|
||||||
{
|
{
|
||||||
Ext2::LinkedDirectoryEntry* entry = (Ext2::LinkedDirectoryEntry*)entry_addr;
|
Ext2::LinkedDirectoryEntry* entry = (Ext2::LinkedDirectoryEntry*)entry_addr;
|
||||||
if (entry->inode)
|
if (entry->inode)
|
||||||
{
|
{
|
||||||
auto entry_name = BAN::StringView(entry->name, entry->name_len);
|
auto entry_name = BAN::StringView(entry->name, entry->name_len);
|
||||||
auto inode = TRY(Ext2Inode::create(*info.fs, entry->inode, entry_name));
|
auto inode = TRY(Ext2Inode::create(m_fs, entry->inode, entry_name));
|
||||||
TRY(info.inodes.push_back(inode));
|
TRY(inodes.push_back(inode));
|
||||||
}
|
}
|
||||||
entry_addr += entry->rec_len;
|
entry_addr += entry->rec_len;
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
TRY(for_each_block(function, &info));
|
return inodes;
|
||||||
|
|
||||||
return info.inodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ext2Inode::operator==(const Inode& other) const
|
bool Ext2Inode::operator==(const Inode& other) const
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <BAN/StringView.h>
|
||||||
|
#include <kernel/FS/Inode.h>
|
||||||
|
#include <kernel/FS/VirtualFileSystem.h>
|
||||||
|
|
||||||
|
namespace Kernel
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
BAN::ErrorOr<BAN::Vector<BAN::RefPtr<Inode>>> Inode::directory_inodes()
|
||||||
|
{
|
||||||
|
for (const auto& mount : VirtualFileSystem::get().mount_points())
|
||||||
|
if (*mount.inode == *this)
|
||||||
|
return mount.target->root_inode()->directory_inodes_impl();
|
||||||
|
return directory_inodes_impl();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<BAN::RefPtr<Inode>> Inode::directory_find(BAN::StringView name)
|
||||||
|
{
|
||||||
|
if (name == ".."sv)
|
||||||
|
return directory_find_impl(name);
|
||||||
|
for (const auto& mount : VirtualFileSystem::get().mount_points())
|
||||||
|
if (*mount.inode == *this)
|
||||||
|
return mount.target->root_inode()->directory_find_impl(name);
|
||||||
|
return directory_find_impl(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -115,6 +115,32 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> VirtualFileSystem::mount_test()
|
||||||
|
{
|
||||||
|
auto mount = TRY(root_inode()->directory_find("mnt"sv));
|
||||||
|
if (!mount->ifdir())
|
||||||
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
if (TRY(mount->directory_inodes()).size() > 2)
|
||||||
|
return BAN::Error::from_errno(ENOTEMPTY);
|
||||||
|
|
||||||
|
for (auto* controller : m_storage_controllers)
|
||||||
|
{
|
||||||
|
for (auto* device : controller->devices())
|
||||||
|
{
|
||||||
|
for (auto& partition : device->partitions())
|
||||||
|
{
|
||||||
|
if (partition.name() == "mount-test"sv)
|
||||||
|
{
|
||||||
|
auto ext2fs = TRY(Ext2FS::create(partition));
|
||||||
|
TRY(m_mount_points.push_back({ mount, ext2fs }));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path)
|
BAN::ErrorOr<VirtualFileSystem::File> VirtualFileSystem::file_from_absolute_path(BAN::StringView path)
|
||||||
{
|
{
|
||||||
ASSERT(path.front() == '/');
|
ASSERT(path.front() == '/');
|
||||||
|
|
|
@ -195,6 +195,8 @@ void init2(void* tty1_ptr)
|
||||||
TTY* tty1 = (TTY*)tty1_ptr;
|
TTY* tty1 = (TTY*)tty1_ptr;
|
||||||
|
|
||||||
MUST(VirtualFileSystem::initialize());
|
MUST(VirtualFileSystem::initialize());
|
||||||
|
if (auto res = VirtualFileSystem::get().mount_test(); res.is_error())
|
||||||
|
dwarnln("{}", res.error());
|
||||||
|
|
||||||
MUST(Process::create_kernel(
|
MUST(Process::create_kernel(
|
||||||
[](void* tty1)
|
[](void* tty1)
|
||||||
|
|
Loading…
Reference in New Issue