summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/arch/amd64/driver/pata.c12
-rw-r--r--src/kernel/arch/amd64/driver/rtl8139.c5
-rw-r--r--src/kernel/arch/amd64/driver/serial.c6
-rw-r--r--src/kernel/arch/amd64/driver/time.c5
-rw-r--r--src/kernel/arch/amd64/driver/util.c6
-rw-r--r--src/kernel/arch/amd64/driver/util.h4
-rw-r--r--src/kernel/arch/amd64/driver/video.c14
-rw-r--r--src/kernel/syscalls.c23
-rw-r--r--src/kernel/vfs/procfs.c14
-rw-r--r--src/kernel/vfs/request.c36
-rw-r--r--src/kernel/vfs/request.h30
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;