Initial TmpFS work
This commit is contained in:
parent
c2a08060cf
commit
70b3d70133
51
kernel/include/fs/TmpFS.h
Normal file
51
kernel/include/fs/TmpFS.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include "fs/VFS.h"
|
||||
|
||||
namespace TmpFSImpl
|
||||
{
|
||||
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
|
||||
ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer);
|
||||
}
|
||||
|
||||
class TmpFS
|
||||
{
|
||||
public:
|
||||
VFS::Node* root()
|
||||
{
|
||||
return m_root;
|
||||
}
|
||||
|
||||
static TmpFS* create(const char* name);
|
||||
static void release(TmpFS* fs);
|
||||
|
||||
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
|
||||
ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer);
|
||||
|
||||
void purge();
|
||||
|
||||
private:
|
||||
struct File
|
||||
{
|
||||
char* buf;
|
||||
size_t len;
|
||||
int valid;
|
||||
};
|
||||
|
||||
struct Directory
|
||||
{
|
||||
VFS::Node* buf;
|
||||
size_t len;
|
||||
int valid;
|
||||
};
|
||||
|
||||
template <typename T> struct Array
|
||||
{
|
||||
T* buf;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
TmpFS(const char* name);
|
||||
Array<File> m_files;
|
||||
Array<Directory> m_dirs;
|
||||
VFS::Node* m_root;
|
||||
};
|
99
kernel/src/fs/TmpFS.cpp
Normal file
99
kernel/src/fs/TmpFS.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "fs/TmpFS.h"
|
||||
#include "std/stdlib.h"
|
||||
#include "std/string.h"
|
||||
|
||||
ssize_t TmpFSImpl::read(VFS::Node* node, size_t offset, size_t size, char* buffer)
|
||||
{
|
||||
if (!node) return -1;
|
||||
if (!node->impl) return -1;
|
||||
return ((TmpFS*)node->impl)->read(node, offset, size, buffer);
|
||||
}
|
||||
|
||||
ssize_t TmpFSImpl::write(VFS::Node* node, size_t offset, size_t size, char* buffer)
|
||||
{
|
||||
if (!node) return -1;
|
||||
if (!node->impl) return -1;
|
||||
return ((TmpFS*)node->impl)->write(node, offset, size, buffer);
|
||||
}
|
||||
|
||||
TmpFS* TmpFS::create(const char* name)
|
||||
{
|
||||
return new TmpFS(name);
|
||||
}
|
||||
|
||||
void TmpFS::release(TmpFS* fs)
|
||||
{
|
||||
fs->purge();
|
||||
kfree(fs->m_dirs.buf);
|
||||
delete fs->root();
|
||||
delete fs;
|
||||
}
|
||||
|
||||
extern uint64_t clock_now();
|
||||
|
||||
TmpFS::TmpFS(const char* name)
|
||||
{
|
||||
m_root = new VFS::Node;
|
||||
m_root->atime = m_root->ctime = m_root->mtime = clock_now();
|
||||
m_root->impl = (uint64_t)this;
|
||||
m_root->inode = 0;
|
||||
m_root->gid = m_root->uid = 0;
|
||||
m_root->mode = 0755;
|
||||
m_root->length = 0;
|
||||
m_root->type = VFS_DIRECTORY;
|
||||
m_root->tty = 0;
|
||||
strlcpy(m_root->name, name, sizeof(m_root->name));
|
||||
m_dirs.buf = (Directory*)krealloc(nullptr, sizeof(Directory));
|
||||
m_dirs.len = 1;
|
||||
m_dirs.buf[0] = {nullptr, 0, 1};
|
||||
}
|
||||
|
||||
void TmpFS::purge()
|
||||
{
|
||||
for (size_t i = 0; i < m_dirs.len; i++)
|
||||
{
|
||||
if (m_dirs.buf[i].valid && m_dirs.buf[i].len) kfree(m_dirs.buf[i].buf);
|
||||
}
|
||||
|
||||
m_dirs.buf = (Directory*)krealloc(m_dirs.buf, sizeof(Directory)); // leave space for the root directory
|
||||
|
||||
for (size_t i = 0; i < m_files.len; i++)
|
||||
{
|
||||
if (m_files.buf[i].valid && m_files.buf[i].len) kfree(m_files.buf[i].buf);
|
||||
}
|
||||
|
||||
kfree(m_files.buf);
|
||||
}
|
||||
|
||||
ssize_t TmpFS::read(VFS::Node* node, size_t offset, size_t size, char* buffer)
|
||||
{
|
||||
if (!node) return -1;
|
||||
if (node->inode >= m_files.len) return -1;
|
||||
File& file = m_files.buf[node->inode];
|
||||
if (!file.valid) return -1;
|
||||
if (offset > file.len) return 0;
|
||||
if (offset + size > file.len) { size = file.len - offset; }
|
||||
memcpy(buffer, (void*)(file.buf + offset), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t TmpFS::write(VFS::Node* node, size_t offset, size_t size, char* buffer)
|
||||
{
|
||||
if (!node) return -1;
|
||||
if (node->inode >= m_files.len) return -1;
|
||||
File& file = m_files.buf[node->inode];
|
||||
if (!file.valid) return -1;
|
||||
if (offset + size > file.len)
|
||||
{
|
||||
char* newbuf = (char*)krealloc(file.buf, offset + size);
|
||||
if (!newbuf) { size = file.len - offset; }
|
||||
else
|
||||
{
|
||||
file.buf = newbuf;
|
||||
file.len = offset + size;
|
||||
node->length = file.len;
|
||||
}
|
||||
}
|
||||
memcpy((void*)(file.buf + offset), buffer, size);
|
||||
return size;
|
||||
}
|
Loading…
Reference in New Issue
Block a user