From 8a9208612eec8ddae4c418485d848ecfa0613699 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 30 Oct 2023 22:12:14 +0100 Subject: Meta: Move kernel and userland to their own folders. This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear. --- fs/devfs.c | 91 -------- fs/devfs.h | 26 --- fs/ext2.c | 763 ------------------------------------------------------------- fs/ext2.h | 140 ------------ fs/fifo.c | 97 -------- fs/fifo.h | 27 --- fs/shm.c | 94 -------- fs/shm.h | 13 -- fs/tmpfs.c | 96 -------- fs/tmpfs.h | 16 -- fs/vfs.c | 318 -------------------------- fs/vfs.h | 100 -------- 12 files changed, 1781 deletions(-) delete mode 100644 fs/devfs.c delete mode 100644 fs/devfs.h delete mode 100644 fs/ext2.c delete mode 100644 fs/ext2.h delete mode 100644 fs/fifo.c delete mode 100644 fs/fifo.h delete mode 100644 fs/shm.c delete mode 100644 fs/shm.h delete mode 100644 fs/tmpfs.c delete mode 100644 fs/tmpfs.h delete mode 100644 fs/vfs.c delete mode 100644 fs/vfs.h (limited to 'fs') diff --git a/fs/devfs.c b/fs/devfs.c deleted file mode 100644 index 14748a7..0000000 --- a/fs/devfs.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include -#include - -devfs_file files[20]; -int num_files = 0; - -vfs_inode_t *devfs_add_file( - char *path, - int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - vfs_vm_object_t *(get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd), - uint8_t has_data, uint8_t can_write, int type) { - files[num_files].name = copy_and_allocate_string(path); - - vfs_inode_t *i = kmalloc(sizeof(vfs_inode_t)); - files[num_files].inode = i; - i->type = type; - i->read = read; - i->write = write; - i->close = NULL; - i->get_vm_object = get_vm_object; - i->has_data = has_data; - i->is_open = 1; - i->can_write = can_write; - num_files++; - return i; -} - -vfs_inode_t *devfs_open(const char *file) { - for (int i = 0; i < num_files; i++) - if (isequal_n(files[i].name, file, strlen(files[i].name))) - return files[i].inode; - - return 0; -} - -int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - return fd->inode->read(buffer, offset, len, fd); -} - -int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - return fd->inode->write(buffer, offset, len, fd); -} - -vfs_vm_object_t *devfs_get_vm_object(uint64_t length, uint64_t offset, - vfs_fd_t *fd) { - return fd->inode->get_vm_object(length, offset, fd); -} - -int stdout_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - (void)offset; - (void)fd; - - int rc = len; - for (; len--;) - putc(*buffer++); - return rc; -} - -int serial_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - (void)offset; - (void)fd; - - int rc = len; - for (; len--;) - write_serial(*buffer++); - return rc; -} - -void add_serial(void) { - devfs_add_file("/serial", NULL, serial_write, NULL, 0, 1, - FS_TYPE_CHAR_DEVICE); -} - -void add_stdout(void) { - devfs_add_file("/stdout", NULL, stdout_write, NULL, 0, 1, - FS_TYPE_CHAR_DEVICE); -} - -vfs_inode_t *devfs_mount(void) { - vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t)); - root->open = devfs_open; - root->read = devfs_read; - root->write = devfs_write; - root->close = NULL; - return root; -} diff --git a/fs/devfs.h b/fs/devfs.h deleted file mode 100644 index 23a499e..0000000 --- a/fs/devfs.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef DEVFS_H -#define DEVFS_H -#include -#include -#include - -typedef struct devfs_file { - char *name; - vfs_inode_t *inode; -} devfs_file; - -vfs_inode_t *devfs_mount(void); -vfs_inode_t *devfs_open(const char *file); -int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); -int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); -void add_stdout(void); -void add_serial(void); -vfs_inode_t *devfs_add_file( - char *path, - int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd), - uint8_t has_data, uint8_t can_write, int type); - -#endif diff --git a/fs/ext2.c b/fs/ext2.c deleted file mode 100644 index bd0fb07..0000000 --- a/fs/ext2.c +++ /dev/null @@ -1,763 +0,0 @@ -#include -#include -#include -#include -#include - -#define EXT2_SUPERBLOCK_SECTOR 2 -#define EXT2_ROOT_INODE 2 - -#define BLOCKS_REQUIRED(_a, _b) ((_a) / (_b) + (((_a) % (_b)) != 0)) - -superblock_t *superblock; -uint32_t block_byte_size; -uint32_t inode_size; -uint32_t inodes_per_block; - -#define BLOCK_SIZE (block_byte_size) - -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); - -struct BLOCK_CACHE { - uint32_t block_num; - uint8_t block[1024]; -}; - -#define NUM_BLOCK_CACHE 30 -struct BLOCK_CACHE cache[NUM_BLOCK_CACHE] = {0}; -uint8_t last_taken_cache = 0; - -void cached_read_block(uint32_t block, void *address, size_t size, - size_t offset) { - int free_found = -1; - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { - if (cache[i].block_num == block) { - memcpy(address, cache[i].block + offset, size); - return; - } - if (0 == cache[i].block_num) - free_found = i; - } - - if (-1 == free_found) { - free_found = last_taken_cache; - last_taken_cache++; - if (last_taken_cache >= NUM_BLOCK_CACHE) - last_taken_cache = 0; - } - - struct BLOCK_CACHE *c = &cache[free_found]; - c->block_num = block; - read_lba(block * block_byte_size / 512, c->block, 1024, 0); - return cached_read_block(block, address, size, offset); -} - -void ext2_read_block(uint32_t block, void *address, size_t size, - size_t offset) { - cached_read_block(block, address, size, offset); -} - -void ext2_write_block(uint32_t block, void *address, size_t size, - size_t offset) { - // Invalidate a old cache - for (int i = 0; i < NUM_BLOCK_CACHE; i++) { - if (cache[i].block_num == block) { - cache[i].block_num = 0; - break; - } - } - write_lba(block * block_byte_size / 512, address, size, offset); -} - -void write_group_descriptor(uint32_t group_index, bgdt_t *block_group) { - int starting_block = (1024 == block_byte_size) ? 2 : 1; - ext2_write_block(starting_block, block_group, sizeof(bgdt_t), - group_index * sizeof(bgdt_t)); -} - -void get_group_descriptor(uint32_t group_index, bgdt_t *block_group) { - int starting_block = (1024 == block_byte_size) ? 2 : 1; - ext2_read_block(starting_block, block_group, sizeof(bgdt_t), - group_index * sizeof(bgdt_t)); -} - -uint32_t num_block_groups(void) { - // Determining the Number of Block Groups - - // From the Superblock, extract the size of each block, the total - // number of inodes, the total number of blocks, the number of blocks - // per block group, and the number of inodes in each block group. From - // this information we can infer the number of block groups there are - // by: - - // Rounding up the total number of blocks divided by the number of - // blocks per block group - uint32_t num_blocks = superblock->num_blocks; - uint32_t num_blocks_in_group = superblock->num_blocks_in_group; - uint32_t b = num_blocks / num_blocks_in_group; - if (num_blocks % num_blocks_in_group != 0) - b++; - - // Rounding up the total number of inodes divided by the number of - // inodes per block group - uint32_t num_inodes = superblock->num_inodes; - uint32_t num_inodes_in_group = superblock->num_inodes_in_group; - uint32_t i = num_inodes / num_inodes_in_group; - if (num_inodes % num_inodes_in_group != 0) - i++; - // Both (and check them against each other) - assert(i == b); - return i; -} - -void ext2_block_containing_inode(uint32_t inode_index, uint32_t *block_index, - uint32_t *offset) { - assert(0 != inode_index); - bgdt_t block_group; - get_group_descriptor((inode_index - 1) / superblock->num_inodes_in_group, - &block_group); - - uint64_t full_offset = - ((inode_index - 1) % superblock->num_inodes_in_group) * inode_size; - *block_index = block_group.starting_inode_table + - (full_offset >> (superblock->block_size + 10)); - *offset = full_offset & (block_byte_size - 1); -} - -int ext2_last_inode_read = -1; -inode_t ext2_last_inode; - -void ext2_get_inode_header(int inode_index, inode_t *data) { - // Very simple cache. If the inode_index is a inode already read then - // just copy the old data. - if (ext2_last_inode_read == inode_index) { - memcpy(data, &ext2_last_inode, sizeof(inode_t)); - return; - } - uint32_t block_index; - uint32_t block_offset; - ext2_block_containing_inode(inode_index, &block_index, &block_offset); - - uint8_t mem_block[inode_size]; - ext2_read_block(block_index, mem_block, inode_size, block_offset); - - memcpy(data, mem_block, inode_size); - memcpy(&ext2_last_inode, mem_block, sizeof(inode_t)); - ext2_last_inode_read = inode_index; -} - -void ext2_write_inode(int inode_index, inode_t *data) { - if (ext2_last_inode_read == inode_index) - ext2_last_inode_read = -1; // Invalidate the cache - uint32_t block_index; - uint32_t block_offset; - ext2_block_containing_inode(inode_index, &block_index, &block_offset); - - uint8_t mem_block[inode_size]; - memcpy(mem_block, data, inode_size); - ext2_write_block(block_index, mem_block, inode_size, block_offset); -} - -int ext2_get_inode_in_directory(int dir_inode, char *file, - direntry_header_t *entry) { - // FIXME: Allocate sufficent size each time - unsigned char *data = kmalloc(block_byte_size * 5); - ASSERT_BUT_FIXME_PROPOGATE( - -1 != read_inode(dir_inode, data, block_byte_size * 5, 0, 0)); - - direntry_header_t *dir; - unsigned char *data_p = data; - for (; (dir = (direntry_header_t *)data_p)->inode; data_p += dir->size) { - if (0 == dir->size) - break; - if (0 == dir->name_length) - continue; - if (0 == - memcmp(data_p + sizeof(direntry_header_t), file, dir->name_length)) { - if (strlen(file) > dir->name_length) - continue; - if (entry) - memcpy(entry, data_p, sizeof(direntry_header_t)); - return dir->inode; - } - } - 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); - - 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; - data_p += dir->size, n_dir++) { - if (0 == dir->size) - break; - if (0 == dir->name_length) - continue; - if (n_dir < (offset / sizeof(struct dirent))) - continue; - - memcpy(tmp_entry.d_name, data_p + sizeof(direntry_header_t), - dir->name_length); - tmp_entry.d_name[dir->name_length] = '\0'; - uint8_t *p = (uint8_t *)&tmp_entry; - size_t l = sizeof(struct dirent); - - l = (len < l) ? len : l; - memcpy(buffer, p, l); - len -= l; - rc += l; - } - return rc; -} - -uint32_t ext2_find_inode(const char *file) { - int cur_path_inode = EXT2_ROOT_INODE; - - if (*file == '/' && *(file + 1) == '\0') - return cur_path_inode; - - char *str = copy_and_allocate_string(file); - char *orig_str = str; - - char *start; - for (;;) { - int final = 0; - start = str + 1; - str++; - - for (; '/' != *str && '\0' != *str; str++) - ; - if ('\0' == *str) - final = 1; - - *str = '\0'; - - direntry_header_t a; - if (0 == (cur_path_inode = - ext2_get_inode_in_directory(cur_path_inode, start, &a))) { - kfree(orig_str); - return 0; - } - - if (final) - break; - - // The expected returned entry is a directory - if (TYPE_INDICATOR_DIRECTORY != a.type_indicator) { - kfree(orig_str); - kprintf("FAILED\n"); - return 0; - } - } - kfree(orig_str); - return cur_path_inode; -} - -uint32_t get_singly_block_index(uint32_t singly_block_ptr, uint32_t i) { - uint8_t block[block_byte_size]; - ext2_read_block(singly_block_ptr, block, block_byte_size, 0); - uint32_t index = *(uint32_t *)(block + (i * (32 / 8))); - return index; -} - -int get_block(inode_t *inode, uint32_t i) { - if (i < 12) - return inode->block_pointers[i]; - - i -= 12; - uint32_t singly_block_size = block_byte_size / (32 / 8); - uint32_t double_block_size = (singly_block_size * singly_block_size); - if (i < singly_block_size) { - return get_singly_block_index(inode->single_indirect_block_pointer, i); - } else if (i < double_block_size) { - i -= singly_block_size; - uint32_t singly_entry = get_singly_block_index( - inode->double_indirect_block_pointer, i / singly_block_size); - uint32_t offset_in_entry = i % singly_block_size; - int block = get_singly_block_index(singly_entry, offset_in_entry); - return block; - } - assert(0); - return 0; -} - -int get_free_block(int allocate) { - bgdt_t block_group; - uint8_t bitmap[BLOCK_SIZE]; - assert(0 < superblock->num_blocks_unallocated); - for (uint32_t g = 0; g < num_block_groups(); g++) { - get_group_descriptor(g, &block_group); - - if (block_group.num_unallocated_blocks_in_group == 0) { - kprintf("skip\n"); - continue; - } - - ext2_read_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, 0); - for (uint32_t i = 0; i < superblock->num_blocks_in_group; i++) { - if (!(bitmap[i >> 3] & (1 << (i % 8)))) { - if (allocate) { - bitmap[i >> 3] |= (1 << (i % 8)); - ext2_write_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, - 0); - block_group.num_unallocated_blocks_in_group--; - write_group_descriptor(g, &block_group); - superblock->num_blocks_unallocated--; - write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, - 0); - } - return i + g * superblock->num_blocks_in_group + 1; - } - } - } - return -1; -} - -int get_free_inode(int allocate) { - bgdt_t block_group; - assert(0 < superblock->num_inodes_unallocated); - for (uint32_t g = 0; g < num_block_groups(); g++) { - get_group_descriptor(g, &block_group); - - if (0 == block_group.num_unallocated_inodes_in_group) - continue; - - uint8_t bitmap[BLOCK_SIZE]; - ext2_read_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, 0); - for (uint32_t i = 0; i < superblock->num_inodes_in_group; i++) { - if (!(bitmap[i / 8] & (1 << (i % 8)))) { - if (allocate) { - bitmap[i / 8] |= (1 << (i % 8)); - ext2_write_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, - 0); - block_group.num_unallocated_inodes_in_group--; - write_group_descriptor(g, &block_group); - superblock->num_inodes_unallocated--; - write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, - 0); - } - return i + g * superblock->num_inodes_in_group + 1; - } - } - } - return -1; -} - -int write_inode(int inode_num, unsigned 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); - inode_t *inode = (inode_t *)inode_buffer; - - uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | - (uint64_t)inode->low_32size); - if (append) - offset = fsize; - - uint32_t block_start = offset / block_byte_size; - uint32_t block_offset = offset % block_byte_size; - - int num_blocks_used = inode->num_disk_sectors / (BLOCK_SIZE / SECTOR_SIZE); - - if (size + offset > fsize) - fsize = size + offset; - - int num_blocks_required = BLOCKS_REQUIRED(fsize, BLOCK_SIZE); - - for (int i = num_blocks_used; i < num_blocks_required; i++) { - if (i > 12) - assert(0); - int b = get_free_block(1 /*true*/); - assert(-1 != b); - inode->block_pointers[i] = b; - } - - inode->num_disk_sectors = num_blocks_required * (BLOCK_SIZE / SECTOR_SIZE); - - int bytes_written = 0; - for (int i = block_start; size; i++) { - uint32_t block = get_block(inode, i); - if (0 == block) { - kprintf("block_not_found\n"); - break; - } - - int write_len = ((size + block_offset) > block_byte_size) - ? (block_byte_size - block_offset) - : size; - ext2_write_block(block, data + bytes_written, write_len, block_offset); - block_offset = 0; - bytes_written += write_len; - size -= write_len; - } - inode->low_32size = fsize; - inode->_upper_32size = (fsize >> 32); - ext2_write_inode(inode_num, inode); - return bytes_written; -} - -int read_inode(int inode_num, unsigned 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]; - ext2_get_inode_header(inode_num, (inode_t *)inode_buffer); - inode_t *inode = (inode_t *)inode_buffer; - - uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | - (uint64_t)inode->low_32size); - - if (file_size) - *file_size = fsize; - - if (size > fsize - offset) - size -= ((size + offset) - fsize); - - if (size == 0) - return 0; - - if (offset > fsize) - return 0; - - uint32_t block_start = offset / block_byte_size; - uint32_t block_offset = offset % block_byte_size; - - int bytes_read = 0; - for (int i = block_start; size; i++) { - uint32_t block = get_block(inode, i); - if (0 == block) { - klog("Filesystem EXT2: Unable to find block", LOG_WARN); - return -1; - } - - int read_len = ((size + block_offset) > block_byte_size) - ? (block_byte_size - block_offset) - : size; - ext2_read_block(block, data + bytes_read, read_len, block_offset); - block_offset = 0; - bytes_read += read_len; - size -= read_len; - } - 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) { - // 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, - uint64_t *file_size) { - return ext2_read_file_offset(file, data, size, 0, file_size); -} - -int resolve_link(int inode_num) { - uint8_t tmp[inode_size]; - inode_t *inode = (inode_t *)tmp; - uint64_t inode_size = - (((uint64_t)inode->_upper_32size) << 32) & inode->low_32size; - assert(inode_size <= 60); - ext2_get_inode_header(inode_num, inode); - char *path = (char *)(tmp + (10 * 4)); - path--; - *path = '/'; - return ext2_find_inode(path); -} - -int ext2_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - uint64_t file_size; - int rc; - int inode_num = fd->inode->inode_num; - assert(fd->inode->type != FS_TYPE_DIRECTORY); - if (fd->inode->type == FS_TYPE_LINK) { - inode_num = resolve_link(inode_num); - } - rc = write_inode(inode_num, buffer, len, offset, &file_size, 0); - return rc; -} - -int ext2_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - uint64_t file_size; - int rc; - int inode_num = fd->inode->inode_num; - if (fd->inode->type == FS_TYPE_DIRECTORY) { - rc = ext2_read_dir(inode_num, buffer, len, offset); - return rc; - } - if (fd->inode->type == FS_TYPE_LINK) { - inode_num = resolve_link(inode_num); - } - rc = read_inode(inode_num, buffer, len, offset, &file_size); - return rc; -} - -int ext2_truncate(vfs_fd_t *fd, size_t length) { - // TODO: Blocks that are no longer used should be freed. - char inode_buffer[inode_size]; - inode_t *ext2_inode = (inode_t *)inode_buffer; - - ext2_get_inode_header(fd->inode->inode_num, ext2_inode); - - // FIXME: ftruncate should support 64 bit lengths - ext2_inode->_upper_32size = 0; - ext2_inode->low_32size = length; - - ext2_write_inode(fd->inode->inode_num, ext2_inode); - return 0; -} - -vfs_inode_t *ext2_open(const char *path) { - uint32_t inode_num = ext2_find_inode(path); - if (0 == inode_num) - return NULL; - - inode_t ext2_inode[inode_size]; - ext2_get_inode_header(inode_num, ext2_inode); - uint64_t file_size = - ((uint64_t)(ext2_inode->_upper_32size) << 32) | ext2_inode->low_32size; - - uint8_t type; - switch ((ext2_inode->types_permissions / 0x1000)) { - case 0xA: - type = FS_TYPE_LINK; - break; - case 0x4: - type = FS_TYPE_DIRECTORY; - break; - default: - type = FS_TYPE_FILE; - break; - } - - return vfs_create_inode(inode_num, type, 1 /*has_data*/, 1 /*can_write*/, - 1 /*is_open*/, NULL /*internal_object*/, file_size, - ext2_open, ext2_create_file, ext2_read, ext2_write, - ext2_close, ext2_create_directory, - NULL /*get_vm_object*/, ext2_truncate /*truncate*/); -} - -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); - - direntry_header_t *dir; - unsigned char *data_p = data; - uint64_t pos = 0; - uint64_t prev = pos; - for (; pos < file_size && (dir = (direntry_header_t *)data_p)->size; - data_p += dir->size, prev = pos, pos += dir->size) - ; - if (entry_offset) - *entry_offset = prev; - if (meta) - memcpy(meta, ((char *)data) + prev, sizeof(direntry_header_t)); - return pos; -} - -void ext2_create_entry(int directory_inode, direntry_header_t entry_header, - const char *name) { - uint64_t entry_offset = 0; - direntry_header_t meta; - end_of_last_entry_position(directory_inode, &entry_offset, &meta); - - uint32_t padding_in_use = block_byte_size - entry_offset; - - // assert(padding_in_use == meta.size); - assert(padding_in_use >= - (sizeof(direntry_header_t) + entry_header.name_length)); - - // 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); - - // Create new entry - uint32_t new_entry_offset = entry_offset + meta.size; - entry_header.size = (sizeof(direntry_header_t) + entry_header.name_length); - entry_header.size += (4 - (entry_header.size % 4)); - - uint32_t length_till_next_block = 1024 - (new_entry_offset % 1024); - if (0 == length_till_next_block) - length_till_next_block = 1024; - assert(entry_header.size < length_till_next_block); - entry_header.size = length_till_next_block; - - uint8_t buffer[entry_header.size]; - 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, - new_entry_offset, NULL, 0); -} - -int ext2_find_parent(char *path, uint32_t *parent_inode, char **filename) { - char *e = path; - for (; *e; e++) - ; - for (; *e != '/'; e--) - ; - *e = '\0'; - *filename = e + 1; - if (*path == '\0') { - *parent_inode = EXT2_ROOT_INODE; - return 1; - } else { - int r = ext2_find_inode(path); - if (0 == r) - return 0; - *parent_inode = r; - return 1; - } - return 0; -} - -int ext2_create_directory(const char *path, int mode) { - (void)mode; - // Check if the directory already exists - uint32_t inode_num = ext2_find_inode(path); - if (0 != inode_num) { - klog("ext2_create_directory: Directory already exists", LOG_WARN); - return inode_num; - } - - uint32_t parent_inode; - // Get the parent directory - char path_buffer[strlen(path) + 1]; - char *filename; - strcpy(path_buffer, path); - if (!ext2_find_parent(path_buffer, &parent_inode, &filename)) { - klog("ext2_create_file: Parent does not exist", LOG_WARN); - return -1; - } - - int new_file_inode = get_free_inode(1); - if (-1 == new_file_inode) { - klog("ext2_create_file: Unable to find free inode", LOG_WARN); - return -1; - } - assert(0 != new_file_inode); - - direntry_header_t entry_header; - entry_header.inode = new_file_inode; - entry_header.name_length = strlen(filename); - entry_header.type_indicator = TYPE_INDICATOR_DIRECTORY; - entry_header.size = sizeof(entry_header) + entry_header.name_length; - - ext2_create_entry(parent_inode, entry_header, filename); - // Create the inode header - uint8_t inode_buffer[inode_size]; - inode_t *new_inode = (inode_t *)inode_buffer; - memset(inode_buffer, 0, inode_size); - new_inode->types_permissions = DIRECTORY; - new_inode->num_hard_links = 2; // 2 since the directory references - // itself with the "." entry - ext2_write_inode(new_file_inode, new_inode); - - // Populate the new directory with "." and ".." - { - // "." - direntry_header_t child_entry_header; - child_entry_header.inode = new_file_inode; - child_entry_header.name_length = 1; - child_entry_header.type_indicator = TYPE_INDICATOR_DIRECTORY; - child_entry_header.size = sizeof(entry_header) + entry_header.name_length; - ext2_create_entry(new_file_inode, child_entry_header, "."); - // ".." - child_entry_header.inode = parent_inode; - child_entry_header.name_length = 2; - child_entry_header.type_indicator = TYPE_INDICATOR_DIRECTORY; - child_entry_header.size = sizeof(entry_header) + entry_header.name_length; - ext2_create_entry(new_file_inode, child_entry_header, ".."); - } - return new_file_inode; -} - -int ext2_create_file(const char *path, int mode) { - // Check if the file already exists - uint32_t inode_num = ext2_find_inode(path); - if (0 != inode_num) { - klog("ext2_create_file: File already exists", LOG_WARN); - return inode_num; - } - - uint32_t parent_inode; - // Get the parent directory - char path_buffer[strlen(path) + 1]; - char *filename; - strcpy(path_buffer, path); - if (!ext2_find_parent(path_buffer, &parent_inode, &filename)) { - klog("ext2_create_file: Parent does not exist", LOG_WARN); - return -1; - } - - int new_file_inode = get_free_inode(1); - if (-1 == new_file_inode) { - klog("ext2_create_file: Unable to find free inode", LOG_WARN); - return -1; - } - assert(0 != new_file_inode); - - direntry_header_t entry_header; - entry_header.inode = new_file_inode; - entry_header.name_length = strlen(filename); - entry_header.type_indicator = TYPE_INDICATOR_REGULAR; - entry_header.size = sizeof(entry_header) + entry_header.name_length; - - ext2_create_entry(parent_inode, entry_header, filename); - // Create the inode header - uint8_t inode_buffer[inode_size]; - inode_t *new_inode = (inode_t *)inode_buffer; - memset(inode_buffer, 0, inode_size); - new_inode->types_permissions = 0x8000; - new_inode->num_hard_links = 1; - ext2_write_inode(new_file_inode, new_inode); - return new_file_inode; -} - -vfs_inode_t *ext2_mount(void) { - parse_superblock(); - return vfs_create_inode(0 /*inode_num*/, 0 /*type*/, 0 /*has_data*/, - 0 /*can_write*/, 0 /*is_open*/, - NULL /*internal_object*/, 0 /*file_size*/, ext2_open, - ext2_create_file, ext2_read, ext2_write, ext2_close, - ext2_create_directory, NULL /*get_vm_object*/, - ext2_truncate /*truncate*/); -} - -void parse_superblock(void) { - superblock = ksbrk(2 * SECTOR_SIZE); - read_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, 0); - block_byte_size = 1024 << superblock->block_size; - - if (0xEF53 != superblock->ext2_signature) { - klog("Incorrect ext2 signature in superblock.", LOG_ERROR); - for (;;) - ; // TODO: Fail properly - } - - if (1 <= superblock->major_version) - inode_size = ((ext_superblock_t *)superblock)->inode_size; - - inodes_per_block = block_byte_size / inode_size; -} diff --git a/fs/ext2.h b/fs/ext2.h deleted file mode 100644 index 3a2f800..0000000 --- a/fs/ext2.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef EXT2_H -#define EXT2_H -#include -#include -#include -#include - -typedef struct Superblock { - uint32_t num_inodes; - uint32_t num_blocks; - uint32_t num_blocks_reserved; - uint32_t num_blocks_unallocated; - uint32_t num_inodes_unallocated; - uint32_t superblock_block_num; - uint32_t block_size; - uint32_t fragment_size; - uint32_t num_blocks_in_group; - uint32_t num_fragments_in_group; - uint32_t num_inodes_in_group; - uint32_t last_mount; - uint32_t last_write; - uint16_t num_mounts_since_fsck; - uint16_t num_mounts_allowed; - uint16_t ext2_signature; // 0xEF53 - uint16_t fs_state; - uint16_t when_error; - uint16_t minor_version; - uint32_t last_fsck; - uint32_t interval_fsck; - uint32_t os_id; - uint32_t major_version; - uint16_t userid_reserved_blocks; - uint16_t groupid_reserved_blocks; -} __attribute__((packed)) superblock_t; - -typedef struct ExtendedSuperblock { - uint32_t num_inodes; - uint32_t num_blocks; - uint32_t num_blocks_reserved; - uint32_t num_blocks_unallocated; - uint32_t num_inodes_unallocated; - uint32_t superblock_block_num; - uint32_t block_size; - uint32_t fragment_size; - uint32_t num_blocks_group; - uint32_t num_fragments_group; - uint32_t num_inodes_group; - uint32_t last_mount; - uint32_t last_write; - uint16_t num_mounts_since_fsck; - uint16_t num_mounts_allowed; - uint16_t ext2_signature; // 0xEF53 - uint16_t fs_state; - uint16_t when_error; - uint16_t minor_version; - uint32_t last_fsck; - uint32_t interval_fsck; - uint32_t os_id; - uint32_t major_version; - uint16_t userid_reserved_blocks; - uint16_t groupid_reserved_blocks; - uint32_t pad; - uint16_t inode_size; -} __attribute__((packed)) ext_superblock_t; - -typedef struct BlockGroupDescriptorTable { - uint32_t block_usage_bitmap; - uint32_t inode_usage_bitmap; - uint32_t starting_inode_table; - uint16_t num_unallocated_blocks_in_group; - uint16_t num_unallocated_inodes_in_group; - uint16_t num_directories_group; -} __attribute__((packed)) bgdt_t; - -typedef struct INode { - uint16_t types_permissions; - uint16_t user_id; - uint32_t low_32size; - uint32_t last_access_time; - uint32_t creation_time; - uint32_t last_modification_time; - uint32_t deletion_time; - uint16_t group_id; - uint16_t num_hard_links; - uint32_t num_disk_sectors; - uint32_t flags; - uint32_t os_specific; - uint32_t block_pointers[12]; - uint32_t single_indirect_block_pointer; - uint32_t double_indirect_block_pointer; - uint32_t triple_indirect_block_pointer; - uint32_t gen_number; - uint32_t _extended_attribute_block; - uint32_t _upper_32size; - uint32_t address_fragment; - uint32_t os_specific2; -} __attribute__((packed)) inode_t; - -// 0 Unknown type -// 1 Regular file -// 2 Directory -// 3 Character device -// 4 Block device -// 5 FIFO -// 6 Socket -// 7 Symbolic link (soft link) -#define TYPE_INDICATOR_UNKOWN 0 -#define TYPE_INDICATOR_REGULAR 1 -#define TYPE_INDICATOR_DIRECTORY 2 -#define TYPE_INDICATOR_CHARACTER_DEVICE 3 -#define TYPE_INDICATOR_BLOCK_DEVICE 4 -#define TYPE_INDICATOR_FIFO 5 -#define TYPE_INDICATOR_SOCKET 6 -#define TYPE_INDICATOR_SOFT_LINK 7 - -#define FIFO 0x1000 -#define CHARACTER_DEVICE 0x2000 -#define DIRECTORY 0x4000 -#define BLOCK_DEVICE 0x6000 -#define REGULAR_FILE 0x8000 -#define SYMBOLIC_LINK 0xA000 -#define UNIX_SOCKET 0xC000 - -typedef struct DirectoryEntryHeader { - uint32_t inode; - uint16_t size; - uint8_t name_length; - uint8_t type_indicator; -} __attribute__((packed)) direntry_header_t; - -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, - uint64_t *file_size); -int ext2_create_directory(const char *path, int mode); -#endif diff --git a/fs/fifo.c b/fs/fifo.c deleted file mode 100644 index d515ed7..0000000 --- a/fs/fifo.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "fifo.h" -#include - -#define STARTING_SIZE 4096 - -void fifo_close(vfs_fd_t *fd) { - // TODO: Implement - (void)fd; - return; -} - -int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, - FIFO_FILE *file) { - (void)offset; - file->has_data = 1; - if (file->write_len + len >= file->buffer_len) { - file->can_write = 0; - return -EAGAIN; - } - memcpy(file->buffer + file->write_len, buffer, len); - file->write_len += len; - return len; -} - -int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, - FIFO_FILE *file) { - (void)offset; - if (file->write_len == 0) { - file->has_data = 0; - return -EAGAIN; - } - - if (len == 0) - return 0; - - file->can_write = 1; - if (len > file->write_len) - len = file->write_len; - - memcpy(buffer, file->buffer, len); - // Shift bufffer to the left - memcpy(file->buffer, file->buffer + len, file->buffer_len - len); - - file->write_len -= len; - if (file->write_len == 0) { - file->has_data = 0; - } - return len; -} - -FIFO_FILE *create_fifo_object(void) { - FIFO_FILE *n = kmalloc(sizeof(FIFO_FILE)); - n->buffer = kmalloc(STARTING_SIZE); - n->buffer_len = STARTING_SIZE; - n->write_len = 0; - return n; -} - -int create_fifo(void) { - - int fd_n = 0; - for (; get_current_task()->file_descriptors[fd_n]; fd_n++) - ; - - vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t)); - fd->flags = O_RDWR | O_NONBLOCK; - get_current_task()->file_descriptors[fd_n] = fd; - fd->inode = kmalloc(sizeof(vfs_inode_t)); - - fd->inode->internal_object = (void *)create_fifo_object(); - fd->inode->open = NULL; - fd->inode->read = fifo_read; - fd->inode->write = fifo_write; - fd->inode->close = fifo_close; - fd->inode->get_vm_object = NULL; - fd->inode->is_open = 1; - - return fd_n; -} - -int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - (void)offset; - FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; - int rc = fifo_object_write(buffer, offset, len, file); - fd->inode->has_data = file->has_data; - fd->inode->can_write = file->can_write; - return rc; -} - -int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; - file->is_blocking = !(fd->flags & O_NONBLOCK); - int rc = fifo_object_read(buffer, offset, len, file); - fd->inode->has_data = file->has_data; - fd->inode->can_write = file->can_write; - return rc; -} diff --git a/fs/fifo.h b/fs/fifo.h deleted file mode 100644 index 1ba7168..0000000 --- a/fs/fifo.h +++ /dev/null @@ -1,27 +0,0 @@ -typedef struct S_FIFO_FILE FIFO_FILE; -#ifndef FIFO_H -#define FIFO_H -#include "vfs.h" -#include -#include - -struct S_FIFO_FILE { - char *buffer; - uint64_t buffer_len; - uint64_t write_len; - uint8_t is_blocking; - uint8_t has_data; - uint8_t can_write; -}; - -int create_fifo(void); -FIFO_FILE *create_fifo_object(void); -int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, - FIFO_FILE *file); -int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, - FIFO_FILE *file); -int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, - vfs_fd_t *fd); -int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, - vfs_fd_t *fd); -#endif diff --git a/fs/shm.c b/fs/shm.c deleted file mode 100644 index 4d5f2ab..0000000 --- a/fs/shm.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -HashMap *shared_memory_objects; - -void shm_init(void) { shared_memory_objects = hashmap_create(10); } - -int shm_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - vfs_vm_object_t *p = fd->inode->internal_object; - - if (offset > p->size) - return -EFBIG; - - if (offset + len > p->size) - len = p->size - offset; - - memcpy((void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), buffer, - len); - return len; -} - -int shm_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - vfs_vm_object_t *p = fd->inode->internal_object; - - if (offset > p->size) - return -EFBIG; - - if (offset + len > p->size) - len = p->size - offset; - - memcpy((void *)buffer, - (void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), len); - return len; -} - -vfs_vm_object_t *shm_get_vm_object(uint64_t length, uint64_t offset, - vfs_fd_t *fd) { - (void)length; - (void)offset; - vfs_vm_object_t *p = fd->inode->internal_object; - return p; -} - -int shm_ftruncate(vfs_fd_t *fd, size_t length) { - vfs_vm_object_t *p = fd->inode->internal_object; - p->size = length; - p->virtual_object = ksbrk(length); - int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000; - p->object = kmalloc(sizeof(void *) * n); - for (int i = 0; i < n; i++) - p->object[i] = - (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame * - 0x1000); - return 0; -} - -int shm_open(const char *name, int oflag, mode_t mode) { - // Try to find or create a new shared memory object. - vfs_vm_object_t *internal_object = - hashmap_get_entry(shared_memory_objects, name); - if (!internal_object) { - // if (!(oflag & O_CREAT)) - // return -EMFILE; - internal_object = kmalloc(sizeof(vfs_vm_object_t)); - internal_object->object = NULL; - internal_object->size = 0; - hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0); - } - - vfs_inode_t *inode = vfs_create_inode( - 0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, 1 /*can_write*/, - 1 /*is_open*/, internal_object, 0 /*file_size*/, NULL /*open*/, - NULL /*create_file*/, shm_read, shm_write, NULL /*close*/, - NULL /*create_directory*/, shm_get_vm_object, shm_ftruncate); - - vfs_fd_t *fd_ptr; - int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr); - if (-1 == fd) { - kfree(inode); - return -EMFILE; - } - return fd; -} - -int shm_unlink(const char *name) { - (void)name; - return 0; -} diff --git a/fs/shm.h b/fs/shm.h deleted file mode 100644 index fbbdb5c..0000000 --- a/fs/shm.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SHM_H -#define SHM_H -#include -#include - -typedef int mode_t; - -void shm_init(void); -int shm_open(const char *name, int oflag, mode_t mode); -int shm_unlink(const char *name); -int ftruncate(int fildes, uint64_t length); - -#endif diff --git a/fs/tmpfs.c b/fs/tmpfs.c deleted file mode 100644 index a9a3c1f..0000000 --- a/fs/tmpfs.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -void tmp_close(vfs_fd_t *fd) { - fd->inode->is_open = 0; - ((tmp_inode *)fd->inode->internal_object)->read_inode->is_open = 0; -} - -int tmp_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - tmp_inode *calling_file = fd->inode->internal_object; - tmp_inode *child_file = calling_file->read_inode->internal_object; - if (child_file->is_closed) - return -EPIPE; - - int rc = fifo_object_write(buffer, offset, len, child_file->fifo); - calling_file->read_inode->has_data = child_file->fifo->has_data; - fd->inode->can_write = child_file->fifo->can_write; - return rc; -} - -int tmp_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { - tmp_inode *calling_file = fd->inode->internal_object; - tmp_inode *child_file = calling_file->read_inode->internal_object; - if (calling_file->is_closed) - return -EPIPE; - - int rc = fifo_object_read(buffer, offset, len, calling_file->fifo); - fd->inode->has_data = calling_file->fifo->has_data; - calling_file->read_inode->can_write = child_file->fifo->can_write; - return rc; -} - -void dual_pipe(int fd[2]) { - for (int i = 0; i < 2; i++) { - tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); - pipe->fifo = create_fifo_object(); - - int has_data = 0; - int can_write = 1; - int is_open = 1; - void *internal_object = pipe; - vfs_inode_t *inode = vfs_create_inode( - 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, - internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, - tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, - NULL /*get_vm_object*/, NULL /*truncate*/); - assert(inode); - - vfs_fd_t *fd_ptr; - fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd_ptr); - assert(-1 != fd[i]); - } - vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; - vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; - tmp_inode *f_pipe = f_inode->internal_object; - tmp_inode *s_pipe = s_inode->internal_object; - f_pipe->read_inode = s_inode; - s_pipe->read_inode = f_inode; - f_pipe->is_closed = 0; - s_pipe->is_closed = 0; -} - -void pipe(int fd[2]) { - for (int i = 0; i < 2; i++) { - tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); - pipe->fifo = create_fifo_object(); - - int has_data = 0; - int can_write = 1; - int is_open = 1; - void *internal_object = pipe; - vfs_inode_t *inode = vfs_create_inode( - 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, - internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, - tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, - NULL /*get_vm_object*/, NULL/*truncate*/); - assert(inode); - - vfs_fd_t *fd_ptr; - fd[i] = vfs_create_fd(O_RDWR, 0, inode, &fd_ptr); - assert(-1 != fd[i]); - } - vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; - vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; - tmp_inode *f_pipe = f_inode->internal_object; - tmp_inode *s_pipe = s_inode->internal_object; - f_pipe->read_inode = s_inode; - s_pipe->read_inode = f_inode; - f_pipe->is_closed = 0; - s_pipe->is_closed = 0; -} diff --git a/fs/tmpfs.h b/fs/tmpfs.h deleted file mode 100644 index 4052bd5..0000000 --- a/fs/tmpfs.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef TMP_H -#define TMP_H -#include -#include - -#define TMP_BUFFER_SIZE (1024 * 10) - -typedef struct { - FIFO_FILE *fifo; - uint8_t is_closed; - vfs_inode_t *read_inode; -} tmp_inode; - -void pipe(int fd[2]); -void dual_pipe(int fd[2]); -#endif diff --git a/fs/vfs.c b/fs/vfs.c deleted file mode 100644 index 0c616a2..0000000 --- a/fs/vfs.c +++ /dev/null @@ -1,318 +0,0 @@ -#include -#include -#include -#include -#include - -vfs_inode_t *root_dir; -vfs_mounts_t mounts[10]; -int num_mounts = 0; - -vfs_fd_t *get_vfs_fd(int fd) { - if (fd >= 100) { - klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); - dump_backtrace(12); - return NULL; - } - if (fd < 0) { - klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); - dump_backtrace(12); - return NULL; - } - return get_current_task()->file_descriptors[fd]; -} - -vfs_inode_t *vfs_create_inode( - int inode_num, int type, uint8_t has_data, uint8_t can_write, - uint8_t is_open, void *internal_object, uint64_t file_size, - vfs_inode_t *(*open)(const char *path), - int (*create_file)(const char *path, int mode), - int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - void (*close)(vfs_fd_t *fd), - int (*create_directory)(const char *path, int mode), - vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd), - int (*truncate)(vfs_fd_t *fd, size_t length)) { - vfs_inode_t *r = kmalloc(sizeof(inode_t)); - r->inode_num = inode_num; - r->type = type; - r->has_data = has_data; - r->can_write = can_write; - r->is_open = is_open; - r->internal_object = internal_object; - r->file_size = file_size; - r->open = open; - r->create_file = create_file; - r->read = read; - r->write = write; - r->close = close; - r->create_directory = create_directory; - r->get_vm_object = get_vm_object; - r->truncate = truncate; - return r; -} - -int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd) { - process_t *p = (process_t *)get_current_task(); - int i; - for (i = 0; i < 100; i++) - if (!p->file_descriptors[i]) - break; - if (p->file_descriptors[i]) - return -1; - vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t)); - r->flags = flags; - r->mode = mode; - r->inode = inode; - r->reference_count = 1; - p->file_descriptors[i] = r; - if (fd) - *fd = r; - return i; -} - -int vfs_create_file(const char *file) { - vfs_mounts_t *file_mount = 0; - int length = 0; - for (int i = 0; i < num_mounts; i++) { - int path_len = strlen(mounts[i].path); - if (path_len <= length) - continue; - - if (isequal_n(mounts[i].path, file, path_len)) { - length = path_len; - file_mount = &mounts[i]; - } - } - if (1 != length) - file += length; - - if (!file_mount) { - kprintf("vfs_internal_open could not find mounted path for file : %s\n", - file); - return 0; - } - // ext2_create_file("/etc/oscreated", 0); - assert(file_mount->local_root->create_file); - kprintf("Creating a file\n"); - return file_mount->local_root->create_file(file, 0); -} - -vfs_inode_t *vfs_internal_open(const char *file) { - vfs_mounts_t *file_mount = 0; - int length = 0; - for (int i = 0; i < num_mounts; i++) { - int path_len = strlen(mounts[i].path); - if (path_len <= length) - continue; - - if (isequal_n(mounts[i].path, file, path_len)) { - length = path_len; - file_mount = &mounts[i]; - } - } - if (1 != length) - file += length; - - if (!file_mount) { - kprintf("vfs_internal_open could not find mounted path for file : %s\n", - file); - return NULL; - } - - vfs_inode_t *ret = file_mount->local_root->open(file); - return ret; -} - -char *vfs_clean_path(const char *path, char *resolved_path) { - // char *const clean = kmalloc(strlen(path) + 1); - char *clean = resolved_path; - int prev_slash = 0; - char *ptr = clean; - for (; *path; path++) { - if (prev_slash && '/' == *path) { - continue; - } - prev_slash = ('/' == *path); - *ptr = *path; - ptr++; - } - *ptr = '\0'; - return clean; -} - -char *vfs_resolve_path(const char *file, char *resolved_path) { - if ('/' == *file) { - return vfs_clean_path(file, resolved_path); - } - const char *cwd = get_current_task()->current_working_directory; - size_t l = strlen(cwd); - assert(l > 0); - assert('/' == cwd[l - 1]); - // char *r = kmalloc(l + strlen(file) + 1); - char r[256]; - strcpy(r, cwd); - strcat(r, file); - char *final = vfs_clean_path(r, resolved_path); - // kfree(r); - return final; -} - -int vfs_mkdir(const char *path, int mode) { - vfs_mounts_t *file_mount = 0; - int length = 0; - for (int i = 0; i < num_mounts; i++) { - int path_len = strlen(mounts[i].path); - if (path_len <= length) - continue; - - if (isequal_n(mounts[i].path, path, path_len)) { - length = path_len; - file_mount = &mounts[i]; - } - } - if (1 != length) - path += length; - - if (!file_mount) { - kprintf("vfs_internal_open could not find mounted path for file : %s\n", - path); - return 0; - } - assert(file_mount->local_root->create_directory); - // TODO: Error checking, don't just assume it is fine - file_mount->local_root->create_directory(path, mode); - return 0; -} - -int vfs_open(const char *file, int flags, int mode) { - char resolved_path[256] = {0}; - vfs_resolve_path(file, resolved_path); - vfs_inode_t *inode = vfs_internal_open(resolved_path); - if (0 == inode) { - if (mode & O_CREAT) { - if (vfs_create_file(resolved_path)) { - klog("VFS: File created", LOG_NOTE); - return vfs_open(file, flags, mode); - } - klog("VFS: Could not create file", LOG_WARN); - } - return -ENOENT; - } - if (inode->type == FS_TYPE_UNIX_SOCKET) { - return uds_open(resolved_path); - } - - return vfs_create_fd(flags, mode, inode, NULL); -} - -int vfs_close(int fd) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); - if (NULL == fd_ptr) { - return -1; - } - assert(0 < fd_ptr->reference_count); - // Remove process reference - fd_ptr->reference_count--; - get_current_task()->file_descriptors[fd] = 0; - // If no references left then free the contents - if (0 == fd_ptr->reference_count) { - if (fd_ptr->inode->close) - fd_ptr->inode->close(fd_ptr); - - kfree(fd_ptr); - } - return 0; -} - -int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, uint64_t count, - uint64_t offset) { - if (!(vfs_fd->flags & O_READ)) - return -EBADF; - return vfs_fd->inode->read(buf, offset, count, vfs_fd); -} - -int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset) { - if (fd >= 100) { - kprintf("EBADF : %x\n", fd); - return -EBADF; - } - if (fd < 0) { - dump_backtrace(12); - kprintf("EBADF : %x\n", fd); - return -EBADF; - } - vfs_fd_t *vfs_fd = get_current_task()->file_descriptors[fd]; - if (!vfs_fd) - return -EBADF; - int rc = raw_vfs_pread(vfs_fd, buf, count, offset); - if (-EAGAIN == rc && count > 0) { - if (!(vfs_fd->flags & O_NONBLOCK)) { - struct pollfd fds; - fds.fd = fd; - fds.events = POLLIN; - fds.revents = 0; - poll(&fds, 1, 0); - return vfs_pread(fd, buf, count, offset); - } - } - return rc; -} - -int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, - uint64_t offset) { - assert(vfs_fd); - assert(vfs_fd->inode); - assert(vfs_fd->inode->write); - return vfs_fd->inode->write(buf, offset, count, vfs_fd); -} - -int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset) { - vfs_fd_t *vfs_fd = get_vfs_fd(fd); - if (!vfs_fd) - return -EBADF; - if (!(vfs_fd->flags & O_WRITE)) { - return -EBADF; - } - return raw_vfs_pwrite(vfs_fd, buf, count, offset); -} - -vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset) { - vfs_fd_t *vfs_fd = get_vfs_fd(fd); - if (!vfs_fd) - return NULL; - vfs_vm_object_t *r = vfs_fd->inode->get_vm_object(length, offset, vfs_fd); - return r; -} - -int vfs_dup2(int org_fd, int new_fd) { - get_current_task()->file_descriptors[new_fd] = - get_current_task()->file_descriptors[org_fd]; - get_current_task()->file_descriptors[new_fd]->reference_count++; - return 1; -} - -int vfs_ftruncate(int fd, size_t length) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); - if (!fd_ptr) - return -EBADF; - if (!(fd_ptr->flags & O_READ)) - return -EINVAL; - vfs_inode_t *inode = fd_ptr->inode; - if (!inode) - return -EINVAL; - if (!inode->truncate) - return -EINVAL; - - return inode->truncate(fd_ptr, length); -} - -void vfs_mount(char *path, vfs_inode_t *local_root) { - int len = strlen(path); - mounts[num_mounts].path = kmalloc_eternal(len + 1); - memcpy(mounts[num_mounts].path, path, len); - mounts[num_mounts].path[len] = '\0'; - mounts[num_mounts].local_root = local_root; - num_mounts++; -} diff --git a/fs/vfs.h b/fs/vfs.h deleted file mode 100644 index f8a4b19..0000000 --- a/fs/vfs.h +++ /dev/null @@ -1,100 +0,0 @@ -typedef struct vfs_fd vfs_fd_t; -typedef struct vfs_inode vfs_inode_t; -typedef struct vfs_vm_object vfs_vm_object_t; -typedef struct vfs_mounts vfs_mounts_t; -#ifndef VFS_H -#define VFS_H -#include -#include -#include -#include -#include - -// FIXME: Is there some standard value for this? -#define O_NONBLOCK (1 << 0) -#define O_READ (1 << 1) -#define O_WRITE (1 << 2) -#define O_CREAT (1 << 3) -#define O_RDONLY O_READ -#define O_WRONLY O_WRITE -#define O_RDWR (O_WRITE | O_READ) - -#define FS_TYPE_FILE 0 -#define FS_TYPE_UNIX_SOCKET 1 -#define FS_TYPE_CHAR_DEVICE 2 -#define FS_TYPE_BLOCK_DEVICE 3 -#define FS_TYPE_DIRECTORY 4 -#define FS_TYPE_LINK 7 - -struct vfs_vm_object { - void *virtual_object; - void **object; - uint64_t size; -}; - -struct vfs_mounts { - char *path; - vfs_inode_t *local_root; -}; - -struct dirent { - unsigned int d_ino; // File serial number. - char d_name[PATH_MAX]; // Filename string of entry. -}; - -struct vfs_fd { - size_t offset; - int flags; - int mode; - int reference_count; // Number of usages of this file descriptor, - // once it reaches zero then the contents can - // be freed. - vfs_inode_t *inode; -}; - -struct vfs_inode { - int inode_num; - int type; - uint8_t has_data; - uint8_t can_write; - uint8_t is_open; - void *internal_object; - uint64_t file_size; - vfs_inode_t *(*open)(const char *path); - int (*create_file)(const char *path, int mode); - int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); - int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); - void (*close)(vfs_fd_t *fd); - int (*create_directory)(const char *path, int mode); - vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd); - int (*truncate)(vfs_fd_t *fd, size_t length); -}; - -int vfs_close(int fd); -vfs_fd_t *get_vfs_fd(int fd); -int vfs_open(const char *file, int flags, int mode); -void vfs_mount(char *path, vfs_inode_t *local_root); -int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset); -int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, - uint64_t offset); -int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset); -vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset); -int vfs_dup2(int org_fd, int new_fd); -vfs_inode_t *vfs_internal_open(const char *file); -int vfs_mkdir(const char *path, int mode); -int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd); -int vfs_ftruncate(int fd, size_t length); -vfs_inode_t *vfs_create_inode( - int inode_num, int type, uint8_t has_data, uint8_t can_write, - uint8_t is_open, void *internal_object, uint64_t file_size, - vfs_inode_t *(*open)(const char *path), - int (*create_file)(const char *path, int mode), - int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), - void (*close)(vfs_fd_t *fd), - int (*create_directory)(const char *path, int mode), - vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd), - int (*truncate)(vfs_fd_t *fd, size_t length)); -#endif -- cgit v1.2.3