Bläddra i källkod

Merge branch 'vfs_fix' into open

greatbridf 2 år sedan
förälder
incheckning
5619ebf4c1

+ 2 - 0
include/fs/fat.hpp

@@ -100,6 +100,7 @@ struct PACKED directory_entry {
     uint32_t size;
 };
 
+// TODO: deallocate inodes when dentry is destroyed
 class fat32 : public virtual fs::vfs {
 private:
     constexpr static uint32_t SECTOR_SIZE = 512;
@@ -113,6 +114,7 @@ private:
     uint32_t next_free_cluster_hint;
     cluster_t root_dir;
     cluster_t data_region_offset;
+    // TODO: use block device special node id
     inode* device;
     uint16_t reserved_sectors;
     uint8_t fat_copies;

+ 1 - 1
include/kernel/mm.hpp

@@ -170,7 +170,7 @@ public:
                 },
             },
             .owner = this,
-            .pgs = ::types::kernel_ident_allocator_new<page_arr>(),
+            .pgs = types::_new<types::kernel_ident_allocator, page_arr>(),
         });
     }
 

+ 6 - 2
include/kernel/vfs.hpp

@@ -75,10 +75,12 @@ public:
     struct dentry {
     public:
         using name_type = types::string<>;
+        template <typename T>
+        using allocator_type = types::kernel_allocator<T>;
 
     private:
-        types::list<dentry> children;
-        types::hash_map<name_type, dentry*, types::string_hasher<const name_type&>> idx_children;
+        types::list<dentry, allocator_type>* children = nullptr;
+        types::hash_map<name_type, dentry*, types::string_hasher<const name_type&>, allocator_type>* idx_children = nullptr;
 
     public:
         dentry* parent;
@@ -101,6 +103,8 @@ public:
         dentry& operator=(const dentry& val) = delete;
         dentry& operator=(dentry&& val) = delete;
 
+        ~dentry();
+
         dentry* append(inode* ind, const name_type& name);
         dentry* append(inode* ind, name_type&& name);
 

+ 20 - 42
include/types/allocator.hpp

@@ -4,7 +4,7 @@
 #include <types/stdint.h>
 #include <types/types.h>
 
-inline void* operator new(size_t, void* ptr)
+constexpr void* operator new(size_t, void* ptr)
 {
     return ptr;
 }
@@ -31,12 +31,12 @@ class kernel_allocator {
 public:
     using value_type = T;
 
-    static value_type* allocate_memory(size_t count)
+    static constexpr value_type* allocate_memory(size_t count)
     {
         return static_cast<value_type*>(::k_malloc(count));
     }
 
-    static void deallocate_memory(value_type* ptr)
+    static constexpr void deallocate_memory(value_type* ptr)
     {
         ::k_free(ptr);
     }
@@ -47,55 +47,33 @@ class kernel_ident_allocator {
 public:
     using value_type = T;
 
-    static value_type* allocate_memory(size_t count)
+    static constexpr value_type* allocate_memory(size_t count)
     {
         return static_cast<value_type*>(::ki_malloc(count));
     }
 
-    static void deallocate_memory(value_type* ptr)
+    static constexpr void deallocate_memory(value_type* ptr)
     {
         ::ki_free(ptr);
     }
 };
 
-template <typename T, typename... Args>
-constexpr T* kernel_allocator_new(Args&&... args)
+template <template <typename _T> class Allocator, typename T, typename... Args>
+constexpr T* _new(Args&&... args)
 {
-    return allocator_traits<kernel_allocator<T>>::allocate_and_construct(forward<Args>(args)...);
+    return allocator_traits<Allocator<T>>::allocate_and_construct(forward<Args>(args)...);
 }
 
-template <PointerType T, typename... Args>
-constexpr auto kernel_allocator_pnew(T, Args&&... args)
+template <template <typename _T> class Allocator, typename T, typename... Args>
+constexpr T* pnew(T* = nullptr, Args&&... args)
 {
-    using value_type = typename traits::remove_pointer<T>::type;
-    return kernel_allocator_new<value_type>(forward<Args>(args)...);
+    return _new<Allocator, T, Args...>(forward<Args>(args)...);
 }
 
-template <typename T, typename... Args>
-constexpr T* kernel_ident_allocator_new(Args&&... args)
+template <template <typename _T> class Allocator, typename T>
+constexpr void pdelete(T* ptr)
 {
-    return allocator_traits<kernel_ident_allocator<T>>::allocate_and_construct(forward<Args>(args)...);
-}
-
-template <PointerType T, typename... Args>
-constexpr auto kernel_ident_allocator_pnew(T, Args&&... args)
-{
-    using value_type = typename traits::remove_pointer<T>::type;
-    return kernel_ident_allocator_new<value_type>(forward<Args>(args)...);
-}
-
-template <PointerType T>
-constexpr void kernel_allocator_delete(T ptr)
-{
-    using value_type = typename traits::remove_pointer<T>::type;
-    return allocator_traits<kernel_allocator<value_type>>::deconstruct_and_deallocate(ptr);
-}
-
-template <PointerType T>
-constexpr void kernel_ident_allocator_delete(T ptr)
-{
-    using value_type = typename traits::remove_pointer<T>::type;
-    return allocator_traits<kernel_ident_allocator<value_type>>::deconstruct_and_deallocate(ptr);
+    allocator_traits<Allocator<T>>::deconstruct_and_deallocate(ptr);
 }
 
 template <Allocator _allocator>
@@ -103,7 +81,7 @@ class allocator_traits {
 public:
     using value_type = typename _allocator::value_type;
 
-    static value_type* allocate(size_t count)
+    static constexpr value_type* allocate(size_t count)
     {
         if (count == 0)
             return nullptr;
@@ -111,35 +89,35 @@ public:
     }
 
     template <typename... Args>
-    static value_type* construct(value_type* ptr, Args&&... args)
+    static constexpr value_type* construct(value_type* ptr, Args&&... args)
     {
         new (ptr) value_type(forward<Args>(args)...);
         return ptr;
     }
 
     template <typename... Args>
-    static value_type* allocate_and_construct(Args&&... args)
+    static constexpr value_type* allocate_and_construct(Args&&... args)
     {
         auto* ptr = allocate(1);
         construct(ptr, forward<Args>(args)...);
         return ptr;
     }
 
-    static void deconstruct(value_type* ptr)
+    static constexpr void deconstruct(value_type* ptr)
     {
         if (!ptr)
             return;
         ptr->~value_type();
     }
 
-    static void deallocate(value_type* ptr)
+    static constexpr void deallocate(value_type* ptr)
     {
         if (!ptr)
             return;
         _allocator::deallocate_memory(ptr);
     }
 
-    static void deconstruct_and_deallocate(value_type* ptr)
+    static constexpr void deconstruct_and_deallocate(value_type* ptr)
     {
         if (!ptr)
             return;

+ 1 - 1
src/kernel/event/event.cpp

@@ -17,7 +17,7 @@ namespace event {
 ::types::list<::input_event>& input_event_queue(void)
 {
     if (!_input_event_queue) {
-        _input_event_queue = types::kernel_allocator_new<types::list<input_event>>();
+        _input_event_queue = types::pnew<types::kernel_allocator>(_input_event_queue);
     }
     return *_input_event_queue;
 }

+ 2 - 2
src/kernel/hw/ata.cpp

@@ -201,11 +201,11 @@ static inline void mbr_part_probe(fs::inode* drive, uint16_t major, uint16_t min
 // data: void (*func_to_call_next)(void)
 void hw::init_ata(void)
 {
-    ata_pri = types::kernel_allocator_new<ata>(ATA_PRIMARY_BUS_BASE);
+    ata_pri = types::pnew<types::kernel_allocator>(ata_pri, ATA_PRIMARY_BUS_BASE);
     if (ata_pri->identify())
         ata_pri->select(true);
 
-    ata_sec = types::kernel_allocator_new<ata>(ATA_SECONDARY_BUS_BASE);
+    ata_sec = types::pnew<types::kernel_allocator>(ata_pri, ATA_SECONDARY_BUS_BASE);
     if (ata_pri->identify())
         ata_pri->select(true);
 

+ 4 - 4
src/kernel/mem.cpp

@@ -305,7 +305,7 @@ struct page allocate_page(void)
     return page {
         .phys_page_id = alloc_raw_page(),
         .pte = nullptr,
-        .ref_count = types::kernel_ident_allocator_new<size_t>(0),
+        .ref_count = types::_new<types::kernel_ident_allocator, size_t>(0),
         .attr { 0 },
     };
 }
@@ -523,13 +523,13 @@ void init_mem(void)
     // map the 16MiB-768MiB identically
     init_paging_map_low_mem_identically();
 
-    kernel_mms = types::kernel_ident_allocator_pnew(kernel_mms, KERNEL_PAGE_DIRECTORY_ADDR);
+    kernel_mms = types::pnew<types::kernel_ident_allocator>(kernel_mms, KERNEL_PAGE_DIRECTORY_ADDR);
     auto heap_mm = kernel_mms->addarea(KERNEL_HEAP_START, true, true);
 
     // create empty_page struct
     empty_page.attr.in.cow = 0;
     empty_page.phys_page_id = to_page(EMPTY_PAGE_ADDR);
-    empty_page.ref_count = types::kernel_ident_allocator_new<size_t>(1);
+    empty_page.ref_count = types::_new<types::kernel_ident_allocator, size_t>(1);
     empty_page.pte = to_pte(*KERNEL_PAGE_DIRECTORY_ADDR, empty_page.phys_page_id);
     empty_page.pte->in.rw = 0;
     invalidate_tlb(0x00000000);
@@ -538,7 +538,7 @@ void init_mem(void)
     while (heap_mm->pgs->size() < 256 * 1024 * 1024 / PAGE_SIZE)
         heap_mm->append_page(&empty_page, true, true, true, true);
 
-    kernel_heap_allocator = types::kernel_ident_allocator_pnew(kernel_heap_allocator,
+    kernel_heap_allocator = types::pnew<types::kernel_ident_allocator>(kernel_heap_allocator,
         KERNEL_HEAP_START, vptrdiff(KERNEL_HEAP_LIMIT, KERNEL_HEAP_START));
 }
 

+ 3 - 3
src/kernel/process.cpp

@@ -168,7 +168,7 @@ void NORETURN _kernel_init(void)
     hw::init_ata();
 
     // TODO: parse kernel parameters
-    auto* _new_fs = fs::register_fs(types::kernel_allocator_new<fs::fat::fat32>(fs::vfs_open("/dev/hda1")->ind));
+    auto* _new_fs = fs::register_fs(types::_new<types::kernel_allocator, fs::fat::fat32>(fs::vfs_open("/dev/hda1")->ind));
     int ret = fs::fs_root->ind->fs->mount(fs::vfs_open("/mnt"), _new_fs);
     assert_likely(ret == GB_OK);
 
@@ -214,8 +214,8 @@ void k_new_thread(void (*func)(void*), void* data)
 
 void NORETURN init_scheduler()
 {
-    procs = types::kernel_allocator_pnew(procs);
-    readythds = types::kernel_ident_allocator_pnew(readythds);
+    procs = types::pnew<types::kernel_allocator>(procs);
+    readythds = types::pnew<types::kernel_allocator>(readythds);
 
     auto* init = &procs->emplace(1);
 

+ 32 - 13
src/kernel/vfs.cpp

@@ -27,6 +27,10 @@ fs::vfs::dentry::dentry(dentry* _parent, inode* _ind, const name_type& _name)
     , flags { 0 }
     , name(_name)
 {
+    if (!_ind || _ind->flags.in.directory) {
+        children = types::pnew<allocator_type>(children);
+        idx_children = types::pnew<allocator_type>(idx_children);
+    }
 }
 fs::vfs::dentry::dentry(dentry* _parent, inode* _ind, name_type&& _name)
     : parent(_parent)
@@ -34,28 +38,40 @@ fs::vfs::dentry::dentry(dentry* _parent, inode* _ind, name_type&& _name)
     , flags { 0 }
     , name(types::move(_name))
 {
+    if (!_ind || _ind->flags.in.directory) {
+        children = types::pnew<allocator_type>(children);
+        idx_children = types::pnew<allocator_type>(idx_children);
+    }
 }
 fs::vfs::dentry::dentry(dentry&& val)
-    : children(types::move(val.children))
-    , idx_children(types::move(val.idx_children))
+    : children(val.children)
+    , idx_children(val.idx_children)
     , parent(val.parent)
     , ind(val.ind)
     , flags { val.flags }
     , name(types::move(val.name))
 {
-    for (auto& item : children)
+    for (auto& item : *children)
         item.parent = this;
+    memset(&val, 0x00, sizeof(dentry));
+}
+fs::vfs::dentry::~dentry()
+{
+    if (children) {
+        types::pdelete<allocator_type>(children);
+        types::pdelete<allocator_type>(idx_children);
+    }
 }
 fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, const name_type& name)
 {
-    auto iter = children.emplace_back(this, ind, name);
-    idx_children.insert(iter->name, &iter);
+    auto iter = children->emplace_back(this, ind, name);
+    idx_children->insert(iter->name, &iter);
     return &iter;
 }
 fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, name_type&& name)
 {
-    auto iter = children.emplace_back(this, ind, types::move(name));
-    idx_children.insert(iter->name, &iter);
+    auto iter = children->emplace_back(this, ind, types::move(name));
+    idx_children->insert(iter->name, &iter);
     return &iter;
 }
 fs::vfs::dentry* fs::vfs::dentry::find(const name_type& name)
@@ -63,7 +79,7 @@ fs::vfs::dentry* fs::vfs::dentry::find(const name_type& name)
     if (ind->flags.in.directory && !flags.in.present)
         ind->fs->load_dentry(this);
 
-    auto iter = idx_children.find(name);
+    auto iter = idx_children->find(name);
     if (!iter) {
         errno = ENOTFOUND;
         return nullptr;
@@ -74,15 +90,15 @@ fs::vfs::dentry* fs::vfs::dentry::find(const name_type& name)
 fs::vfs::dentry* fs::vfs::dentry::replace(dentry* val)
 {
     // TODO: prevent the dirent to be swapped out of memory
-    parent->idx_children.find(this->name)->value = val;
+    parent->idx_children->find(this->name)->value = val;
     return this;
 }
 void fs::vfs::dentry::invalidate(void)
 {
     // TODO: write back
     flags.in.dirty = 0;
-    children.clear();
-    idx_children.clear();
+    children->clear();
+    idx_children->clear();
     flags.in.present = 0;
 }
 fs::vfs::vfs(void)
@@ -133,6 +149,9 @@ int fs::vfs::mount(dentry* mnt, vfs* new_fs)
 
     auto* orig_ent = mnt->replace(new_ent);
     _mount_recover_list.insert(new_ent, orig_ent);
+
+    new_ent->ind->flags.in.mount_point = 1;
+
     return GB_OK;
 }
 size_t fs::vfs::inode_read(inode*, char*, size_t, size_t, size_t)
@@ -462,9 +481,9 @@ void init_vfs(void)
     // null
     register_special_block(0, 0, b_null_read, b_null_write, 0, 0);
 
-    fs_es = types::kernel_allocator_new<types::list<vfs*>>();
+    fs_es = types::pnew<types::kernel_ident_allocator>(fs_es);
 
-    auto* rootfs = types::kernel_allocator_new<tmpfs>();
+    auto* rootfs = types::_new<types::kernel_allocator, tmpfs>();
     fs_es->push_back(rootfs);
     fs_root = rootfs->root();