summaryrefslogtreecommitdiff
path: root/core/fs/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/fs/fs.c')
-rw-r--r--core/fs/fs.c172
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;
}