[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 03/11] LIOv2: lio_probe_service für Userspaceservices
+ LIOv2: Userspace-LIO-Services können jetzt auch lio_probe_service
unterstützen
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/include/syscall_structs.h | 15 +++++++++
src/kernel2/src/syscalls/lio_server.c | 61 +++++++++++++++++++++++++++++++++++
src/modules/include/lostio.h | 6 ++++
src/modules/lib/lostio/lio_server.c | 16 +++++++++
4 files changed, 98 insertions(+)
diff --git a/src/include/syscall_structs.h b/src/include/syscall_structs.h
index 3ba12b9..d433779 100644
--- a/src/include/syscall_structs.h
+++ b/src/include/syscall_structs.h
@@ -303,6 +303,11 @@ enum lio_opcode {
* Stream der Ressource wird geschlossen
*/
LIO_OP_CLOSE = 15,
+
+ /**
+ * Prüfen, ob die Ressource als Pipequelle benutzt werden kann
+ */
+ LIO_OP_PROBE = 16,
};
/// Flags fuer Operationen
@@ -547,6 +552,16 @@ struct lio_op_sync {
void* opaque;
} __attribute__((packed));
+struct lio_op_probe {
+ struct lio_op op;
+
+ /// Stream fuer die Pipequelle
+ lio_usp_stream_t source;
+
+ /// Rückgabe: Informationen über Dateisystem
+ struct lio_probe_service_result* probe_data;
+} __attribute__((packed));
+
/// Flags fuer Server-Ressourcen
enum lio_server_flags {
diff --git a/src/kernel2/src/syscalls/lio_server.c b/src/kernel2/src/syscalls/lio_server.c
index 5127d7a..4b1b03d 100644
--- a/src/kernel2/src/syscalls/lio_server.c
+++ b/src/kernel2/src/syscalls/lio_server.c
@@ -68,6 +68,8 @@ static struct lio_resource* make_symlink(struct lio_resource* parent,
const char* name, const char* target);
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);
struct lio_pending_op {
struct tree_item tinfo;
@@ -136,6 +138,7 @@ int syscall_lio_srv_service_register(const char* name, size_t name_len,
// TODO: Ein paar is_userspace
service->name = strdup(name);
+ service->lio_ops.probe= probe;
service->lio_ops.load_root = load_root;
service->lio_ops.load_children = load_children;
service->lio_ops.close = close;
@@ -831,3 +834,61 @@ static int unlink(struct lio_resource* parent, const char* name)
return result;
}
+
+static int probe(struct lio_service* serv, struct lio_stream* source,
+ struct lio_probe_service_result* probe_data)
+{
+ struct lio_userspace_service* s = serv->opaque;
+ struct lio_probe_service_result* result;
+ struct lio_usp_stream* usp_fd;
+ struct lio_op_probe* op;
+ void* user_buf;
+ int ret;
+
+ if (s->provider == NULL) {
+ return -EBADF;
+ }
+
+ op = (struct lio_op_probe*) alloc_ring_op(&s->ring, sizeof(*op));
+
+ usp_fd = lio_usp_add_stream(s->provider->process, source);
+ if (!usp_fd) {
+ return -EBADF;
+ }
+
+ BUILD_BUG_ON(sizeof(*result) > PAGE_SIZE);
+ result = mmc_valloc(&mmc_current_context(), 1, MM_FLAGS_KERNEL_CODE);
+ if (result == NULL) {
+ ret = -ENOMEM;
+ goto fail_alloc_page;
+ }
+ memset(result, 0, PAGE_SIZE);
+
+ user_buf = mmc_automap_user(&s->provider->process->context,
+ &mmc_current_context(), result, 1,
+ MM_USER_START, MM_USER_END, MM_FLAGS_USER_DATA);
+ if (user_buf == NULL) {
+ ret = -ENOMEM;
+ goto fail_map;
+ }
+
+ op->op.opcode = LIO_OP_PROBE;
+ op->source = usp_fd->usp_id;
+ op->probe_data = user_buf;
+
+ ret = commit_ring_op(&s->ring, s->provider, &op->op, NULL);
+ if (ret == 0) {
+ strlcpy(result->service, serv->name, sizeof(result->service));
+ memcpy(probe_data, result, sizeof(*probe_data));
+ }
+
+ mmc_unmap(&s->provider->process->context, user_buf, 1);
+fail_map:
+ mmc_vfree(&mmc_current_context(), result, 1);
+fail_alloc_page:
+ /* Wir dürfen kein close() machen, der Kernel braucht den Stream noch */
+ source->usp_refcount++;
+ lio_usp_unref_stream(s->provider->process, usp_fd);
+ BUG_ON(--source->usp_refcount != 0);
+ return ret;
+}
diff --git a/src/modules/include/lostio.h b/src/modules/include/lostio.h
index 06dafec..9ad8c33 100644
--- a/src/modules/include/lostio.h
+++ b/src/modules/include/lostio.h
@@ -252,8 +252,14 @@ int64_t lio_compat_tell(io_resource_t* io_res);
*/
void lio_dispatch(void);
+struct lio_service;
struct lio_tree;
struct lio_driver {
+ /// Prüfen, ob die Ressource als Pipequelle benutzt werden kann
+ int (*probe)(struct lio_service* service,
+ lio_stream_t source,
+ struct lio_probe_service_result* probe_data);
+
/// Root-Ressource eines Baums laden
struct lio_resource* (*load_root)(struct lio_tree* tree);
diff --git a/src/modules/lib/lostio/lio_server.c b/src/modules/lib/lostio/lio_server.c
index 64206f5..2f3825d 100644
--- a/src/modules/lib/lostio/lio_server.c
+++ b/src/modules/lib/lostio/lio_server.c
@@ -50,6 +50,7 @@ static void tree_dispatch(struct lio_tree* tree);
static void process_op(struct lio_service* service, struct lio_op* op);
// Operationen
+static void op_probe(struct lio_service* service, struct lio_op* op);
static void op_load_root(struct lio_service* service, struct lio_op* op);
static void op_load_children(struct lio_service* service, struct lio_op* op);
static void op_close(struct lio_service* service, struct lio_op* op);
@@ -94,6 +95,10 @@ void lio_dispatch(void)
op_load_root(s, op);
break;
+ case LIO_OP_PROBE:
+ op_probe(s, op);
+ break;
+
default:
printf("lio_dispatch: Fehler, unerwarteter Opcode 0x%x\n",
op->opcode);
@@ -203,6 +208,17 @@ static void process_op(struct lio_service* service, struct lio_op* op)
op->flags &= ~LIO_OPFL_USP;
}
+static void op_probe(struct lio_service* service, struct lio_op* op)
+{
+ struct lio_op_probe* opr = (struct lio_op_probe*) op;
+ int ret = -EINVAL;
+
+ if (service->lio_ops.probe) {
+ ret = service->lio_ops.probe(service, opr->source, opr->probe_data);
+ }
+ lio_srv_op_done(op, ret, 0);
+}
+
static void op_load_root(struct lio_service* service, struct lio_op* op)
{
struct lio_op_load_root* olr = (struct lio_op_load_root*) op;
--
2.1.4