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

[Lost] [PATCH] + cdi/fs: Loeschen von Dateien und Verzeichnissen implementiert



---
 src/modules/cdi/include/cdi/fs.h   |    4 ++
 src/modules/cdi/lib/fs/fs.c        |    4 ++
 src/modules/cdi/lib/fs/lostio_if.c |   67 ++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/src/modules/cdi/include/cdi/fs.h b/src/modules/cdi/include/cdi/fs.h
index c3309f3..76a6999 100644
--- a/src/modules/cdi/include/cdi/fs.h
+++ b/src/modules/cdi/include/cdi/fs.h
@@ -361,6 +361,10 @@ struct cdi_fs_res_res {
      * Diese Ressource aus einer Klasse entfernen. Diese Funktion wird nur
      * aufgerufen, wenn die Ressource zu dieser Klasse gehoert.
      *
+     * Bei Verzeichnissen muss von der Implementation garantiert werden, dass
+     * diese Funktion nicht aufgerufen wird, solange das Verzeichnis noch
+     * Kindressourcen hat.
+     *
      * @param class Konstante fuer den Typ der klasse, aus der die Ressource
      *              entfernt werden soll.
      *
diff --git a/src/modules/cdi/lib/fs/fs.c b/src/modules/cdi/lib/fs/fs.c
index 70b0ddf..9ef41af 100644
--- a/src/modules/cdi/lib/fs/fs.c
+++ b/src/modules/cdi/lib/fs/fs.c
@@ -53,6 +53,7 @@ size_t lostio_read_handler(lostio_filehandle_t* fh, void* buf,
 size_t lostio_write_handler(lostio_filehandle_t* fh, size_t bs, size_t bc,
     void* data);
 int lostio_seek_handler(lostio_filehandle_t* fh, uint64_t offset, int origin);
+int lostio_unlink_handler(lostio_filehandle_t* fh, const char* name);
 size_t lostio_symlink_read_handler(lostio_filehandle_t* fh, void* buf,
     size_t bs, size_t bc);
 size_t lostio_symlink_write_handler(lostio_filehandle_t* fh, size_t bs,
@@ -66,6 +67,7 @@ typehandle_t cdi_typehandle = {
     .read = &lostio_read_handler,
     .write = &lostio_write_handler,
     .seek = &lostio_seek_handler,
+    .unlink = &lostio_unlink_handler,
     .close = NULL
 };
 
@@ -77,6 +79,7 @@ typehandle_t cdi_symlink_typehandle = {
     .read = &lostio_symlink_read_handler,
     .write = &lostio_symlink_write_handler,
     .seek = &lostio_seek_handler,
+    .unlink = &lostio_unlink_handler,
     .close = NULL
 };
 
@@ -111,6 +114,7 @@ void cdi_fs_driver_init(struct cdi_fs_driver* driver)
         typehandle->pre_open = &lostio_pre_open_handler;
         typehandle->not_found = &lostio_not_found_handler;
         typehandle->post_open = NULL;
+        typehandle->unlink = &lostio_unlink_handler;
 
         initialized = 1;
     }
diff --git a/src/modules/cdi/lib/fs/lostio_if.c b/src/modules/cdi/lib/fs/lostio_if.c
index 66d3f75..aced058 100644
--- a/src/modules/cdi/lib/fs/lostio_if.c
+++ b/src/modules/cdi/lib/fs/lostio_if.c
@@ -481,6 +481,73 @@ int lostio_seek_handler(lostio_filehandle_t* fh, uint64_t offset, int origin)
     return 0;
 }
 
+/**
+ * Alle Klassen von einer Ressource entfernen und sie dann loeschen.
+ */
+static int cdi_remove_res(struct cdi_fs_stream* stream)
+{
+    if (stream->res->file &&
+        !stream->res->res->remove_class(stream,CDI_FS_CLASS_FILE))
+    {
+        return -1;
+    }
+    if (stream->res->dir &&
+        !stream->res->res->remove_class(stream,CDI_FS_CLASS_DIR))
+    {
+        return -1;
+    }
+    if (stream->res->link &&
+        !stream->res->res->remove_class(stream,CDI_FS_CLASS_LINK))
+    {
+        return -1;
+    }
+
+    if (!stream->res->res->remove(stream)) {
+        return -1;
+    }
+
+    return 0;
+}
+
+int lostio_unlink_handler(lostio_filehandle_t* fh, const char* name)
+{
+    struct cdi_fs_stream* stream;
+    vfstree_node_t* node;
+    int i;
+    int result = 0;
+
+    p();
+
+    // Passender Kindknoten finden
+    for (i = 0; (node = list_get_element_at(fh->node->children, i)); i++) {
+        if (!strcmp(node->name, name)) {
+            break;
+        }
+    }
+    if (!node)  {
+        result = -1;
+    } else {
+        stream = node->data;
+
+        // Spezialfall: Es handelt sich um ein Verzeichnis. Das heisst es darf
+        // nur geloescht werden wenn es keine Kind-Eintraege mehr hat.
+        if (stream->res->dir && list_size(node->children)) {
+            result = -1;
+        } else {
+            // Sonst kann die Ressource geloescht werden.
+            result = cdi_remove_res(stream);
+        }
+    }
+
+    // Aus LostIO-Baum loeschen
+    if (!result && vfstree_delete_child(fh->node, name) == FALSE) {
+        result = -2;
+    }
+
+    v();
+    return result;
+}
+
 size_t lostio_symlink_read_handler(lostio_filehandle_t* fh, void* buf,
     size_t bs, size_t bc)
 {