diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/arch/amd64/driver/pata.c | 12 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/rtl8139.c | 5 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c | 6 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/time.c | 5 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/util.c | 6 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/util.h | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/video.c | 14 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 23 | ||||
-rw-r--r-- | src/kernel/vfs/procfs.c | 14 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 36 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 30 |
11 files changed, 72 insertions, 83 deletions
diff --git a/src/kernel/arch/amd64/driver/pata.c b/src/kernel/arch/amd64/driver/pata.c index cc6645d..59a43c3 100644 --- a/src/kernel/arch/amd64/driver/pata.c +++ b/src/kernel/arch/amd64/driver/pata.c @@ -47,10 +47,10 @@ static void accept(VfsReq *req) { vfsreq_finish_short(req, req_readcopy(req, list, len)); break; } - fs_normslice(&req->offset, &req->output.len, ata_size(id), false); - len = min(req->output.len, sizeof wbuf); + fs_normslice(&req->offset, &req->outlen, ata_size(id), false); + len = min(req->outlen, sizeof wbuf); ata_read(id, wbuf, len, req->offset); - pcpy_to(req->caller, req->output.buf, wbuf, len); + pcpy_to(req->caller, req->out, wbuf, len); vfsreq_finish_short(req, len); break; @@ -59,10 +59,10 @@ static void accept(VfsReq *req) { vfsreq_finish_short(req, -EACCES); break; } - fs_normslice(&req->offset, &req->input.len, ata_size(id), false); - len = min(req->input.len, sizeof wbuf); + fs_normslice(&req->offset, &req->uinlen, ata_size(id), false); + len = min(req->uinlen, sizeof wbuf); if (len != 0) { - len = pcpy_from(req->caller, wbuf, req->input.buf, len); + len = pcpy_from(req->caller, wbuf, req->uin, len); ata_write(id, wbuf, len, req->offset); } vfsreq_finish_short(req, len); diff --git a/src/kernel/arch/amd64/driver/rtl8139.c b/src/kernel/arch/amd64/driver/rtl8139.c index c952d8a..c739527 100644 --- a/src/kernel/arch/amd64/driver/rtl8139.c +++ b/src/kernel/arch/amd64/driver/rtl8139.c @@ -204,7 +204,7 @@ static void accept(VfsReq *req) { ret = req_readcopy(req, data, sizeof data); vfsreq_finish_short(req, ret); } else if (id == HandleNet) { - ret = try_rx(req->caller, req->output.buf, req->output.len); + ret = try_rx(req->caller, req->out, req->outlen); if (ret == WAIT) { reqqueue_join(&blocked_on, req); rx_irq_enable(true); @@ -218,8 +218,7 @@ static void accept(VfsReq *req) { break; case VFSOP_WRITE: if (id == HandleNet) { - assert(!req->input.kern); - vfsreq_finish_short(req, try_tx(req->caller, req->input.buf, req->input.len)); + vfsreq_finish_short(req, try_tx(req->caller, req->uin, req->uinlen)); } else { vfsreq_finish_short(req, -ENOSYS); } diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 76ec33b..bd3966d 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -77,7 +77,7 @@ static void accept(VfsReq *req) { bool valid; switch (req->type) { case VFSOP_OPEN: - valid = req->input.len == 0; + valid = req->kinlen == 0; vfsreq_finish_short(req, valid ? 0 : -1); break; case VFSOP_READ: @@ -87,8 +87,8 @@ static void accept(VfsReq *req) { case VFSOP_WRITE: if (req->caller && !req->flags) { char buf[4096]; - size_t len = min(sizeof buf, req->input.len); - len = pcpy_from(req->caller, buf, req->input.buf, len); + size_t len = min(sizeof buf, req->uinlen); + len = pcpy_from(req->caller, buf, req->uin, len); serial_write(buf, len); ret = len; } else { diff --git a/src/kernel/arch/amd64/driver/time.c b/src/kernel/arch/amd64/driver/time.c index f47cb74..5ec28b9 100644 --- a/src/kernel/arch/amd64/driver/time.c +++ b/src/kernel/arch/amd64/driver/time.c @@ -52,9 +52,8 @@ handle(VfsReq *req) case VFSOP_GETSIZE: return 8; case VFSOP_WRITE: - if (req->input.len == 8) { - assert(!req->input.kern); - if (pcpy_from(req->caller, u.buf, req->input.buf, sizeof u.buf) != sizeof(u.buf)) { + if (req->uinlen == 8) { + if (pcpy_from(req->caller, u.buf, req->uin, sizeof u.buf) != sizeof(u.buf)) { return -EGENERIC; } h->base = now - u.t; diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c index f02c4e2..c55e36e 100644 --- a/src/kernel/arch/amd64/driver/util.c +++ b/src/kernel/arch/amd64/driver/util.c @@ -7,10 +7,10 @@ int req_readcopy(VfsReq *req, const void *buf, size_t len) { if (!req->caller) return -1; assert(req->type == VFSOP_READ); - fs_normslice(&req->offset, &req->output.len, len, false); + fs_normslice(&req->offset, &req->outlen, len, false); /* read errors are ignored. TODO write a spec */ - pcpy_to(req->caller, req->output.buf, buf + req->offset, req->output.len); - return req->output.len; + pcpy_to(req->caller, req->out, buf + req->offset, req->outlen); + return req->outlen; } size_t ring_to_virt(ring_t *r, Proc *proc, void __user *ubuf, size_t max) { diff --git a/src/kernel/arch/amd64/driver/util.h b/src/kernel/arch/amd64/driver/util.h index 898875a..44d5728 100644 --- a/src/kernel/arch/amd64/driver/util.h +++ b/src/kernel/arch/amd64/driver/util.h @@ -11,8 +11,6 @@ int req_readcopy(VfsReq *req, const void *buf, size_t len); /* compare request path. path MUST be a static string */ #define reqpathcmp(req, path) _reqpathcmp(req, ""path"", sizeof(path) - 1) #define _reqpathcmp(req, path, plen) \ - (req->input.kern && \ - req->input.len == plen && \ - memcmp(req->input.buf_kern, path, plen) == 0) + (req->kin && req->kinlen == plen && memcmp(req->kin, path, plen) == 0) size_t ring_to_virt(ring_t *r, Proc *proc, void __user *ubuf, size_t max); diff --git a/src/kernel/arch/amd64/driver/video.c b/src/kernel/arch/amd64/driver/video.c index 5ce9a30..4ce1657 100644 --- a/src/kernel/arch/amd64/driver/video.c +++ b/src/kernel/arch/amd64/driver/video.c @@ -20,10 +20,10 @@ enum { static int handle(VfsReq *req) { switch (req->type) { case VFSOP_OPEN: - if (!req->input.kern) panic_invalid_state(); - if (req->input.len == 0) { + assert(req->kin != NULL); + if (req->kinlen == 0) { return H_ROOT; - } else if (req->input.len == namelen && !memcmp(req->input.buf_kern, namebuf, namelen)) { + } else if (req->kinlen == namelen && !memcmp(req->kin, namebuf, namelen)) { return H_FB; } else { return -1; @@ -40,10 +40,10 @@ static int handle(VfsReq *req) { if ((long __force)req->id != H_FB) { return -1; } - fs_normslice(&req->offset, &req->input.len, fb.size, false); - /* parial writes ignored */ - pcpy_from(req->caller, fb.b + req->offset, req->input.buf, req->input.len); - return req->input.len; + fs_normslice(&req->offset, &req->uinlen, fb.size, false); + /* partial writes ignored */ + pcpy_from(req->caller, fb.b + req->offset, req->uin, req->uinlen); + return req->uinlen; case VFSOP_GETSIZE: return fb.size; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index a6c807c..0b22770 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -96,11 +96,8 @@ hid_t _sys_open(const char __user *path, long len, int flags) { vfsreq_dispatchcopy((VfsReq) { .type = VFSOP_OPEN, - .input = { - .kern = true, - .buf_kern = path_buf, - .len = len, - }, + .kin = path_buf, + .kinlen = len, .caller = proc_cur, .backend = mount->backend, .flags = flags, @@ -198,12 +195,12 @@ static long simple_vfsop( .flags = flags, }; if (vfsop == VFSOP_READ) { - req.output.buf = buf; - req.output.len = len; + req.out = buf; + req.outlen = len; } if (vfsop == VFSOP_WRITE) { - req.input.buf = buf; - req.input.len = len; + req.uin = buf; + req.uinlen = len; } vfsreq_dispatchcopy(req); } else if (h->type == HANDLE_PIPE) { @@ -295,12 +292,8 @@ long _sys_fs_respond(hid_t hid, const void __user *buf, long ret, int flags) { if (ret > 0 && req->type == VFSOP_READ) { /* vfsreq_finish can't copy this data, as it doesn't know where the * buf argument came from */ - ret = min(ret, capped_cast32(req->output.len)); - ret = pcpy_bi( - req->caller, req->output.buf, - proc_cur, buf, - ret - ); + ret = min(ret, capped_cast32(req->outlen)); + ret = pcpy_bi(req->caller, req->out, proc_cur, buf, ret); } vfsreq_finish(req, (void __user *)buf, ret, flags, proc_cur); } diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c index ab57628..b0ebbe0 100644 --- a/src/kernel/vfs/procfs.c +++ b/src/kernel/vfs/procfs.c @@ -99,8 +99,8 @@ procfs_accept(VfsReq *req) assert(root->pns == root); if (req->type == VFSOP_OPEN) { - assert(req->input.kern); - h = openpath(req->input.buf_kern, req->input.len, root); + assert(req->kin); + h = openpath(req->kin, req->kinlen, root); vfsreq_finish_short(req, h ? (long)h : -ENOENT); return; } else if (req->type == VFSOP_CLOSE) { @@ -143,16 +143,16 @@ procfs_accept(VfsReq *req) return; } size_t res = pcpy_bi( - req->caller, req->output.buf, + req->caller, req->out, p, (__user void*)req->offset, - req->output.len + req->outlen ); vfsreq_finish_short(req, res); } else if (req->type == VFSOP_WRITE && (h->type == PhIntr || h->type == PhIntrDown)) { - size_t len = min(sizeof buf, req->input.len); - len = pcpy_from(req->caller, buf, req->input.buf, len); + size_t len = min(sizeof buf, req->uinlen); + len = pcpy_from(req->caller, buf, req->uin, len); if (h->type == PhIntr) { proc_intr(p, buf, len); } else { @@ -160,7 +160,7 @@ procfs_accept(VfsReq *req) proc_intr(it, buf, len); } } - vfsreq_finish_short(req, req->input.len); + vfsreq_finish_short(req, req->uinlen); } else { vfsreq_finish_short(req, -ENOSYS); } diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 69a007e..9b60080 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -100,11 +100,11 @@ vfsreq_finish(VfsReq *req, char __user *stored, long ret, int flags, Proc *handl } if (req->type == VFSOP_READ && ret >= 0) { - assert((size_t)ret <= req->output.len); + assert((size_t)ret <= req->outlen); } - if (req->input.kern) { - kfree(req->input.buf_kern); + if (req->kin) { + kfree(req->kin); } if (req->backend) { @@ -148,23 +148,21 @@ vfsback_useraccept(VfsReq *req) // it's a way to tell apart kernel and user backends apart // TODO check validity of memory regions somewhere else - if (req->input.buf) { - __user void *buf = handler->awaited_req.buf; - len = min(req->input.len, handler->awaited_req.max_len); - if (req->input.kern) { - pcpy_to(handler, buf, req->input.buf_kern, len); - } else { - len = pcpy_bi( - handler, buf, - req->caller, req->input.buf, len - ); - } + assert(!(req->kin && req->uin)); + if (req->kin) { + void __user *buf = handler->awaited_req.buf; + len = min(req->kinlen, handler->awaited_req.max_len); + pcpy_to(handler, buf, req->kin, len); + } else if (req->uin) { + void __user *buf = handler->awaited_req.buf; + len = min(req->uinlen, handler->awaited_req.max_len); + len = pcpy_bi(handler, buf, req->caller, req->uin, len); } else { - len = req->output.len; + len = req->outlen; } res.len = len; - res.capacity = req->output.len; + res.capacity = req->outlen; res.id = req->id; res.id2 = req->id2; res.offset = req->offset; @@ -263,16 +261,16 @@ reqqueue_ringreadall(ReqQueue *q, ring_t *r) /* read as much as the biggest request wants */ for (req = q->head; req; req = req->reqqueue_next) { - mlen = max(mlen, req->output.len); + mlen = max(mlen, req->outlen); } mlen = min(mlen, sizeof tmp); mlen = ring_get(r, tmp, mlen); while ((req = reqqueue_pop(q))) { - size_t ret = min(mlen, req->output.len); + size_t ret = min(mlen, req->outlen); assert(req->type == VFSOP_READ); if (req->caller) { - pcpy_to(req->caller, req->output.buf, tmp, ret); + pcpy_to(req->caller, req->out, tmp, ret); } vfsreq_finish_short(req, ret); } diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index d6facfd..484fdd7 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -37,20 +37,22 @@ struct VfsBackend { /* describes an in-progress vfs call */ struct VfsReq { enum vfs_op type; - struct { - bool kern; // if false: use .buf ; if true: use .buf_kern - union { - char __user *buf; - char *buf_kern; - }; - size_t len; - } input; - struct { - char __user *buf; - size_t len; - } output; - - void __user *id, *id2; // handle.file.id + + /* "kernel" input - an allocation owned by this struct, contains a NUL + * terminated string. the NUL isn't counted in the kinlen (for compat + * with old code). used for the path in open() */ + char *kin; + size_t kinlen; + + /* user inputs and outputs - just point to some buffer in the caller */ + char __user *uin; + size_t uinlen; + char __user *out; + size_t outlen; + + /* those correspond to handle.file.id + * id2 is used for duplex() */ + void __user *id, *id2; long offset; int flags; |