summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-11-10 00:18:47 +0100
committerAnton Kling <anton@kling.gg>2023-11-10 00:18:47 +0100
commita098a603d0bad5dffa08fe76d03f7d9521757e78 (patch)
treeecc0d3a0f3c6e6b3e65d4b326762e92a6bcbbda3
parent240e715aed9ea8b1a6d3b89c84cf9af3c3436e6f (diff)
Kernel/fs: Dynamically allocate based upon file size.
This commit also changes "unsigned char" to "char". A slight step in the direction of making my coding style less bipolar.
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/fs/ext2.c63
-rw-r--r--kernel/fs/ext2.h7
3 files changed, 39 insertions, 33 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 59562aa..515ac51 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -1,7 +1,7 @@
CC="i686-sb-gcc"
AS="i686-sb-as"
OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o scalls/recvfrom.o math.o scalls/sendto.o signal.o scalls/kill.o scalls/sigaction.o network/tcp.o
-CFLAGS = -O3 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I.
+CFLAGS = -O3 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign
INCLUDE=-I./includes/ -I./libc/include/
all: myos.iso
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c
index b4d7716..0c226cf 100644
--- a/kernel/fs/ext2.c
+++ b/kernel/fs/ext2.c
@@ -20,8 +20,12 @@ void ext2_close(vfs_fd_t *fd) {
return; // There is nothing to clear
}
-int read_inode(int inode_num, unsigned char *data, uint64_t size,
- uint64_t offset, uint64_t *file_size);
+int read_inode(int inode_num, char *data, uint64_t size, uint64_t offset,
+ uint64_t *file_size);
+
+inline void get_inode_data_size(int inode_num, uint64_t *file_size) {
+ read_inode(inode_num, NULL, 0, 0, file_size);
+}
struct BLOCK_CACHE {
uint32_t block_num;
@@ -169,13 +173,13 @@ int ext2_get_inode_in_directory(int dir_inode, char *file,
ASSERT_BUT_FIXME_PROPOGATE(-1 !=
read_inode(dir_inode, NULL, 0, 0, &file_size));
uint64_t allocation_size = file_size;
- unsigned char *data = kmalloc(allocation_size);
+ char *data = kmalloc(allocation_size);
ASSERT_BUT_FIXME_PROPOGATE(
-1 != read_inode(dir_inode, data, allocation_size, 0, NULL));
direntry_header_t *dir;
- unsigned char *data_p = data;
- unsigned char *data_end = data + allocation_size;
+ char *data_p = data;
+ char *data_end = data + allocation_size;
for (; data_p <= (data_end - sizeof(direntry_header_t)) &&
(dir = (direntry_header_t *)data_p)->inode;
data_p += dir->size) {
@@ -195,17 +199,20 @@ int ext2_get_inode_in_directory(int dir_inode, char *file,
return 0;
}
-int ext2_read_dir(int dir_inode, unsigned char *buffer, size_t len,
- size_t offset) {
- unsigned char data[block_byte_size];
- read_inode(dir_inode, data, block_byte_size, 0, 0);
+int ext2_read_dir(int dir_inode, char *buffer, size_t len, size_t offset) {
+ uint64_t file_size;
+ get_inode_data_size(dir_inode, &file_size);
+ char *data = kmalloc(file_size);
+ read_inode(dir_inode, data, file_size, 0, NULL);
direntry_header_t *dir;
struct dirent tmp_entry;
size_t n_dir = 0;
int rc = 0;
- unsigned char *data_p = data;
- for (; (dir = (direntry_header_t *)data_p)->inode && len > 0;
+ char *data_p = data;
+ char *data_end = data + file_size;
+ for (; data_p <= (data_end - sizeof(direntry_header_t)) &&
+ (dir = (direntry_header_t *)data_p)->inode && len > 0;
data_p += dir->size, n_dir++) {
if (0 == dir->size)
break;
@@ -225,6 +232,7 @@ int ext2_read_dir(int dir_inode, unsigned char *buffer, size_t len,
len -= l;
rc += l;
}
+ kfree(data);
return rc;
}
@@ -361,8 +369,8 @@ int get_free_inode(int allocate) {
return -1;
}
-int write_inode(int inode_num, unsigned char *data, uint64_t size,
- uint64_t offset, uint64_t *file_size, int append) {
+int write_inode(int inode_num, char *data, uint64_t size, uint64_t offset,
+ uint64_t *file_size, int append) {
(void)file_size;
uint8_t inode_buffer[inode_size];
ext2_get_inode_header(inode_num, (inode_t *)inode_buffer);
@@ -415,8 +423,8 @@ int write_inode(int inode_num, unsigned char *data, uint64_t size,
return bytes_written;
}
-int read_inode(int inode_num, unsigned char *data, uint64_t size,
- uint64_t offset, uint64_t *file_size) {
+int read_inode(int inode_num, char *data, uint64_t size, uint64_t offset,
+ uint64_t *file_size) {
// TODO: Fail if size is lower than the size of the file being read, and
// return the size of the file the callers is trying to read.
uint8_t inode_buffer[inode_size];
@@ -460,15 +468,14 @@ int read_inode(int inode_num, unsigned char *data, uint64_t size,
return bytes_read;
}
-size_t ext2_read_file_offset(const char *file, unsigned char *data,
- uint64_t size, uint64_t offset,
- uint64_t *file_size) {
+size_t ext2_read_file_offset(const char *file, char *data, uint64_t size,
+ uint64_t offset, uint64_t *file_size) {
// TODO: Fail if the file does not exist.
uint32_t inode = ext2_find_inode(file);
return read_inode(inode, data, size, offset, file_size);
}
-size_t ext2_read_file(const char *file, unsigned char *data, size_t size,
+size_t ext2_read_file(const char *file, char *data, size_t size,
uint64_t *file_size) {
return ext2_read_file_offset(file, data, size, 0, file_size);
}
@@ -560,14 +567,13 @@ vfs_inode_t *ext2_open(const char *path) {
uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset,
direntry_header_t *meta) {
- // FIXME: Allocate sufficent size each time
- unsigned char data[block_byte_size * 5];
- uint64_t file_size = 0;
- read_inode(dir_inode, data, block_byte_size * 5, 0, &file_size);
- assert(block_byte_size * 5 > file_size);
+ uint64_t file_size;
+ get_inode_data_size(dir_inode, &file_size);
+ char *data = kmalloc(file_size);
+ read_inode(dir_inode, data, file_size, 0, NULL);
direntry_header_t *dir;
- unsigned char *data_p = data;
+ char *data_p = data;
uint64_t pos = 0;
uint64_t prev = pos;
for (; pos < file_size && (dir = (direntry_header_t *)data_p)->size;
@@ -577,6 +583,7 @@ uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset,
*entry_offset = prev;
if (meta)
memcpy(meta, ((char *)data) + prev, sizeof(direntry_header_t));
+ kfree(data);
return pos;
}
@@ -595,8 +602,8 @@ void ext2_create_entry(int directory_inode, direntry_header_t entry_header,
// Modify the entry to have its real size
meta.size = sizeof(direntry_header_t) + meta.name_length;
meta.size += (4 - (meta.size % 4));
- write_inode(directory_inode, (unsigned char *)&meta,
- sizeof(direntry_header_t), entry_offset, NULL, 0);
+ write_inode(directory_inode, (char *)&meta, sizeof(direntry_header_t),
+ entry_offset, NULL, 0);
// Create new entry
uint32_t new_entry_offset = entry_offset + meta.size;
@@ -613,7 +620,7 @@ void ext2_create_entry(int directory_inode, direntry_header_t entry_header,
memset(buffer, 0, entry_header.size);
memcpy(buffer, &entry_header, sizeof(entry_header));
memcpy(buffer + sizeof(entry_header), name, entry_header.name_length);
- write_inode(directory_inode, (unsigned char *)buffer, entry_header.size,
+ write_inode(directory_inode, (char *)buffer, entry_header.size,
new_entry_offset, NULL, 0);
}
diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h
index 3a2f800..4b4dec0 100644
--- a/kernel/fs/ext2.h
+++ b/kernel/fs/ext2.h
@@ -131,10 +131,9 @@ typedef struct DirectoryEntryHeader {
int ext2_create_file(const char *path, int mode);
vfs_inode_t *ext2_mount(void);
void parse_superblock(void);
-size_t ext2_read_file_offset(const char *file, unsigned char *data,
- uint64_t size, uint64_t offset,
- uint64_t *file_size);
-size_t ext2_read_file(const char *file, unsigned char *data, size_t size,
+size_t ext2_read_file_offset(const char *file, char *data, uint64_t size,
+ uint64_t offset, uint64_t *file_size);
+size_t ext2_read_file(const char *file, char *data, size_t size,
uint64_t *file_size);
int ext2_create_directory(const char *path, int mode);
#endif