From 65409d2312e702a48d3cf5b32479d25266bda3c3 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 1 Jan 2020 18:22:19 -0800 Subject: 5858 Move script to create a Soso boot image into a sub-directory. I'm trying to streamline newcomer attention to just a couple of use cases. --- tools/iso/kernel.soso/fs.c | 530 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 tools/iso/kernel.soso/fs.c (limited to 'tools/iso/kernel.soso/fs.c') diff --git a/tools/iso/kernel.soso/fs.c b/tools/iso/kernel.soso/fs.c new file mode 100644 index 00000000..0d072c33 --- /dev/null +++ b/tools/iso/kernel.soso/fs.c @@ -0,0 +1,530 @@ +#include "fs.h" +#include "alloc.h" +#include "screen.h" +#include "rootfs.h" + +FileSystemNode *gFileSystemRoot = NULL; // The root of the filesystem. + +#define FILESYSTEM_CAPACITY 10 + +static FileSystem gRegisteredFileSystems[FILESYSTEM_CAPACITY]; +static int gNextFileSystemIndex = 0; + +void initializeVFS() { + memset((uint8*)gRegisteredFileSystems, 0, sizeof(gRegisteredFileSystems)); + + gFileSystemRoot = initializeRootFS(); + + mkdir_fs(gFileSystemRoot, "dev", 0); + mkdir_fs(gFileSystemRoot, "initrd", 0); +} + +FileSystemNode* getFileSystemRootNode() { + return gFileSystemRoot; +} + +void copyFileDescriptors(Process* fromProcess, Process* toProcess) { + for (int i = 0; i < MAX_OPENED_FILES; ++i) { + File* original = fromProcess->fd[i]; + + if (original) { + File* file = kmalloc(sizeof(File)); + memcpy((uint8*)file, (uint8*)original, sizeof(File)); + file->process = toProcess; + file->thread = NULL; + + toProcess->fd[i] = file; + + } + } +} + +int getFileSystemNodePath(FileSystemNode *node, char* buffer, uint32 bufferSize) { + if (node == gFileSystemRoot) { + if (bufferSize > 1) { + buffer[0] = '/'; + buffer[1] = '\0'; + + return 1; + } + else { + return -1; + } + } + + char targetPath[128]; + + FileSystemNode *n = node; + int charIndex = 127; + targetPath[charIndex] = '\0'; + while (NULL != n) { + int length = strlen(n->name); + charIndex -= length; + + if (charIndex < 2) { + return -1; + } + + if (NULL != n->parent) { + strcpyNonNull(targetPath + charIndex, n->name); + charIndex -= 1; + targetPath[charIndex] = '/'; + } + + n = n->parent; + } + + int len = 127 - charIndex; + + //printkf("getFileSystemNodePath: len:[%s] %d\n", targetPath + charIndex, len); + + if (bufferSize < len) { + return -1; + } + + strcpy(buffer, targetPath + charIndex); + + return len; +} + +BOOL resolvePath(const char* path, char* buffer, int bufferSize) { + int lengthPath = strlen(path); + + if (path[0] != '/') { + return FALSE; + } + + if (bufferSize < 2) { + return FALSE; + } + + buffer[0] = '/'; + buffer[1] = '\0'; + int index = 0; + int indexBuffer = 1; + + while (index < lengthPath - 1) { + while (path[++index] == '/');//eliminate successive + + const char* current = path + index; + int nextIndex = strFirstIndexOf(path + index, '/'); + + int lengthToken = 0; + + if (nextIndex >= 0) { + const char* next = path + index + nextIndex; + + lengthToken = next - (path + index); + } + else { + lengthToken = strlen(current); + } + + if (lengthToken > 0) { + index += lengthToken; + if (strncmp(current, "..", 2) == 0) { + --indexBuffer; + while (indexBuffer > 0) { + --indexBuffer; + + if (buffer[indexBuffer] == '/') { + break; + } + + buffer[indexBuffer] = '\0'; + } + + ++indexBuffer; + continue; + } + else if (strncmp(current, ".", 1) == 0) { + continue; + } + + if (indexBuffer + lengthToken + 2 > bufferSize) { + return FALSE; + } + + strncpy(buffer + indexBuffer, current, lengthToken); + indexBuffer += lengthToken; + + if (current[lengthToken] == '/') { + buffer[indexBuffer++] = '/'; + } + buffer[indexBuffer] = '\0'; + } + } + + if (indexBuffer > 2) { + if (buffer[indexBuffer - 1] == '/') { + buffer[indexBuffer - 1] = '\0'; + } + } + + return TRUE; +} + +uint32 read_fs(File *file, uint32 size, uint8 *buffer) { + if (file->node->read != 0) { + return file->node->read(file, size, buffer); + } + + return -1; +} + +uint32 write_fs(File *file, uint32 size, uint8 *buffer) { + if (file->node->write != 0) { + return file->node->write(file, size, buffer); + } + + return -1; +} + +File *open_fs(FileSystemNode *node, uint32 flags) { + return open_fs_forProcess(getCurrentThread(), node, flags); +} + +File *open_fs_forProcess(Thread* thread, FileSystemNode *node, uint32 flags) { + Process* process = thread->owner; + + if ( (node->nodeType & FT_MountPoint) == FT_MountPoint && node->mountPoint != NULL ) { + node = node->mountPoint; + } + + if (node->open != NULL) { + File* file = kmalloc(sizeof(File)); + memset((uint8*)file, 0, sizeof(File)); + file->node = node; + file->process = process; + file->thread = thread; + + BOOL success = node->open(file, flags); + + if (success) { + //printkf("Opened:%s\n", file->node->name); + int32 fd = addFileToProcess(file->process, file); + + if (fd < 0) { + //TODO: sett errno max files opened already + printkf("Maxfiles opened already!!\n"); + + close_fs(file); + file = NULL; + } + } + else { + kfree(file); + } + + return file; + } + + return NULL; +} + +void close_fs(File *file) { + if (file->node->close != NULL) { + file->node->close(file); + } + + removeFileFromProcess(file->process, file); + + kfree(file); +} + +int32 ioctl_fs(File *file, int32 request, void * argp) { + if (file->node->ioctl != NULL) { + return file->node->ioctl(file, request, argp); + } + + return 0; +} + +int32 lseek_fs(File *file, int32 offset, int32 whence) { + if (file->node->lseek != NULL) { + return file->node->lseek(file, offset, whence); + } + + return 0; +} + +int32 ftruncate_fs(File* file, int32 length) { + if (file->node->ftruncate != NULL) { + return file->node->ftruncate(file, length); + } + + return -1; +} + +int32 stat_fs(FileSystemNode *node, struct stat *buf) { +#define __S_IFDIR 0040000 /* Directory. */ +#define __S_IFCHR 0020000 /* Character device. */ +#define __S_IFBLK 0060000 /* Block device. */ +#define __S_IFREG 0100000 /* Regular file. */ +#define __S_IFIFO 0010000 /* FIFO. */ +#define __S_IFLNK 0120000 /* Symbolic link. */ +#define __S_IFSOCK 0140000 /* Socket. */ + + if (node->stat != NULL) { + int32 val = node->stat(node, buf); + + if (val == 1) { + //return value of 1 from driver means we should fill buf here. + + if ((node->nodeType & FT_Directory) == FT_Directory) { + buf->st_mode = __S_IFDIR; + } + else if ((node->nodeType & FT_CharacterDevice) == FT_CharacterDevice) { + buf->st_mode = __S_IFCHR; + } + else if ((node->nodeType & FT_BlockDevice) == FT_BlockDevice) { + buf->st_mode = __S_IFBLK; + } + else if ((node->nodeType & FT_Pipe) == FT_Pipe) { + buf->st_mode = __S_IFIFO; + } + else if ((node->nodeType & FT_SymbolicLink) == FT_SymbolicLink) { + buf->st_mode = __S_IFLNK; + } + else if ((node->nodeType & FT_File) == FT_File) { + buf->st_mode = __S_IFREG; + } + + buf->st_size = node->length; + + return 0; + } + else { + return val; + } + } + + return -1; +} + +FileSystemDirent *readdir_fs(FileSystemNode *node, uint32 index) { + //printkf("readdir_fs: node->name:%s index:%d\n", node->name, index); + + if ( (node->nodeType & FT_MountPoint) == FT_MountPoint && node->mountPoint != NULL ) { + if (NULL == node->mountPoint->readdir) { + WARNING("mounted fs does not have readdir!\n"); + } + else { + return node->mountPoint->readdir(node->mountPoint, index); + } + } + else if ( (node->nodeType & FT_Directory) == FT_Directory && node->readdir != NULL ) { + return node->readdir(node, index); + } + + return NULL; +} + +FileSystemNode *finddir_fs(FileSystemNode *node, char *name) { + //printkf("finddir_fs: name:%s\n", name); + + if ( (node->nodeType & FT_MountPoint) == FT_MountPoint && node->mountPoint != NULL ) { + if (NULL == node->mountPoint->finddir) { + WARNING("mounted fs does not have finddir!\n"); + } + else { + return node->mountPoint->finddir(node->mountPoint, name); + } + } + else if ( (node->nodeType & FT_Directory) == FT_Directory && node->finddir != NULL ) { + return node->finddir(node, name); + } + + return NULL; +} + +BOOL mkdir_fs(FileSystemNode *node, const char *name, uint32 flags) { + if ( (node->nodeType & FT_MountPoint) == FT_MountPoint && node->mountPoint != NULL ) { + if (node->mountPoint->mkdir) { + return node->mountPoint->mkdir(node->mountPoint, name, flags); + } + } + else if ( (node->nodeType & FT_Directory) == FT_Directory && node->mkdir != NULL ) { + return node->mkdir(node, name, flags); + } + + return FALSE; +} + +void* mmap_fs(File* file, uint32 size, uint32 offset, uint32 flags) { + if (file->node->mmap) { + return file->node->mmap(file, size, offset, flags); + } + + return NULL; +} + +BOOL munmap_fs(File* file, void* address, uint32 size) { + if (file->node->munmap) { + return file->node->munmap(file, address, size); + } + + return FALSE; +} + +FileSystemNode *getFileSystemNode(const char *path) { + //printkf("getFileSystemNode:%s *0\n", path); + + if (path[0] != '/') { + //We require absolute path! + return NULL; + } + + + char realPath[256]; + + BOOL resolved = resolvePath(path, realPath, 256); + + if (FALSE == resolved) { + return NULL; + } + + const char* inputPath = realPath; + int pathLength = strlen(inputPath); + + if (pathLength < 1) { + return NULL; + } + + + + //printkf("getFileSystemNode:%s *1\n", path); + + FileSystemNode* root = getFileSystemRootNode(); + + if (pathLength == 1) { + return root; + } + + int nextIndex = 0; + + FileSystemNode* node = root; + + //printkf("getFileSystemNode:%s *2\n", path); + + char buffer[64]; + + do { + do_start: + inputPath = inputPath + nextIndex + 1; + nextIndex = strFirstIndexOf(inputPath, '/'); + + if (nextIndex == 0) { + //detected successive slash + goto do_start; + } + + if (nextIndex > 0) { + int tokenSize = nextIndex; + + strncpy(buffer, inputPath, tokenSize); + buffer[tokenSize] = '\0'; + } + else { + //Last part + strcpy(buffer, inputPath); + } + + //printkf("getFileSystemNode:%s *3\n", path); + + node = finddir_fs(node, buffer); + + //printkf("getFileSystemNode:%s *4\n", path); + + if (NULL == node) { + return NULL; + } + + } while (nextIndex > 0); + + return node; +} + +FileSystemNode* getFileSystemNodeAbsoluteOrRelative(const char* path, Process* process) { + FileSystemNode* node = NULL; + + if (process) { + if ('\0' == path[0]) { + //empty + } + else if ('/' == path[0]) { + //absolute + + node = getFileSystemNode(path); + } + else { + //relative + + if (process->workingDirectory) { + char buffer[256]; + + if (getFileSystemNodePath(process->workingDirectory, buffer, 256) >= 0) { + strcat(buffer, "/"); + strcat(buffer, path); + + //printkf("getFileSystemNodeAbsoluteOrRelative:[%s]\n", buffer); + + node = getFileSystemNode(buffer); + } + } + } + } + + return node; +} + +BOOL registerFileSystem(FileSystem* fs) { + if (strlen(fs->name) <= 0) { + return FALSE; + } + + for (int i = 0; i < gNextFileSystemIndex; ++i) { + if (strcmp(gRegisteredFileSystems[i].name, fs->name) == 0) { + //name is in use + return FALSE; + } + } + + gRegisteredFileSystems[gNextFileSystemIndex++] = *fs; + + return TRUE; +} + +BOOL mountFileSystem(const char *source, const char *target, const char *fsType, uint32 flags, void *data) { + FileSystem* fs = NULL; + + for (int i = 0; i < gNextFileSystemIndex; ++i) { + if (strcmp(gRegisteredFileSystems[i].name, fsType) == 0) { + fs = &gRegisteredFileSystems[i]; + break; + } + } + + if (NULL == fs) { + return FALSE; + } + + return fs->mount(source, target, flags, data); +} + +BOOL checkMountFileSystem(const char *source, const char *target, const char *fsType, uint32 flags, void *data) { + FileSystem* fs = NULL; + + for (int i = 0; i < gNextFileSystemIndex; ++i) { + if (strcmp(gRegisteredFileSystems[i].name, fsType) == 0) { + fs = &gRegisteredFileSystems[i]; + break; + } + } + + if (NULL == fs) { + return FALSE; + } + + return fs->checkMount(source, target, flags, data); +} -- cgit 1.4.1-2-gfad0