diff options
author | Ian McFarlane <i.mcfarlane2002@gmail.com> | 2025-05-06 15:14:11 -0400 |
---|---|---|
committer | Ian McFarlane <i.mcfarlane2002@gmail.com> | 2025-05-06 15:14:11 -0400 |
commit | da396afa8b612b8f8ff07d71c57761a627b158eb (patch) | |
tree | b4935b29aca686c6ee17a583cffe149d7bb3c819 /kernel/fs | |
parent | update forkman with spinlock (diff) | |
parent | start docs (diff) | |
download | comus-da396afa8b612b8f8ff07d71c57761a627b158eb.tar.gz comus-da396afa8b612b8f8ff07d71c57761a627b158eb.tar.bz2 comus-da396afa8b612b8f8ff07d71c57761a627b158eb.zip |
merge main into forkmanforkman
Diffstat (limited to 'kernel/fs')
-rw-r--r-- | kernel/fs/fs.c | 21 | ||||
-rw-r--r-- | kernel/fs/ramfs.c | 171 | ||||
-rw-r--r-- | kernel/fs/tar.c | 306 |
3 files changed, 491 insertions, 7 deletions
diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c index a887ca4..ef031f2 100644 --- a/kernel/fs/fs.c +++ b/kernel/fs/fs.c @@ -1,5 +1,6 @@ #include <lib.h> #include <comus/fs.h> +#include <comus/fs/tar.h> #include <comus/mboot.h> #include <comus/error.h> @@ -50,9 +51,9 @@ static void load_fs(struct disk *disk) fs->fs_id = disk->d_id; fs->fs_present = 1; - // // try examplefs - // if (example_mount(fs) == SUCCESS) - // return; + // try tarfs + if (tar_mount(fs) == SUCCESS) + return; fs->fs_present = 0; WARN("failed to load fs on disk %u", disk->d_id); @@ -122,13 +123,16 @@ int fs_find_file_rel(struct file *rel, char *rel_path, struct file *res) static int disk_read_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer) { - if (offset + len >= disk->rd.len) { + if (offset >= disk->rd.len) { WARN("attempted to read past length of ramdisk"); return -E_BAD_PARAM; } + if (disk->rd.len - offset < len) + len = disk->rd.len - offset; + memcpy(buffer, disk->rd.start + offset, len); - return 0; + return len; } static int disk_read_ata(struct disk *disk, size_t offset, size_t len, @@ -181,13 +185,16 @@ int disk_read(struct disk *disk, size_t offset, size_t len, void *buffer) static int disk_write_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer) { - if (offset + len >= disk->rd.len) { + if (offset >= disk->rd.len) { WARN("attempted to write past length of ramdisk"); return -E_BAD_PARAM; } + if (disk->rd.len - offset < len) + len = disk->rd.len - offset; + memcpy(disk->rd.start + offset, buffer, len); - return 0; + return len; } static int disk_write_ata(struct disk *disk, size_t offset, size_t len, diff --git a/kernel/fs/ramfs.c b/kernel/fs/ramfs.c new file mode 100644 index 0000000..0c92c96 --- /dev/null +++ b/kernel/fs/ramfs.c @@ -0,0 +1,171 @@ +#include <comus/fs.h> +/*#include <lib.h> +//#include <comus/tar.h> +//#include <string.h> +#include <comus/ramfs.h> + +#define NOERROR 0 +#define ERROR 1 + +int ramfs_check_exists(const char *name) { + for(int i = 0; i < numberOfFiles; i++) { + if(memcmp(allTheFiles[i].name, name, strlen(allTheFiles[i].name)) == 0) { + // found it + return i; + } + } + // doesn't exist + return -1; +} +int ramfs_create(const char *name) { + if(ramfs_check_exists(name) != -1) { + // already exists + return ERROR; + } + struct file *newFile; + *newFile->name = name; + newFile->size = 0; + newFile->data = kalloc(MAX_FILE_SIZE); + newFile = &allTheFiles[numberOfFiles]; + +} + +int ramfs_delete(const char *name) { + int i = ramfs_check_exists(name); + if(i >= 0) { + kfree(allTheFiles[i].data); + for(int j = i; j < numberOfFiles; j++) { + allTheFiles[j] = allTheFiles[j+1]; + numberOfFiles -= 1; + } + return NOERROR; + + } + return ERROR; +} + +int ramfs_read(const char *name, char *buffer, size_t len) { + int i = ramfs_check_exists(name); + if(i >= 0) { + memcpy(buffer, allTheFiles[i].data, len); + return NOERROR; + } + return ERROR; +} + + +int ramfs_write(const char *name, char *buffer) { + int i = ramfs_check_exists(name); + if(i >= 0) { + memcpy(buffer) + } +} + +// here we return the index of the file as well. +*int ramfs_find_file(root *r, const char *fullpath, const char *name, file *out, directory *outDirectory) { + directory *location = r->root; + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + for(int i = 0; i < location->file_count; i++) { + if(strcmp(location->files[i]->name, name) == 0) { + outDirectory = location; + out = location->files[i]; + return i; + } + } + + } + return -1; +} +int ramfs_find_directory(root *r, const char *fullpath, const char *name, directory *out) { + directory *location = r->root; + char *path = fullpath; + char *tempPath = strtok(tempPath, "/"); + while(tempPath != NULL) { + bool wasItFound = false; + + for(int i = 0; i < location->directory_count; i++) { + if(strcmp(location->directories[i]->name, tempPath) == 0) { + // yay we found it; + location = location->directories[i]; + wasItFound = true; + break; + + } + } + if(!wasItFound) { + return ERROR; + } + tempPath = strtok(NULL, "/"); + + } + out = location; + return NOERROR; + +} + +int ramfs_create_file(root *r, const char *fullpath, const char *name) { + // trace through the path + // struct ramfs_directory *location = r->root; + directory *location = r->root; + + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + if(location->file_count >= MAX_FILES) { + return ERROR; + } + file *newFile = malloc(sizeof(file)); + strcpy(newFile->name, name); + newFile->size = 0; + newFile->data = malloc(MAX_FILE_SIZE); + location->files[location->file_count] = newFile; + location->file_count += 1; + + return NOERROR; + + } + return ERROR; +} + +int ramfs_delete_file(root *r, const char *fullpath, const char *name) { + directory *location; + if(ramfs_find_directory(r, fullpath, name, location) == NOERROR) { + file *find_file; + int file_index = ramfs_find_file(r, fullpath, name, find_file, location) >= 0; + if(file_index >= 0) { + free(location->files[file_index]->data); + free(location->files[file_index]); + for(int i = file_index + 1; i < location->file_count; i++) { + location->files[i-1] = location->files[i]; + //memcpy(location->files[i-1], location->files[i], location->files[i]->size); + //free(location->files[i]); + } + location->file_count -= 1; + return NOERROR; + } + return ERROR; + + } + return ERROR; +} + +int ramfs_create_directory() { + +} + +int ramfs_delete_directory() { +} + +int ramfs_write() { + +} + + +root *ramfs_init() { + root *r = malloc(sizeof(root)); + r->root = malloc(sizeof(directory)); + strcpy(r->root->name, "/"); + r->root->file_count = 0; + r->root->directory_count = 0; + return r; +} + +*/ diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c new file mode 100644 index 0000000..5f02c34 --- /dev/null +++ b/kernel/fs/tar.c @@ -0,0 +1,306 @@ +#include <comus/fs.h> +#include <lib.h> +#include <comus/tar.h> + +// the placements of these values mimics their placement in standard UStar +struct tar_header { + char name[100]; // 0-99 + char mode[8]; // 100-107 + char ownerUID[8]; // 108-115 + char groupUID[8]; // 116-123 + char fileSize[12]; // 124-135 + char lastMod[12]; // 136-147 + char checksum[8]; // 148-155 + char type_flag; // 156 + char linked_name[100]; // 157-256 + char magic[6]; // 257-262 + char version[2]; // 263-264 + char username[32]; // 265-296 + char groupname[32]; // 297-328 + char majorNum[8]; // 329-336 + char minorNum[8]; // 337-344 + char prefix[155]; // 345-499 + char notUsed[12]; // 500-511 +}; +#define TAR_SIZE 512 +#define TMAGIC "ustar" /* ustar and a null */ +#define TMAGLEN 6 +#define TVERSION "00" /* 00 and no null */ +#define TVERSLEN 2 +#define ERROR_TAR 1 +#define NOERROR_TAR 0 + +#define REGTYPE '0' /* regular file */ +#define DIRTYPE '5' /* directory */ + +struct tar_file { + struct file file; + struct file_system *fs; + size_t len; + size_t offset; + size_t sect; +}; +// read_tar_header reads what is in tar +int read_tar_header(struct disk *disk, uint32_t sect, struct tar_header *hdr) +{ + if (disk_read(disk, sect * TAR_SIZE, TAR_SIZE, hdr) < TAR_SIZE) { + return ERROR_TAR; + } + if (memcmp(hdr->magic, TMAGIC, TMAGLEN) != 0 || + memcmp(hdr->version, TVERSION, TVERSLEN) != 0) { + return ERROR_TAR; + } + return NOERROR_TAR; +} + +/// @brief +/// @param f the file to be read +/// @param buffer the buffer that the content of the file is read into +/// @param len +/// @return +int tar_read(struct file *f, void *buffer, size_t len) +{ + struct tar_file *tf = (struct tar_file *)f; + long size = MIN((tf->len - tf->offset), len); + if (tf->file.f_type != F_REG || size < 1) { + return ERROR_TAR; + } + size = disk_read(tf->fs->fs_disk, (tf->sect + 1) * TAR_SIZE + tf->offset, + size, buffer); + tf->offset += size; + return size; +} +//static int read_tar() +// we are assuming that things are formatted correctly. +int find_file(struct file_system *fs, const char *filepath, size_t *sect, + size_t *sect_return, struct tar_header *outHeader) +{ + //char *tempFilePath = filepath; + struct tar_header hdr; + size_t curr_sect; + if (sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if (read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if (memcmp(hdr.name, filepath, strlen(filepath) + 1) != 0) { + // didn't find it. + + curr_sect += + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / TAR_SIZE) + + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if (sect != NULL) { + sect += curr_sect; + } + return NOERROR_TAR; + } + } + return ERROR_TAR; +} +int find_file_redux(struct file_system *fs, const char *filepath, size_t *sect, + size_t *sect_return, struct tar_header *outHeader) +{ + struct tar_header hdr; + size_t curr_sect; + if (sect == NULL) { + curr_sect = 0; + } else { + curr_sect = *sect; + } + while (1 == 1) { + if (read_tar_header(fs->fs_disk, curr_sect, &hdr) != 0) { + return ERROR_TAR; + } + if (memcmp(hdr.name, filepath, + MIN(strlen(filepath), strlen(hdr.name))) != 0) { + // didn't find it. + + curr_sect += + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / TAR_SIZE) + + 1; + continue; + } else { + *outHeader = hdr; + *sect_return = curr_sect; + if (sect != NULL) { + sect += curr_sect + + ((strtoull(hdr.fileSize, NULL, 8) + TAR_SIZE - 1) / + TAR_SIZE) + + 1; + } + return NOERROR_TAR; + } + } + return ERROR_TAR; // it should never actually reach here. +} + +void tar_close(struct file *f) +{ + kfree(f); +} + +int tar_seek(struct file *f, long int offsetAdd, int theSeek) +{ + struct tar_file *tf = (struct tar_file *)f; + if (theSeek == SEEK_SET) { + tf->offset = offsetAdd; + return tf->offset; + } else if (theSeek == SEEK_CUR) { + tf->offset = tf->offset + offsetAdd; + return tf->offset; + } else if (theSeek == SEEK_END) { + tf->offset = tf->len + offsetAdd; + return tf->offset; + } else { + return -1; + } +} + +int tar_write(struct file *f, const void *buffer, size_t len) +{ + // tar doesn't do write lol. This is just here so there is something to send to write + (void)f; + (void)buffer; + (void)len; + return ERROR_TAR; +} + +/*int tar_ents(struct file *f, struct dirent *d, size_t dIndex) { + struct tar_header hdr; + struct tar_header dir; + struct tar_file *tf = (struct tar_file*) f; + size_t sect = 0; + size_t sect_off = 0; + size_t curr_index = 0; + if(read_tar_header(tf->fs->fs_disk, sect, &hdr) != 0) { + return ERROR_TAR; + } + while(1 == 1) { + if(find_file_redux(tf->fs, dir.name, §_off, §, &dir) != 0) { + return ERROR_TAR; + } + if(curr_index < dIndex) { + curr_index += 1; + } else if(curr_index > dIndex) { + // something went seriously wrong + return ERROR_TAR; + } else { + d->d_namelen = strlen(hdr.name); + dir.type_flag = DIRTYPE; + d->d_offset = dIndex; + memcpy(d->d_name, hdr.name, d->d_namelen + 1); + return NOERROR_TAR; + } + + + } + + +}*/ + +int tar_ents(struct file *f, struct dirent *ent, size_t entry) +{ + struct tar_file *tf; + struct tar_header dir, hdr; + size_t sect; + size_t sect_off = 0; + size_t idx = 0; + + tf = (struct tar_file *)f; + sect = 0; + + if (tf->file.f_type != F_DIR) + return -1; + + if (read_tar_header(tf->fs->fs_disk, sect, &dir)) { + return ERROR_TAR; + } + + while (1) { + if (find_file_redux(tf->fs, dir.name, §_off, §, &hdr)) + return ERROR_TAR; + + if (idx != entry) { + idx++; + continue; + } + + ent->d_offset = entry; + ent->d_namelen = strlen(hdr.name); + memcpy(ent->d_name, hdr.name, ent->d_namelen + 1); + return NOERROR_TAR; + } + + return ERROR_TAR; +} + +// opens up the tar file at fullpath, and puts it in out. +int tar_open(struct file_system *fs, const char *fullpath, int flags, + struct file **out) +{ + struct tar_header hdr; + struct tar_file *newFile; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + if (flags != O_RDONLY) { + return ERROR_TAR; + } + newFile = kalloc(sizeof(struct tar_file)); + + newFile->file.f_type = F_REG; + newFile->fs = fs; + newFile->file.read = tar_read; + newFile->file.close = tar_close; + newFile->file.write = tar_write; // doesn't actually work; + newFile->file.ents = tar_ents; + newFile->file.seek = tar_seek; + newFile->offset = 0; + newFile->len = strtoull(hdr.fileSize, NULL, 8); + newFile->sect = sect_result; + + *out = (struct file *)newFile; + return NOERROR_TAR; +} + +// gets stats at the file at fullpath, putting them in out. +int tar_stat(struct file_system *fs, const char *fullpath, struct stat *out) +{ + struct tar_header hdr; + size_t sect_result; + find_file(fs, fullpath, NULL, §_result, &hdr); + out->s_length = strtoull(hdr.fileSize, NULL, 8); + if (hdr.type_flag == REGTYPE) { + out->s_type = F_REG; + } else if (hdr.type_flag == DIRTYPE) { + out->s_type = F_DIR; + } else { + // wth + return ERROR_TAR; + } + return NOERROR_TAR; +} + +// use tar for the filesystem. +int tar_mount(struct file_system *fs) +{ + struct tar_header hdr; + // reads into hdr + if (read_tar_header(fs->fs_disk, 0, &hdr) == 0) { + fs->fs_name = "tar"; + fs->open = tar_open; + fs->stat = tar_stat; + fs->fs_present = true; + return NOERROR_TAR; + } + return ERROR_TAR; +} + +// no need to unmount, since mount just overrides whatever it was using previously.
\ No newline at end of file |