From 1f7e7501660123ff8f26e8c65e75c2b282b933ef Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 8 Jul 2022 14:40:44 +0200 Subject: 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. --- src/kernel/arch/i386/driver/fsroot.c | 7 ++++--- src/kernel/handle.h | 2 +- src/kernel/syscalls.c | 4 ++-- src/kernel/vfs/request.c | 7 ++++--- src/kernel/vfs/request.h | 6 +++--- 5 files changed, 14 insertions(+), 12 deletions(-) (limited to 'src/kernel') 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 */ -- cgit v1.2.3