Commit a35acbe8 authored by Kevin Wolf's avatar Kevin Wolf

kernel2: LIO-Server-Operation pipe

+ kernel2: Passende Kernelimplementierung für die .pipe-Operation, die
  im Userspace schon implementiert ist: Für eine als Pipe markierte
  erstellt der Kernel beim Öffnen eine Pipe und gibt das eine Ende an
  den .pipe-Callback des Service.

  Das ist nicht das Interface, das wir am Ende haben wollen, aber es ist
  vervollständigt, was schon da ist, und erstmal das zu mergen und dann
  davon ausgehend weiterzubasteln macht das Rebasen des alten
  LIOv2-Codes auf master einfacher.
Signed-off-by: Kevin Wolf's avatarKevin Wolf <kevin@tyndur.org>
parent fb197022
......@@ -342,6 +342,28 @@ struct lio_stream* lio_open(struct lio_resource* res, int flags)
s->flags = flags;
s->eof = false;
// Wenn es sich um eine Pipe handelt, muessen wir entsprechende Ressourcen
// anlegen.
if (res->ispipe && res->tree->service->lio_ops.pipe) {
struct lio_stream* s_serv;
int ret;
ret = lio_pipe(&s, &s_serv, true);
if (ret < 0) {
return NULL;
}
if (!res->tree->service->lio_ops.pipe ||
res->tree->service->lio_ops.pipe(res, s_serv, s_serv->flags))
{
lio_close(s);
lio_close(s_serv);
return NULL;
}
return s;
}
if (res->tree->service->lio_ops.preopen &&
res->tree->service->lio_ops.preopen(s))
{
......
......@@ -127,6 +127,16 @@ struct lio_driver {
*/
int (*truncate)(struct lio_resource* res, uint64_t size);
/**
* Neue Pipe erstellen.
*
* Wird aufgerufen wenn jemand eine Ressource oeffnet, die als pipe
* gekennzeichnet wurde. Der Kernel erstellt dann 2 neue Ressourcen, die an
* den beiden Enden jeweils vertauscht als Lese- und Schreibressource
* eingetragen werden.
*/
int (*pipe)(struct lio_resource* res, struct lio_stream* pipe_end,
int flags);
};
......
......@@ -70,6 +70,8 @@ static int truncate(struct lio_resource* res, uint64_t size);
static int unlink(struct lio_resource* parent, const char* name);
static int probe(struct lio_service* serv, struct lio_stream* source,
struct lio_probe_service_result* probe_data);
static int pipe(struct lio_resource* res, struct lio_stream* pipe_end,
int flags);
struct lio_pending_op {
struct tree_item tinfo;
......@@ -149,6 +151,7 @@ int syscall_lio_srv_service_register(const char* name, size_t name_len,
service->lio_ops.make_symlink = make_symlink;
service->lio_ops.truncate = truncate;
service->lio_ops.unlink = unlink;
service->lio_ops.pipe = pipe;
service->lio_ops.sync = sync;
buf = mmc_automap_user(&mmc_current_context(),
......@@ -893,3 +896,31 @@ fail_alloc_page:
BUG_ON(--source->usp_refcount != 0);
return ret;
}
static int pipe(struct lio_resource* res, struct lio_stream* pipe_end,
int flags)
{
int result = 0;
struct lio_op_pipe* opi;
struct lio_service* serv = res->tree->service;
struct lio_userspace_service* s = serv->opaque;
struct lio_usp_stream* fd;
opi = (struct lio_op_pipe*) alloc_op(res, sizeof(*opi));
if (opi == NULL) {
return -EBADF;
}
fd = lio_usp_add_stream(s->provider->process, pipe_end);
opi->op.opcode = LIO_OP_PIPE;
opi->res = res->usp_id;
opi->opaque = res->opaque;
opi->pipe_end = fd->usp_id;
opi->flags = flags;
opi->op.flags |= LIO_OPFL_USP;
result = commit_op(res, &opi->op, NULL);
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment