diff options
Diffstat (limited to 'core/fs/fs.c')
-rw-r--r-- | core/fs/fs.c | 172 |
1 files changed, 42 insertions, 130 deletions
diff --git a/core/fs/fs.c b/core/fs/fs.c index 3cb27b0d..b6ee19c2 100644 --- a/core/fs/fs.c +++ b/core/fs/fs.c @@ -1,15 +1,20 @@ +#include <sys/file.h> #include <stdio.h> #include <stdbool.h> #include <string.h> +#include <unistd.h> +#include <fcntl.h> #include <dprintf.h> +#include "core.h" +#include "dev.h" #include "fs.h" #include "cache.h" /* The currently mounted filesystem */ -struct fs_info *this_fs = NULL; /* Root filesystem */ +__export struct fs_info *this_fs = NULL; /* Root filesystem */ /* Actual file structures (we don't have malloc yet...) */ -struct file files[MAX_OPEN]; +__export struct file files[MAX_OPEN]; /* Symlink hard limits */ #define MAX_SYMLINK_CNT 20 @@ -34,9 +39,13 @@ struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data) */ void put_inode(struct inode *inode) { - while (inode && --inode->refcnt == 0) { + while (inode) { struct inode *dead = inode; - inode = inode->parent; + int refcnt = --(dead->refcnt); + dprintf("put_inode %p name %s refcnt %u\n", dead, dead->name, refcnt); + if (refcnt) + break; /* We still have references */ + inode = dead->parent; if (dead->name) free((char *)dead->name); free(dead); @@ -68,7 +77,7 @@ static inline void free_file(struct file *file) memset(file, 0, sizeof *file); } -void _close_file(struct file *file) +__export void _close_file(struct file *file) { if (file->fs) file->fs->fs_ops->close_file(file); @@ -76,92 +85,37 @@ void _close_file(struct file *file) } /* - * Convert between a 16-bit file handle and a file structure + * Find and open the configuration file */ - -void pm_load_config(com32sys_t *regs) +__export int open_config(void) { - int err; + int fd, handle; + struct file_info *fp; - err = this_fs->fs_ops->load_config(); + fd = opendev(&__file_dev, NULL, O_RDONLY); + if (fd < 0) + return -1; - if (err) - printf("ERROR: No configuration file found\n"); + fp = &__file_info[fd]; - set_flags(regs, err ? EFLAGS_ZF : 0); -} + handle = this_fs->fs_ops->open_config(&fp->i.fd); + if (handle < 0) { + close(fd); + errno = ENOENT; + return -1; + } -void pm_mangle_name(com32sys_t *regs) -{ - const char *src = MK_PTR(regs->ds, regs->esi.w[0]); - char *dst = MK_PTR(regs->es, regs->edi.w[0]); + fp->i.offset = 0; + fp->i.nbytes = 0; - mangle_name(dst, src); + return fd; } -void mangle_name(char *dst, const char *src) +__export void mangle_name(char *dst, const char *src) { this_fs->fs_ops->mangle_name(dst, src); } -void getfssec(com32sys_t *regs) -{ - int sectors; - bool have_more; - uint32_t bytes_read; - char *buf; - struct file *file; - uint16_t handle; - - sectors = regs->ecx.w[0]; - - handle = regs->esi.w[0]; - file = handle_to_file(handle); - - buf = MK_PTR(regs->es, regs->ebx.w[0]); - bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); - - /* - * If we reach EOF, the filesystem driver will have already closed - * the underlying file... this really should be cleaner. - */ - if (!have_more) { - _close_file(file); - regs->esi.w[0] = 0; - } - - regs->ecx.l = bytes_read; -} - -void getfsbytes(com32sys_t *regs) -{ - int sectors; - bool have_more; - uint32_t bytes_read; - char *buf; - struct file *file; - uint16_t handle; - - handle = regs->esi.w[0]; - file = handle_to_file(handle); - - sectors = regs->ecx.w[0] >> SECTOR_SHIFT(file->fs); - - buf = MK_PTR(regs->es, regs->ebx.w[0]); - bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); - - /* - * If we reach EOF, the filesystem driver will have already closed - * the underlying file... this really should be cleaner. - */ - if (!have_more) { - _close_file(file); - regs->esi.w[0] = 0; - } - - regs->ecx.l = bytes_read; -} - size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) { bool have_more; @@ -183,24 +137,7 @@ size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) return bytes_read; } -void pm_searchdir(com32sys_t *regs) -{ - char *name = MK_PTR(regs->ds, regs->edi.w[0]); - int rv; - - rv = searchdir(name); - if (rv < 0) { - regs->esi.w[0] = 0; - regs->eax.l = 0; - regs->eflags.l |= EFLAGS_ZF; - } else { - regs->esi.w[0] = rv; - regs->eax.l = handle_to_file(rv)->inode->size; - regs->eflags.l &= ~EFLAGS_ZF; - } -} - -int searchdir(const char *name) +int searchdir(const char *name, int flags) { static char root_name[] = "/"; struct file *file; @@ -217,7 +154,7 @@ int searchdir(const char *name) /* if we have ->searchdir method, call it */ if (file->fs->fs_ops->searchdir) { - file->fs->fs_ops->searchdir(name, file); + file->fs->fs_ops->searchdir(name, flags, file); if (file->inode) return file_to_handle(file); @@ -398,7 +335,7 @@ err_no_close: return -1; } -int open_file(const char *name, struct com32_filedata *filedata) +__export int open_file(const char *name, int flags, struct com32_filedata *filedata) { int rv; struct file *file; @@ -407,7 +344,7 @@ int open_file(const char *name, struct com32_filedata *filedata) dprintf("open_file %s\n", name); mangle_name(mangled_name, name); - rv = searchdir(mangled_name); + rv = searchdir(mangled_name, flags); if (rv < 0) return rv; @@ -426,29 +363,7 @@ int open_file(const char *name, struct com32_filedata *filedata) return rv; } -void pm_open_file(com32sys_t *regs) -{ - int rv; - struct file *file; - const char *name = MK_PTR(regs->es, regs->esi.w[0]); - char mangled_name[FILENAME_MAX]; - - dprintf("pm_open_file %s\n", name); - - mangle_name(mangled_name, name); - rv = searchdir(mangled_name); - if (rv < 0) { - regs->eflags.l |= EFLAGS_CF; - } else { - file = handle_to_file(rv); - regs->eflags.l &= ~EFLAGS_CF; - regs->eax.l = file->inode->size; - regs->ecx.w[0] = SECTOR_SIZE(file->fs); - regs->esi.w[0] = rv; - } -} - -void close_file(uint16_t handle) +__export void close_file(uint16_t handle) { struct file *file; @@ -458,11 +373,6 @@ void close_file(uint16_t handle) } } -void pm_close_file(com32sys_t *regs) -{ - close_file(regs->esi.w[0]); -} - /* * it will do: * initialize the memory management function; @@ -488,9 +398,6 @@ void fs_init(com32sys_t *regs) /* ops is a ptr list for several fs_ops */ const struct fs_ops **ops = (const struct fs_ops **)regs->eax.l; - /* Initialize malloc() */ - mem_init(); - /* Default name for the root directory */ fs.cwd_name[0] = '/'; @@ -532,6 +439,11 @@ void fs_init(com32sys_t *regs) dprintf("init: root inode %p, cwd inode %p\n", fs.root, fs.cwd); } + if (fs.fs_ops->chdir_start) { + if (fs.fs_ops->chdir_start() < 0) + printf("Failed to chdir to start directory\n"); + } + SectorShift = fs.sector_shift; SectorSize = fs.sector_size; } |