[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 09/11] cdi/storage: Dateisystem proben
+ cdi/storage: Für jedes neue Storage-Gerät bzw. jede Partition wird
jetzt lio_probe_service() aufgerufen. Bei Erfolg wird ein Symlink in
dev:/fs/ angelegt. Als Dateiname für den Symlink wird der Volumename
des Dateisystems benutzt.
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/modules/cdi/lib/storage.c | 95 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 6 deletions(-)
diff --git a/src/modules/cdi/lib/storage.c b/src/modules/cdi/lib/storage.c
index 3a50e04..028280f 100644
--- a/src/modules/cdi/lib/storage.c
+++ b/src/modules/cdi/lib/storage.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <lostio.h>
+#include <io.h>
#include "cdi/storage.h"
#include "libpartition.h"
@@ -28,6 +29,20 @@ static int load_children(struct lio_resource* res);
int cdi_storage_read(struct cdi_storage_device* device, uint64_t pos,
size_t size, void* dest);
+static const char* service_name;
+
+static const char* get_service_name(struct cdi_storage_driver* drv)
+{
+ const char* name;
+
+ name = drv->drv.name;
+ if (!strcmp(name, "ahci-disk")) {
+ name = "ahci";
+ }
+
+ return name;
+}
+
/**
* Initialisiert die Datenstrukturen fuer einen Massenspeichertreiber
*/
@@ -36,7 +51,6 @@ void cdi_storage_driver_init(struct cdi_storage_driver* driver)
static struct lio_resource* first_res = NULL;
struct lio_resource* res;
struct lio_service* service;
- const char* service_name;
driver->drv.type = CDI_STORAGE;
cdi_driver_init((struct cdi_driver*) driver);
@@ -47,10 +61,7 @@ void cdi_storage_driver_init(struct cdi_storage_driver* driver)
return;
}
- service_name = driver->drv.name;
- if (!strcmp(service_name, "ahci-disk")) {
- service_name = "ahci";
- }
+ service_name = get_service_name(driver);
res = lio_resource_create(NULL);
res->browsable = 1;
@@ -231,6 +242,75 @@ int cdi_storage_write(struct cdi_storage_device* device, uint64_t pos,
return 0;
}
+
+struct fs_detection {
+ char* path;
+};
+
+static void fs_detection_thread(void* opaque)
+{
+ struct fs_detection* fsd = opaque;
+ lio_resource_t fd;
+ char* link_path;
+ char* target_path;
+ struct lio_probe_service_result probe_data;
+ int ret;
+
+ fd = lio_resource(fsd->path, false);
+ if (fd < 0) {
+ goto fail;
+ }
+
+ ret = lio_probe_service(fd, &probe_data);
+ if (ret < 0) {
+ goto fail;
+ }
+
+ asprintf(&link_path, "dev:/fs/%s", &probe_data.volname);
+ asprintf(&target_path, "%s|%s:/", fsd->path, &probe_data.service);
+
+ io_create_link(target_path, link_path, false);
+
+ free(link_path);
+ free(target_path);
+fail:
+ free(fsd->path);
+ free(fsd);
+}
+
+/**
+ * Versucht, einen dev:/-Link für das Dateisystem anlegen. Wenn es schiefgeht,
+ * ist nicht schlimm, dann fehlt der Link halt. Die eigentliche Erkennung des
+ * Dateisystems muss in einem anderen Thread ablaufen, weil der Kernel Requests
+ * an den Service schicken wird und wir nicht deadlocken wollen.
+ */
+static void queue_fs_detection(const char* service, const char* relpath)
+{
+ struct fs_detection* fsd;
+ int ret;
+
+ fsd = malloc(sizeof(*fsd));
+ if (fsd == NULL) {
+ return;
+ }
+
+ ret = asprintf(&fsd->path, "%s:/%s", service, relpath);
+ if (ret < 0) {
+ fsd->path = NULL;
+ goto fail;
+ }
+
+ ret = create_thread((uint32_t) &fs_detection_thread, fsd);
+ if (ret < 0) {
+ goto fail;
+ }
+ return;
+
+fail:
+ free(fsd->path);
+ free(fsd);
+}
+
/**
* Erstellt den Dateisystemknoten fuer ein Geraet.
*/
@@ -259,7 +339,6 @@ int lostio_mst_if_newdev(struct partition* part)
res->opaque = part;
lio_node_create(driver->osdep.root, res, path);
- free(path);
// Das erste ATAPI-Laufwerk wird ata:/cdrom
if (!has_cdrom && !strncmp(device->dev.name, "atapi", strlen("atapi"))) {
@@ -272,6 +351,10 @@ int lostio_mst_if_newdev(struct partition* part)
lio_node_create(driver->osdep.root, res, "cdrom");
}
+ // Versuchen, das Dateisystem zu erkennen
+ queue_fs_detection(service_name, path);
+
+ free(path);
return 0;
}
--
2.1.4