Disable EXT2 writes; add experimental tmpfs
This is still a work in progress. ext2 writes are quite broken, so they have been completely disabled, but there's a new tmpfs mounted to /tmp that you can try to poke at. I'm still fixing up quirks in the VFS that make it incompatible with a bunch of stuff, but I did manage to write some files with vim, and swap files appear to be working at least somewhat. It's all still broken as fuck.
This commit is contained in:
parent
9901767cbe
commit
7c8d34d1b6
0
hdd/tmp/.dummy
Normal file
0
hdd/tmp/.dummy
Normal file
@ -327,6 +327,8 @@ uint32_t ext2_disk_inode_write_block(ext2_inodetable_t *inode, uint32_t inode_no
|
||||
* Create a new, regular, and empty file under directory 'parent'.
|
||||
*/
|
||||
void ext2_create(fs_node_t *parent, char *name, uint16_t permission) {
|
||||
debug_print(WARNING, "Attempt to write to EXT2 device blocked.");
|
||||
return 0;
|
||||
|
||||
debug_print(NOTICE, "Creating file %s", name);
|
||||
uint16_t mode = permission | EXT2_S_IFREG;
|
||||
@ -602,6 +604,9 @@ void ext2_disk_write_inode(ext2_inodetable_t *inode, uint32_t index) {
|
||||
}
|
||||
|
||||
uint32_t write_ext2_disk(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
debug_print(WARNING, "Attempt to write to EXT2 device blocked.");
|
||||
return 0;
|
||||
|
||||
ext2_inodetable_t *inode = ext2_disk_inode(node->inode);
|
||||
uint32_t end = offset + size;
|
||||
uint32_t start_block = offset / BLOCKSIZE;
|
||||
|
250
kernel/fs/tmpfs.c
Normal file
250
kernel/fs/tmpfs.c
Normal file
@ -0,0 +1,250 @@
|
||||
#include <system.h>
|
||||
#include <logging.h>
|
||||
#include <fs.h>
|
||||
#include <version.h>
|
||||
#include <process.h>
|
||||
|
||||
/* 1KB */
|
||||
#define BLOCKSIZE 1024
|
||||
|
||||
static uint8_t volatile lock = 0;
|
||||
|
||||
struct tmpfs_file {
|
||||
char * name;
|
||||
size_t length;
|
||||
size_t block_count;
|
||||
size_t pointers;
|
||||
uint32_t flags;
|
||||
char ** blocks;
|
||||
};
|
||||
|
||||
list_t * tmpfs_files = NULL;
|
||||
|
||||
char empty_block[BLOCKSIZE] = {0};
|
||||
|
||||
static struct tmpfs_file * tmpfs_file_new(char * name) {
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
struct tmpfs_file * t = malloc(sizeof(struct tmpfs_file));
|
||||
t->name = strdup(name);
|
||||
t->length = 0;
|
||||
t->pointers = 2;
|
||||
t->block_count = 0;
|
||||
t->flags = 0;
|
||||
t->blocks = malloc(t->pointers * sizeof(char *));
|
||||
for (size_t i = 0; i < t->pointers; ++i) {
|
||||
t->blocks[i] = NULL;
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
return t;
|
||||
}
|
||||
|
||||
static void tmpfs_file_blocks_embiggen(struct tmpfs_file * t) {
|
||||
t->pointers *= 2;
|
||||
debug_print(INFO, "Embiggening file %s to %d blocks", t->name, t->pointers);
|
||||
t->blocks = realloc(t->blocks, sizeof(char *) * t->pointers);
|
||||
}
|
||||
|
||||
static char * tmpfs_file_getset_block(struct tmpfs_file * t, size_t blockid, int create) {
|
||||
debug_print(INFO, "Reading block %d from file %s", blockid, t->name);
|
||||
if (create) {
|
||||
spin_lock(&lock);
|
||||
while (blockid >= t->pointers) {
|
||||
tmpfs_file_blocks_embiggen(t);
|
||||
}
|
||||
while (blockid >= t->block_count) {
|
||||
debug_print(INFO, "Allocating block %d for file %s", blockid, t->name);
|
||||
t->blocks[t->block_count] = malloc(BLOCKSIZE);
|
||||
t->block_count += 1;
|
||||
}
|
||||
spin_unlock(&lock);
|
||||
} else {
|
||||
if (blockid >= t->block_count) {
|
||||
debug_print(CRITICAL, "This will probably end badly.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
debug_print(WARNING, "Using block %d->0x%x (of %d) on file %s", blockid, t->blocks[blockid], t->block_count, t->name);
|
||||
return t->blocks[blockid];
|
||||
}
|
||||
|
||||
|
||||
static uint32_t read_tmpfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)(node->device);
|
||||
uint32_t end;
|
||||
if (offset + size > t->length) {
|
||||
end = t->length;
|
||||
} else {
|
||||
end = offset + size;
|
||||
}
|
||||
debug_print(INFO, "reading from %d to %d", offset, end);
|
||||
uint32_t start_block = offset / BLOCKSIZE;
|
||||
uint32_t end_block = end / BLOCKSIZE;
|
||||
uint32_t end_size = end - end_block * BLOCKSIZE;
|
||||
uint32_t size_to_read = end - offset;
|
||||
if (start_block == end_block && offset == end) return 0;
|
||||
if (end_size == 0) {
|
||||
end_block--;
|
||||
}
|
||||
if (start_block == end_block) {
|
||||
void *buf = tmpfs_file_getset_block(t, start_block, 0);
|
||||
memcpy(buffer, (uint8_t *)(((uint32_t)buf) + (offset % BLOCKSIZE)), size_to_read);
|
||||
return size_to_read;
|
||||
} else {
|
||||
uint32_t block_offset;
|
||||
uint32_t blocks_read = 0;
|
||||
for (block_offset = start_block; block_offset < end_block; block_offset++, blocks_read++) {
|
||||
if (block_offset == start_block) {
|
||||
void *buf = tmpfs_file_getset_block(t, block_offset, 0);
|
||||
memcpy(buffer, (uint8_t *)(((uint32_t)buf) + (offset % BLOCKSIZE)), BLOCKSIZE - (offset % BLOCKSIZE));
|
||||
} else {
|
||||
void *buf = tmpfs_file_getset_block(t, block_offset, 0);
|
||||
memcpy(buffer + BLOCKSIZE * blocks_read - (offset % BLOCKSIZE), buf, BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
void *buf = tmpfs_file_getset_block(t, end_block, 0);
|
||||
memcpy(buffer + BLOCKSIZE * blocks_read - (offset % BLOCKSIZE), buf, end_size);
|
||||
}
|
||||
return size_to_read;
|
||||
}
|
||||
|
||||
static uint32_t write_tmpfs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)(node->device);
|
||||
uint32_t end;
|
||||
if (offset + size > t->length) {
|
||||
t->length = offset + size;
|
||||
}
|
||||
end = offset + size;
|
||||
uint32_t start_block = offset / BLOCKSIZE;
|
||||
uint32_t end_block = end / BLOCKSIZE;
|
||||
uint32_t end_size = end - end_block * BLOCKSIZE;
|
||||
uint32_t size_to_read = end - offset;
|
||||
if (end_size == 0) {
|
||||
end_block--;
|
||||
}
|
||||
if (start_block == end_block) {
|
||||
void *buf = tmpfs_file_getset_block(t, start_block, 1);
|
||||
memcpy((uint8_t *)(((uint32_t)buf) + (offset % BLOCKSIZE)), buffer, size_to_read);
|
||||
return size_to_read;
|
||||
} else {
|
||||
uint32_t block_offset;
|
||||
uint32_t blocks_read = 0;
|
||||
for (block_offset = start_block; block_offset < end_block; block_offset++, blocks_read++) {
|
||||
if (block_offset == start_block) {
|
||||
void *buf = tmpfs_file_getset_block(t, block_offset, 1);
|
||||
memcpy((uint8_t *)(((uint32_t)buf) + (offset % BLOCKSIZE)), buffer, BLOCKSIZE - (offset % BLOCKSIZE));
|
||||
} else {
|
||||
void *buf = tmpfs_file_getset_block(t, block_offset, 1);
|
||||
memcpy(buf, buffer + BLOCKSIZE * blocks_read - (offset % BLOCKSIZE), BLOCKSIZE);
|
||||
}
|
||||
}
|
||||
void *buf = tmpfs_file_getset_block(t, end_block, 1);
|
||||
memcpy(buf, buffer + BLOCKSIZE * blocks_read - (offset % BLOCKSIZE), end_size);
|
||||
}
|
||||
return size_to_read;
|
||||
}
|
||||
|
||||
static fs_node_t * tmpfs_from_file(struct tmpfs_file * t) {
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
fnode->inode = 0;
|
||||
strcpy(fnode->name, t->name);
|
||||
fnode->device = t;
|
||||
fnode->mask = 0777;
|
||||
fnode->uid = 0;
|
||||
fnode->gid = 0;
|
||||
fnode->flags = FS_FILE;
|
||||
fnode->read = read_tmpfs;
|
||||
fnode->write = write_tmpfs;
|
||||
fnode->open = NULL;
|
||||
fnode->close = NULL;
|
||||
fnode->readdir = NULL;
|
||||
fnode->finddir = NULL;
|
||||
fnode->length = t->length;
|
||||
return fnode;
|
||||
}
|
||||
|
||||
static struct dirent * readdir_tmpfs(fs_node_t *node, uint32_t index) {
|
||||
uint32_t i = 0;
|
||||
|
||||
debug_print(NOTICE, "tmpfs - readdir id=%d", index);
|
||||
|
||||
if (index >= tmpfs_files->length) return NULL;
|
||||
|
||||
foreach(f, tmpfs_files) {
|
||||
if (i == index) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
struct dirent * out = malloc(sizeof(struct dirent));
|
||||
memset(out, 0x00, sizeof(struct dirent));
|
||||
out->ino = (uint32_t)t;
|
||||
strcpy(out->name, t->name);
|
||||
return out;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static fs_node_t * finddir_tmpfs(fs_node_t * node, char * name) {
|
||||
if (!name) return NULL;
|
||||
|
||||
spin_lock(&lock);
|
||||
|
||||
foreach(f, tmpfs_files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
spin_unlock(&lock);
|
||||
return tmpfs_from_file(t);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void create_tmpfs(fs_node_t *parent, char *name, uint16_t permission) {
|
||||
if (!name) return;
|
||||
|
||||
debug_print(CRITICAL, "Creating TMPFS file %s", name);
|
||||
|
||||
spin_lock(&lock);
|
||||
foreach(f, tmpfs_files) {
|
||||
struct tmpfs_file * t = (struct tmpfs_file *)f->value;
|
||||
if (!strcmp(name, t->name)) {
|
||||
spin_unlock(&lock);
|
||||
debug_print(WARNING, "... already exists.");
|
||||
return; /* Already exists */
|
||||
}
|
||||
}
|
||||
spin_unlock(&lock);
|
||||
|
||||
debug_print(NOTICE, "... creating a new file.");
|
||||
struct tmpfs_file * t = tmpfs_file_new(name);
|
||||
t->flags = permission;
|
||||
|
||||
list_insert(tmpfs_files, t);
|
||||
}
|
||||
|
||||
fs_node_t * tmpfs_create() {
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
fnode->inode = 0;
|
||||
strcpy(fnode->name, "tmp");
|
||||
fnode->uid = 0;
|
||||
fnode->gid = 0;
|
||||
fnode->flags = FS_DIRECTORY;
|
||||
fnode->read = NULL;
|
||||
fnode->write = NULL;
|
||||
fnode->open = NULL;
|
||||
fnode->close = NULL;
|
||||
fnode->readdir = readdir_tmpfs;
|
||||
fnode->finddir = finddir_tmpfs;
|
||||
fnode->create = create_tmpfs;
|
||||
|
||||
tmpfs_files = list_create();
|
||||
return fnode;
|
||||
}
|
@ -132,6 +132,34 @@ int ioctl_fs(fs_node_t *node, int request, void * argp) {
|
||||
*/
|
||||
|
||||
int create_file_fs(char *name, uint16_t permission) {
|
||||
fs_node_t * parent;
|
||||
char *cwd = (char *)(current_process->wd_name);
|
||||
char *path = canonicalize_path(cwd, name);
|
||||
|
||||
char * parent_path = malloc(strlen(path) + 4);
|
||||
sprintf(parent_path, "%s/..", path);
|
||||
|
||||
char * f_path = path + strlen(path) - 1;
|
||||
while (f_path > path) {
|
||||
if (*f_path == '/') {
|
||||
f_path += 1;
|
||||
break;
|
||||
}
|
||||
f_path--;
|
||||
}
|
||||
|
||||
debug_print(WARNING, "creating file %s within %s (hope these strings are good)", f_path, parent_path);
|
||||
|
||||
parent = kopen(parent_path, 0);
|
||||
free(parent_path);
|
||||
|
||||
if (parent->create) {
|
||||
parent->create(parent, f_path, permission);
|
||||
}
|
||||
|
||||
free(path);
|
||||
free(parent);
|
||||
#if 0
|
||||
int32_t i = strlen(name);
|
||||
char *dir_name = malloc(i + 1);
|
||||
memcpy(dir_name, name, i);
|
||||
@ -170,10 +198,12 @@ int create_file_fs(char *name, uint16_t permission) {
|
||||
|
||||
free(node);
|
||||
free(dir_name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mkdir_fs(char *name, uint16_t permission) {
|
||||
#if 0
|
||||
int32_t i = strlen(name);
|
||||
char *dir_name = malloc(i + 1);
|
||||
memcpy(dir_name, name, i);
|
||||
@ -213,6 +243,8 @@ int mkdir_fs(char *name, uint16_t permission) {
|
||||
free(node);
|
||||
free(dir_name);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -526,6 +558,11 @@ fs_node_t *get_mount_point(char * path, unsigned int path_depth, char **outpath,
|
||||
|
||||
*outdepth = _tree_depth;
|
||||
|
||||
if (last) {
|
||||
fs_node_t * last_clone = malloc(sizeof(fs_node_t));
|
||||
memcpy(last_clone, last, sizeof(fs_node_t));
|
||||
return last_clone;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,7 @@ extern fs_node_t * null_device_create();
|
||||
extern fs_node_t * zero_device_create();
|
||||
extern fs_node_t * serial_device_create(int device);
|
||||
extern fs_node_t * procfs_create();
|
||||
extern fs_node_t * tmpfs_create();
|
||||
extern void serial_mount_devices();
|
||||
extern int openpty(int * master, int * slave, char * name, void * _ign0, void * size);
|
||||
|
||||
|
@ -146,6 +146,7 @@ int main(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) {
|
||||
vfs_mount("/dev/zero", zero_device_create());
|
||||
vfs_mount("/dev/hello", hello_device_create());
|
||||
vfs_mount("/dev/random", random_device_create());
|
||||
vfs_mount("/tmp", tmpfs_create());
|
||||
|
||||
vfs_mount("/proc", procfs_create());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user