summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2022-07-08 14:40:44 +0200
committerdzwdz2022-07-08 14:40:44 +0200
commit1f7e7501660123ff8f26e8c65e75c2b282b933ef (patch)
tree5ba6cee10ac656b20dcabc9c9f7b079dcd952a45 /src/kernel
parente567ebeee5ea196128f15adcf30cec5dd1137f90 (diff)
syscall/fs_respond: get the file id from the buf argument
Previously, file ids could only be positive integers, so their range was 31 bits - not enough to represent the entire memory. Now, pointers can be safely used as file ids.
Diffstat (limited to 'src/kernel')
-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
5 files changed, 14 insertions, 12 deletions
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 */