[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 02/11] kernel2: Neuer Syscall lio_probe_service



+ kernel2: Unterstützung für einen neuen Syscall, der zu einer gegebenen
  Ressource einen Service verwendet, der sie als Pipequelle benutzen
  kann.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/include/syscall_structs.h               |  6 +++++
 src/include/syscallno.h                     |  1 +
 src/kernel2/include/lostio/client.h         |  4 ++++
 src/kernel2/include/syscall.h               |  4 ++++
 src/kernel2/src/lostio/include/lostio_int.h |  4 ++++
 src/kernel2/src/lostio/tree.c               | 34 +++++++++++++++++++++++++++++
 src/kernel2/src/syscall.c                   |  1 +
 src/kernel2/src/syscalls/lostio.c           | 14 ++++++++++++
 src/modules/include/syscall.h               |  9 ++++++++
 src/modules/lib/syscalls/lostio.c           | 21 ++++++++++++++++++
 10 files changed, 98 insertions(+)

diff --git a/src/include/syscall_structs.h b/src/include/syscall_structs.h
index 0d5892c..3ba12b9 100644
--- a/src/include/syscall_structs.h
+++ b/src/include/syscall_structs.h
@@ -86,6 +86,12 @@ typedef int64_t lio_usp_resource_t;
 /** ID eines LostIO-Verzeichnisbaums */
 typedef int64_t lio_usp_tree_t;
 
+
+struct lio_probe_service_result {
+    char service[32];
+    char volname[32];
+} __attribute__((packed));
+
 /**
  * Beschreibt als Bitmaske den Modus, in dem ein Stream arbeiten soll.
  */
diff --git a/src/include/syscallno.h b/src/include/syscallno.h
index 47ab453..5fa5cf1 100644
--- a/src/include/syscallno.h
+++ b/src/include/syscallno.h
@@ -108,6 +108,7 @@
 #define SYSCALL_LIO_UNLINK      98
 #define SYSCALL_LIO_SYNC_ALL    99
 #define SYSCALL_LIO_PASS_FD     100
+#define SYSCALL_LIO_PROBE_SERVICE 101
 
 #define SYSCALL_LIO_SRV_SERVICE_REGISTER            110
 #define SYSCALL_LIO_SRV_TREE_SET_RING               111
diff --git a/src/kernel2/include/lostio/client.h b/src/kernel2/include/lostio/client.h
index c7b3795..8880e62 100644
--- a/src/kernel2/include/lostio/client.h
+++ b/src/kernel2/include/lostio/client.h
@@ -52,6 +52,10 @@ struct lio_dir_entry {
  */
 struct lio_resource* lio_get_resource(const char* path, int follow_symlinks);
 
+/** Service finden, der die Ressource als Pipequelle akzeptiert */
+int lio_probe_service(struct lio_resource* res,
+                      struct lio_probe_service_result* probe_data);
+
 /**
  * Oeffnet einen Stream zu einer Ressource
  *
diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h
index 9ff28f6..e23656e 100644
--- a/src/kernel2/include/syscall.h
+++ b/src/kernel2/include/syscall.h
@@ -253,6 +253,10 @@ int syscall_lio_unlink(lio_usp_resource_t* parent, const char* name,
 /// Alle Blocks rausschreiben, die sich im Cache befinden
 int syscall_lio_sync_all(int soft);
 
+/// Service finden, der die Ressource als Pipequelle akzeptiert
+int syscall_lio_probe_service(lio_usp_resource_t* res,
+                              struct lio_probe_service_result* probe_data);
+
 // LIO-Server
 /// Neuen lio-Service registrieren
 int syscall_lio_srv_service_register(const char* name, size_t name_len,
diff --git a/src/kernel2/src/lostio/include/lostio_int.h b/src/kernel2/src/lostio/include/lostio_int.h
index 33c055c..18518d6 100644
--- a/src/kernel2/src/lostio/include/lostio_int.h
+++ b/src/kernel2/src/lostio/include/lostio_int.h
@@ -50,6 +50,10 @@
 
 struct lio_service;
 struct lio_driver {
+    /** Prüfen, ob die Ressource als Pipequelle benutzt werden kann */
+    int (*probe)(struct lio_service* service, struct lio_stream* source,
+                 struct lio_probe_service_result* probe_data);
+
     /**
      * Root-Ressource eines Dateisystems laden, das root-Feld in tree ist also
      * noch NULL.
diff --git a/src/kernel2/src/lostio/tree.c b/src/kernel2/src/lostio/tree.c
index 3fcd2c7..fbc36fd 100644
--- a/src/kernel2/src/lostio/tree.c
+++ b/src/kernel2/src/lostio/tree.c
@@ -35,6 +35,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "kernel.h"
 #include "kprintf.h"
@@ -273,6 +274,39 @@ void lio_add_service(struct lio_service* service)
 }
 
 /**
+ * Service finden, der die Ressource als Pipequelle akzeptiert
+ */
+int lio_probe_service(struct lio_resource* res,
+                      struct lio_probe_service_result* probe_data)
+{
+    struct lio_service* service;
+    struct lio_stream *stream;
+    int ret;
+    int i;
+
+    stream = lio_open(res, LIO_READ);
+    if (stream == NULL) {
+        return -EIO;
+    }
+
+    for (i = 0; (service = list_get_element_at(lio_services, i)); i++) {
+        if (!service->lio_ops.probe) {
+            continue;
+        }
+
+        ret = service->lio_ops.probe(service, stream, probe_data);
+        if (ret == 0) {
+            goto out;
+        }
+    }
+
+    ret = -ENOENT;
+out:
+    lio_close(stream);
+    return ret;
+}
+
+/**
  * Neue Ressource initialisieren.
  * Vom Aufrufer initialisiert werden muessen (werden alle auf 0 initialisiert):
  *   - blocksize
diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c
index e0bd7bb..8d4da44 100644
--- a/src/kernel2/src/syscall.c
+++ b/src/kernel2/src/syscall.c
@@ -129,6 +129,7 @@ void syscall_init()
     syscall_register(SYSCALL_LIO_UNLINK, &syscall_lio_unlink, 3);
     syscall_register(SYSCALL_LIO_SYNC_ALL, &syscall_lio_sync_all, 0);
     syscall_register(SYSCALL_LIO_PASS_FD, &syscall_lio_pass_fd, 2);
+    syscall_register(SYSCALL_LIO_PROBE_SERVICE, &syscall_lio_probe_service, 2);
 
     syscall_register(SYSCALL_LIO_SRV_SERVICE_REGISTER,
         &syscall_lio_srv_service_register, 4);
diff --git a/src/kernel2/src/syscalls/lostio.c b/src/kernel2/src/syscalls/lostio.c
index 32efd4b..9fde44d 100644
--- a/src/kernel2/src/syscalls/lostio.c
+++ b/src/kernel2/src/syscalls/lostio.c
@@ -378,3 +378,17 @@ int syscall_lio_sync_all(int soft)
 {
     return lio_sync_all(soft);
 }
+
+/// Service finden, der die Ressource als Pipequelle akzeptiert
+int syscall_lio_probe_service(lio_usp_resource_t* usp_res,
+                              struct lio_probe_service_result* probe_data)
+{
+    struct lio_resource* res;
+
+    res = lio_usp_get_resource(*usp_res);
+    if (res == NULL) {
+        return -EINVAL;
+    }
+
+    return lio_probe_service(res, probe_data);
+}
diff --git a/src/modules/include/syscall.h b/src/modules/include/syscall.h
index 1528b12..7ab42a4 100644
--- a/src/modules/include/syscall.h
+++ b/src/modules/include/syscall.h
@@ -357,6 +357,15 @@ int lio_unlink(lio_resource_t parent, const char* name);
  */
 int lio_sync_all(void);
 
+/**
+ * Versucht einen Service zu finden, der die angegebene Ressource als
+ * Pipequelle verwenden kann (z.B. passendes Dateisystem für Image)
+ *
+ * @return 0 bei Erfolg, negativ im Fehlerfall
+ */
+int lio_probe_service(lio_resource_t res,
+                      struct lio_probe_service_result* ret);
+
 // LIO2-Server
 
 /**
diff --git a/src/modules/lib/syscalls/lostio.c b/src/modules/lib/syscalls/lostio.c
index c702084..81658b7 100644
--- a/src/modules/lib/syscalls/lostio.c
+++ b/src/modules/lib/syscalls/lostio.c
@@ -526,3 +526,24 @@ int lio_sync_all(void)
     return result;
 }
 
+/**
+ * Versucht einen Service zu finden, der die angegebene Ressource als
+ * Pipequelle verwenden kann (z.B. passendes Dateisystem für Image)
+ *
+ * @return 0 bei Erfolg, negativ im Fehlerfall
+ */
+int lio_probe_service(lio_resource_t res, struct lio_probe_service_result* ret)
+{
+    int result;
+
+    asm(
+        "pushl %3;"
+        "pushl %2;"
+        "mov %1, %%eax;"
+        "int $0x30;"
+        "add $0x8, %%esp;"
+    : "=a" (result) : "i" (SYSCALL_LIO_PROBE_SERVICE), "r" (&res), "r" (ret)
+    : "memory");
+
+    return result;
+}
-- 
2.1.4