summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init/driver/ansiterm.c2
-rw-r--r--src/init/driver/tmpfs.c21
-rw-r--r--src/init/fs/misc.c14
-rw-r--r--src/init/syscalls.c2
-rw-r--r--src/init/tar.c19
-rw-r--r--src/kernel/arch/i386/driver/fsroot.c7
-rw-r--r--src/kernel/handle.h2
-rw-r--r--src/kernel/syscalls.c4
-rw-r--r--src/kernel/vfs/request.c7
-rw-r--r--src/kernel/vfs/request.h6
-rw-r--r--src/shared/syscalls.h4
11 files changed, 45 insertions, 43 deletions
diff --git a/src/init/driver/ansiterm.c b/src/init/driver/ansiterm.c
index 4d98972..b7f0b04 100644
--- a/src/init/driver/ansiterm.c
+++ b/src/init/driver/ansiterm.c
@@ -83,7 +83,7 @@ void ansiterm_drv(void) {
break;
}
// TODO check path
- _syscall_fs_respond(NULL, 1, 0);
+ _syscall_fs_respond(NULL, 0, 0);
break;
case VFSOP_WRITE:
diff --git a/src/init/driver/tmpfs.c b/src/init/driver/tmpfs.c
index 4b639da..bbed095 100644
--- a/src/init/driver/tmpfs.c
+++ b/src/init/driver/tmpfs.c
@@ -10,6 +10,7 @@ struct node {
};
struct node *root = NULL;
+static struct node special_root;
static struct node *lookup(const char *path, size_t len) {
for (struct node *iter = root; iter; iter = iter->next) {
@@ -19,18 +20,18 @@ static struct node *lookup(const char *path, size_t len) {
return NULL;
}
-static int tmpfs_open(const char *path, struct fs_wait_response *res) {
- if (res->len == 0) return -1;
+static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) {
+ if (res->len == 0) return NULL;
path++;
res->len--;
- if (res->len == 0) return 0; /* root */
+ if (res->len == 0) return &special_root;
// no directory support (yet)
- if (memchr(path, '/', res->len)) return -1;
+ if (memchr(path, '/', res->len)) return NULL;
if (res->flags & OPEN_CREATE) {
- if (lookup(path, res->len)) return -1; /* already exists */
+ if (lookup(path, res->len)) return NULL; /* already exists */
struct node *new = malloc(sizeof *new);
char *namebuf = malloc(res->len);
memcpy(namebuf, path, res->len);
@@ -38,24 +39,26 @@ static int tmpfs_open(const char *path, struct fs_wait_response *res) {
new->len = res->len;
new->next = root;
root = new;
- return 1;
+ return new;
}
- return lookup(path, res->len) != 0 ? 1 : -1;
+ return lookup(path, res->len);
}
void tmpfs_drv(void) {
// TODO replace all the static allocations in drivers with mallocs
static char buf[512];
struct fs_wait_response res;
+ struct node *ptr;
while (!_syscall_fs_wait(buf, sizeof buf, &res)) {
switch (res.op) {
case VFSOP_OPEN:
- _syscall_fs_respond(NULL, tmpfs_open(buf, &res), 0);
+ ptr = tmpfs_open(buf, &res);
+ _syscall_fs_respond(ptr, ptr ? 0 : -1, 0);
break;
case VFSOP_READ:
- if (res.id != 0) {
+ if (res.id != &special_root) {
// rw unimplemented
_syscall_fs_respond(NULL, -1, 0);
break;
diff --git a/src/init/fs/misc.c b/src/init/fs/misc.c
index b394c26..701db9f 100644
--- a/src/init/fs/misc.c
+++ b/src/init/fs/misc.c
@@ -188,7 +188,7 @@ void fs_dir_inject(const char *path) {
/* if we're making up the opened directory, disallow create */
if (ret < 0 && (res.flags & OPEN_CREATE)) hid = ret;
- _syscall_fs_respond(NULL, hid, 0);
+ _syscall_fs_respond((void*)hid, hid, 0);
} else {
/* not injecting, don't allow opening nonexistent stuff */
@@ -198,16 +198,16 @@ void fs_dir_inject(const char *path) {
break;
case VFSOP_CLOSE:
- if (handles[res.id].delegate >= 0)
- _syscall_close(handles[res.id].delegate);
- handles[res.id].taken = false;
+ if (handles[(int)res.id].delegate >= 0)
+ _syscall_close(handles[(int)res.id].delegate);
+ handles[(int)res.id].taken = false;
_syscall_fs_respond(NULL, 0, 0);
break;
case VFSOP_READ:
- if (handles[res.id].inject) {
+ if (handles[(int)res.id].inject) {
if (res.offset > 0) _syscall_fs_respond(NULL, 0, 0); // TODO working offsets
- struct fs_dir_handle h = handles[res.id];
+ struct fs_dir_handle h = handles[(int)res.id];
int out_len = 0;
while (h.inject[out_len] && h.inject[out_len] != '/')
@@ -232,7 +232,7 @@ void fs_dir_inject(const char *path) {
/* fallthrough */
default: {
- struct fs_dir_handle h = handles[res.id];
+ struct fs_dir_handle h = handles[(int)res.id];
if (h.delegate < 0)
_syscall_fs_respond(NULL, -1, 0);
else
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index f7e540f..14c0d52 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -42,7 +42,7 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us
return _syscall(_SYSCALL_FS_WAIT, (int)buf, max_len, (int)res, 0);
}
-int _syscall_fs_respond(char __user *buf, int ret, int flags) {
+int _syscall_fs_respond(void __user *buf, int ret, int flags) {
return _syscall(_SYSCALL_FS_RESPOND, (int)buf, ret, flags, 0);
}
diff --git a/src/init/tar.c b/src/init/tar.c
index dfb0396..87236ae 100644
--- a/src/init/tar.c
+++ b/src/init/tar.c
@@ -5,7 +5,7 @@
#define BUF_SIZE 64
-static int tar_open(const char *path, int len, void *base, size_t base_len);
+static void *tar_open(const char *path, int len, void *base, size_t base_len);
static void tar_read(struct fs_wait_response *res, void *base, size_t base_len);
static int tar_size(void *sector);
static void *tar_find(const char *path, size_t path_len, void *base, size_t base_len);
@@ -18,6 +18,7 @@ static const char *root_fakemeta = ""; /* see comment in tar_open */
void tar_driver(void *base) {
static char buf[BUF_SIZE];
struct fs_wait_response res;
+ void *ptr;
while (!_syscall_fs_wait(buf, BUF_SIZE, &res)) {
switch (res.op) {
case VFSOP_OPEN:
@@ -25,7 +26,8 @@ void tar_driver(void *base) {
_syscall_fs_respond(NULL, -1, 0);
break;
}
- _syscall_fs_respond(NULL, tar_open(buf, res.len, base, ~0), 0);
+ ptr = tar_open(buf, res.len, base, ~0);
+ _syscall_fs_respond(ptr, ptr ? 0 : -1, 0);
break;
case VFSOP_READ:
@@ -40,10 +42,8 @@ void tar_driver(void *base) {
_syscall_exit(0);
}
-static int tar_open(const char *path, int len, void *base, size_t base_len) {
- void *ptr;
-
- if (len <= 0) return -1;
+static void *tar_open(const char *path, int len, void *base, size_t base_len) {
+ if (len <= 0) return NULL;
path += 1; // skip the leading slash
len -= 1;
@@ -51,12 +51,9 @@ static int tar_open(const char *path, int len, void *base, size_t base_len) {
* returning a fake one. this isn't a full entry because i'm currently too
* lazy to create a full one - thus, it has to be special cased in tar_read */
if (len == 0)
- return (int)root_fakemeta;
+ return (void*)root_fakemeta;
- ptr = tar_find(path, len, base, base_len);
- if (!ptr) return -1;
- // TODO this won't work if ptr > 0x80000000
- return (int)ptr;
+ return tar_find(path, len, base, base_len);
}
static void tar_read(struct fs_wait_response *res, void *base, size_t base_len) {
diff --git a/src/kernel/arch/i386/driver/fsroot.c b/src/kernel/arch/i386/driver/fsroot.c
index ccba0b6..e16dd80 100644
--- a/src/kernel/arch/i386/driver/fsroot.c
+++ b/src/kernel/arch/i386/driver/fsroot.c
@@ -45,6 +45,7 @@ static void req_preprocess(struct vfs_request *req, size_t max_len) {
static int handle(struct vfs_request *req) {
assert(req->caller);
+ int id = (int)req->id;
switch (req->type) {
case VFSOP_OPEN:
if (req->flags & OPEN_CREATE) return -1;
@@ -65,7 +66,7 @@ static int handle(struct vfs_request *req) {
return -1;
case VFSOP_READ:
- switch (req->id) {
+ switch (id) {
case HANDLE_ROOT: {
// TODO document directory read format
const char src[] =
@@ -106,7 +107,7 @@ static int handle(struct vfs_request *req) {
char buf[512];
uint32_t sector = req->offset / 512;
size_t len = min(req->output.len, 512 - ((size_t)req->offset & 511));
- ata_read(req->id - HANDLE_ATA, sector, buf);
+ ata_read(id - HANDLE_ATA, sector, buf);
virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
return len;
}
@@ -114,7 +115,7 @@ static int handle(struct vfs_request *req) {
}
case VFSOP_WRITE:
- switch (req->id) {
+ switch (id) {
case HANDLE_VGA: {
void *vga = (void*)0xB8000;
req_preprocess(req, 80*25*2);
diff --git a/src/kernel/handle.h b/src/kernel/handle.h
index 423ea88..4a5cab2 100644
--- a/src/kernel/handle.h
+++ b/src/kernel/handle.h
@@ -16,7 +16,7 @@ enum handle_type {
struct handle {
enum handle_type type;
struct vfs_backend *backend; // HANDLE_FILE | HANDLE_FS_FRONT
- int file_id; // only applicable to HANDLE_FILE
+ void __user *file_id; // only applicable to HANDLE_FILE
struct {
struct process *reader, *writer;
} pipe;
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index cb26b70..e639d1f 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -246,7 +246,7 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us
return -1; // dummy
}
-int _syscall_fs_respond(char __user *buf, int ret, int flags) {
+int _syscall_fs_respond(void __user *buf, int ret, int flags) {
struct vfs_request *req = process_current->handled_req;
if (!req) SYSCALL_RETURN(-1);
@@ -261,7 +261,7 @@ int _syscall_fs_respond(char __user *buf, int ret, int flags) {
}
process_current->handled_req = NULL;
- vfsreq_finish(req, ret, flags, process_current);
+ vfsreq_finish(req, buf, ret, flags, process_current);
SYSCALL_RETURN(0);
}
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index dfbd5cd..7c677cc 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -29,7 +29,9 @@ void vfsreq_create(struct vfs_request req_) {
vfs_backend_tryaccept(req->backend);
}
-void vfsreq_finish(struct vfs_request *req, int ret, int flags, struct process *handler) {
+void vfsreq_finish(struct vfs_request *req, char __user *stored, int ret,
+ int flags, struct process *handler)
+{
if (req->type == VFSOP_OPEN && ret >= 0) {
// TODO write tests for caller getting killed while opening a file
if (!req->caller) panic_unimplemented();
@@ -43,8 +45,7 @@ void vfsreq_finish(struct vfs_request *req, int ret, int flags, struct process *
struct handle *backing = handle_init(HANDLE_FILE);
backing->backend = req->backend;
req->backend->refcount++;
- // TODO file ids can only be 31bit long, so they can't be pointers
- backing->file_id = ret;
+ backing->file_id = stored;
req->caller->handles[handle] = backing;
} else {
/* delegating - moving a handle to the caller */
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index 7d36a5d..29f1ee9 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -47,7 +47,7 @@ struct vfs_request {
size_t len;
} output;
- int id; // handle.file.id
+ void __user *id; // handle.file.id
int offset;
int flags;
@@ -59,10 +59,10 @@ struct vfs_request {
/** Assigns the vfs_request to the caller, and dispatches the call */
void vfsreq_create(struct vfs_request);
-void vfsreq_finish(struct vfs_request*, int ret, int flags, struct process *handler);
+void vfsreq_finish(struct vfs_request*, char __user *stored, int ret, int flags, struct process *handler);
static inline void vfsreq_finish_short(struct vfs_request *req, int ret) {
- vfsreq_finish(req, ret, 0, NULL);
+ vfsreq_finish(req, (void __user *)ret, ret, 0, NULL);
}
/** Try to accept an enqueued request */
diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h
index b9be23d..c6d3c33 100644
--- a/src/shared/syscalls.h
+++ b/src/shared/syscalls.h
@@ -63,14 +63,14 @@ struct fs_wait_response {
enum vfs_operation op;
size_t len; // how much was put in *buf
size_t capacity; // how much output can be accepted by the caller
- int id; // file id (returned by the open handler, passed to other calls)
+ void __user *id; // file id (returned by the open handler, passed to other calls)
int offset;
int flags;
};
/** Blocks until an fs request is made.
* @return 0 if everything was successful */
int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __user *res);
-int _syscall_fs_respond(char __user *buf, int ret, int flags);
+int _syscall_fs_respond(void __user *buf, int ret, int flags);
/** Modifies the virtual address space.
*