Try building a tmpfs, but weird stuff happens
This commit is contained in:
parent
000ffd1fae
commit
3451d50a37
61
initrd/make-folders.sh
Normal file
61
initrd/make-folders.sh
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
mkdir /tmp/folder0
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder1
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder2
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder3
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder4
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder5
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder6
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder7
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder8
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder9
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder10
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder11
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder12
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder13
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder14
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder15
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder16
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder17
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder18
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder19
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder20
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder21
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder22
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder23
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder24
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder25
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder26
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder27
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder28
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder29
|
||||||
|
sleep 1
|
||||||
|
mkdir /tmp/folder30
|
16
kernel/include/fs/TmpFS.h
Normal file
16
kernel/include/fs/TmpFS.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fs/VFS.h"
|
||||||
|
|
||||||
|
namespace TmpFS
|
||||||
|
{
|
||||||
|
VFS::Node* get();
|
||||||
|
|
||||||
|
VFS::Node* finddir(VFS::Node* node, const char* filename);
|
||||||
|
VFS::Node* readdir(VFS::Node* node, long offset);
|
||||||
|
|
||||||
|
int mkdir(VFS::Node* node, const char* name, mode_t mode);
|
||||||
|
|
||||||
|
ssize_t read(VFS::Node* node, size_t offset, size_t length, char* buffer);
|
||||||
|
ssize_t write(VFS::Node* node, size_t offset, size_t length, char* buffer);
|
||||||
|
}
|
167
kernel/include/utils/Dynamic.h
Normal file
167
kernel/include/utils/Dynamic.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "log/Log.h"
|
||||||
|
#include "std/ensure.h"
|
||||||
|
#include "std/stdlib.h"
|
||||||
|
#include "std/string.h"
|
||||||
|
#include "utils/new.h"
|
||||||
|
|
||||||
|
#define __noinline __attribute__((noinline))
|
||||||
|
|
||||||
|
template <typename T> struct Dynamic
|
||||||
|
{
|
||||||
|
Dynamic()
|
||||||
|
{
|
||||||
|
set_expand_rate(16);
|
||||||
|
ensure(expand_fixed());
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic(size_t capacity)
|
||||||
|
{
|
||||||
|
set_expand_rate(16);
|
||||||
|
ensure(expand_fixed());
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic(const Dynamic<T>& other)
|
||||||
|
{
|
||||||
|
set_expand_rate(other.m_expand_rate);
|
||||||
|
ensure_capacity(other.capacity());
|
||||||
|
m_size = other.size();
|
||||||
|
memcpy(m_buf, other.data(), m_capacity * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic(Dynamic<T>&& other)
|
||||||
|
{
|
||||||
|
set_expand_rate(other.m_expand_rate);
|
||||||
|
m_buf = other.release_data();
|
||||||
|
m_capacity = other.capacity();
|
||||||
|
m_size = other.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dynamic<T>& operator=(const Dynamic<T>& other)
|
||||||
|
{
|
||||||
|
if (this == &other) return *this;
|
||||||
|
|
||||||
|
if (m_buf)
|
||||||
|
{
|
||||||
|
while (m_size) pop(); // destroy all objects
|
||||||
|
kfree(m_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
set_expand_rate(other.m_expand_rate);
|
||||||
|
ensure_capacity(other.capacity());
|
||||||
|
m_size = other.size();
|
||||||
|
memcpy(m_buf, other.data(), m_capacity * sizeof(T));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Dynamic()
|
||||||
|
{
|
||||||
|
if (m_buf)
|
||||||
|
{
|
||||||
|
while (m_size) pop(); // destroy all objects
|
||||||
|
kfree(m_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T& at(size_t index)
|
||||||
|
{
|
||||||
|
ensure(index < m_size);
|
||||||
|
return m_buf[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& at(size_t index) const
|
||||||
|
{
|
||||||
|
ensure(index < m_size);
|
||||||
|
return m_buf[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[](size_t index)
|
||||||
|
{
|
||||||
|
return at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator[](size_t index) const
|
||||||
|
{
|
||||||
|
return at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expand_capacity(size_t capacity)
|
||||||
|
{
|
||||||
|
return expand(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensure_capacity(size_t capacity)
|
||||||
|
{
|
||||||
|
ensure(expand(capacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_expand_rate(size_t rate)
|
||||||
|
{
|
||||||
|
if (!rate) return;
|
||||||
|
m_expand_rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
__noinline bool push(const T& item)
|
||||||
|
{
|
||||||
|
if (m_size == m_capacity)
|
||||||
|
if (!expand_fixed()) return false;
|
||||||
|
m_size++;
|
||||||
|
T* loc = ptr_at(m_size - 1);
|
||||||
|
new (loc) T(item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
at(m_size - 1).~T();
|
||||||
|
m_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t capacity() const
|
||||||
|
{
|
||||||
|
return m_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* data() const
|
||||||
|
{
|
||||||
|
return m_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* release_data()
|
||||||
|
{
|
||||||
|
T* result = m_buf;
|
||||||
|
m_buf = nullptr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_buf = nullptr;
|
||||||
|
size_t m_capacity = 0;
|
||||||
|
size_t m_size = 0;
|
||||||
|
size_t m_expand_rate = 16;
|
||||||
|
|
||||||
|
bool expand(size_t new_capacity)
|
||||||
|
{
|
||||||
|
m_buf = (T*)krealloc(m_buf, new_capacity * sizeof(T));
|
||||||
|
if (!m_buf) return false;
|
||||||
|
m_capacity = new_capacity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expand_fixed()
|
||||||
|
{
|
||||||
|
ensure(m_expand_rate != 0);
|
||||||
|
return expand(m_capacity + m_expand_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
T* ptr_at(size_t index)
|
||||||
|
{
|
||||||
|
return (T*)((char*)m_buf + index * sizeof(T));
|
||||||
|
}
|
||||||
|
};
|
94
kernel/src/fs/TmpFS.cpp
Normal file
94
kernel/src/fs/TmpFS.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "fs/TmpFS.h"
|
||||||
|
#include "std/errno.h"
|
||||||
|
#include "std/string.h"
|
||||||
|
#include "utils/Dynamic.h"
|
||||||
|
#include "utils/move.h"
|
||||||
|
|
||||||
|
namespace TmpFS
|
||||||
|
{
|
||||||
|
struct File
|
||||||
|
{
|
||||||
|
char* ptr;
|
||||||
|
uint64_t pages;
|
||||||
|
uint64_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Directory
|
||||||
|
{
|
||||||
|
Dynamic<VFS::Node*> files;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* tmpfs_root = nullptr;
|
||||||
|
|
||||||
|
Dynamic<TmpFS::Directory> tmpfs_dirs;
|
||||||
|
Dynamic<TmpFS::File> tmpfs_files;
|
||||||
|
|
||||||
|
extern uint64_t clock_now();
|
||||||
|
|
||||||
|
VFS::Node* TmpFS::get()
|
||||||
|
{
|
||||||
|
if (tmpfs_root) return tmpfs_root;
|
||||||
|
tmpfs_root = new VFS::Node;
|
||||||
|
tmpfs_root->length = 0;
|
||||||
|
tmpfs_root->inode = 0;
|
||||||
|
tmpfs_root->type = VFS_DIRECTORY;
|
||||||
|
tmpfs_root->find_func = TmpFS::finddir;
|
||||||
|
tmpfs_root->readdir_func = TmpFS::readdir;
|
||||||
|
tmpfs_root->mkdir_func = TmpFS::mkdir;
|
||||||
|
tmpfs_root->mode = 0755;
|
||||||
|
tmpfs_root->uid = tmpfs_root->gid = 0;
|
||||||
|
tmpfs_root->atime = tmpfs_root->ctime = tmpfs_root->mtime = clock_now();
|
||||||
|
strncpy(tmpfs_root->name, "tmpfs", sizeof(tmpfs_root->name));
|
||||||
|
tmpfs_dirs.ensure_capacity(16);
|
||||||
|
tmpfs_files.ensure_capacity(16);
|
||||||
|
tmpfs_dirs.set_expand_rate(16);
|
||||||
|
tmpfs_files.set_expand_rate(16);
|
||||||
|
ensure(tmpfs_dirs.push({{}}));
|
||||||
|
return tmpfs_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* TmpFS::finddir(VFS::Node* node, const char* filename)
|
||||||
|
{
|
||||||
|
if (!node) return nullptr;
|
||||||
|
if (node->inode >= tmpfs_dirs.size()) return nullptr;
|
||||||
|
auto& dir = tmpfs_dirs[node->inode];
|
||||||
|
for (size_t i = 0; i < dir.files.size(); i++)
|
||||||
|
{
|
||||||
|
if (!strncmp(dir.files[i]->name, filename, sizeof(dir.files[i]->name))) return dir.files[i];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VFS::Node* TmpFS::readdir(VFS::Node* node, long offset)
|
||||||
|
{
|
||||||
|
if (!node) return nullptr;
|
||||||
|
if (node->inode >= tmpfs_dirs.size()) return nullptr;
|
||||||
|
auto& dir = tmpfs_dirs[node->inode];
|
||||||
|
if (offset < 0) return nullptr;
|
||||||
|
if ((size_t)offset >= dir.files.size()) return nullptr;
|
||||||
|
return dir.files[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
int TmpFS::mkdir(VFS::Node* node, const char* name, mode_t mode)
|
||||||
|
{
|
||||||
|
if (node->inode >= tmpfs_dirs.size()) return -EINVAL;
|
||||||
|
if (!(node->type & VFS_DIRECTORY)) return -ENOTDIR;
|
||||||
|
auto& parent = tmpfs_dirs[node->inode];
|
||||||
|
uint64_t inode = tmpfs_dirs.size();
|
||||||
|
VFS::Node* new_node = new VFS::Node;
|
||||||
|
new_node->inode = inode;
|
||||||
|
new_node->find_func = TmpFS::finddir;
|
||||||
|
new_node->readdir_func = TmpFS::readdir;
|
||||||
|
new_node->mkdir_func = TmpFS::mkdir;
|
||||||
|
new_node->length = 0;
|
||||||
|
new_node->type = VFS_DIRECTORY;
|
||||||
|
new_node->mode = mode;
|
||||||
|
new_node->uid = new_node->gid = 0;
|
||||||
|
new_node->atime = new_node->ctime = new_node->mtime = clock_now();
|
||||||
|
strncpy(new_node->name, name, sizeof(new_node->name));
|
||||||
|
ensure(tmpfs_dirs.push({{}}));
|
||||||
|
node->length++;
|
||||||
|
ensure(parent.files.push(new_node));
|
||||||
|
return 0;
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cpu/CPU.h"
|
#include "cpu/CPU.h"
|
||||||
|
#include "fs/TmpFS.h"
|
||||||
#include "fs/devices/DeviceFS.h"
|
#include "fs/devices/DeviceFS.h"
|
||||||
#include "gdt/GDT.h"
|
#include "gdt/GDT.h"
|
||||||
#include "init/Init.h"
|
#include "init/Init.h"
|
||||||
@ -58,7 +59,9 @@ extern "C" void _start()
|
|||||||
});
|
});
|
||||||
|
|
||||||
ensure(VFS::mkdir("/dev") == 0);
|
ensure(VFS::mkdir("/dev") == 0);
|
||||||
|
ensure(VFS::mkdir("/tmp") == 0);
|
||||||
VFS::mount("/dev", DeviceFS::get());
|
VFS::mount("/dev", DeviceFS::get());
|
||||||
|
VFS::mount("/tmp", TmpFS::get());
|
||||||
|
|
||||||
Init::finish_kernel_boot();
|
Init::finish_kernel_boot();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user