2 * Copyright (c) 2007 Antoine Kaufmann
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
17 #include "cdi/lists.h"
18 #include "cdi/cache.h"
20 #include <sys/types.h>
22 struct cdi_fs_filesystem
;
24 * Diese Struktur wird fuer jeden Dateisystemtreiber einmal erstellt
26 struct cdi_fs_driver
{
27 struct cdi_driver drv
;
30 * Neues Dateisystem initialisieren; Diese Funktion muss das root_object in
31 * der Dateisystemstruktur eintragen.
33 * @return Wenn das Dateisystem erfolgreich initialisiert wurde 1, sonst
34 * 0. Falls ein Fehler auftritt, muss das error-Feld in der
35 * Dateisystemstruktur gesetzt werden.
37 int (*fs_init
)(struct cdi_fs_filesystem
* fs
);
40 * Dateisystem deinitialisieren
42 * @return Wenn das Dateisystem erfolgreich deinitialisiert wurde 1, 0
43 * sonst. Falls ein Fehler auftritt, muss das error-Feld in der
44 * Dateisystemstruktur gesetzt werden.
46 int (*fs_destroy
)(struct cdi_fs_filesystem
* fs
);
51 * Diese Struktur wird fuer jedes eingebundene Dateisystem einmal erstellt.
53 struct cdi_fs_filesystem
{
55 /** Treiber, dem das Dateisystem gehoert */
56 struct cdi_fs_driver
* driver
;
58 /** Wurzelverzeichnis des Dateisystems */
59 struct cdi_fs_res
* root_res
;
62 * Falls ein gravierender Fehler auftritt, wird diese Fehlernummer gesetzt.
63 * Wenn sie != 0 ist wird das Dateisystem fuer Schreibzugriffe gesperrt.
68 * Das Dateisystem darf nicht geschrieben werden. Damit schlaegt unter
69 * anderem cdi_fs_write_data fehl.
74 * Hier sollte man wohl noch ein paar allgemeine Mount-Optionen oder
75 * sonstige Flags die das ganze Dateisystem betreffen.
79 /** OS-spezifisch: Deskriptor fuer den Datentraeger */
83 * Zeiger den der Treiber fuer eigene Daten zum Dateisystem benutzen kann
89 struct FsFileHandle
*data
;
93 // XXX Bei den Fehlernummern weiss ich noch nicht wirklich, was da notwendig
94 // ist, deshalb lasse ich das mal so stehen.
96 CDI_FS_ERROR_NONE
= 0,
97 // Fehler bei Eingabe/Ausgabeoperationen
99 // Operation nicht unterstuetzt
101 // Ressource nicht gefunden
103 // Beim lesen einer Datei wurde das Ende erreicht
108 CDI_FS_ERROR_INTERNAL
,
109 // Funktion noch nicht implementiert
110 CDI_FS_ERROR_NOT_IMPLEMENTED
,
111 // Unbekannter Fehler
116 * Der Stream stellt die Verbindung zwischen Aufrufer und Ressource dar.
118 struct cdi_fs_stream
{
120 struct cdi_fs_filesystem
* fs
;
122 // Betroffene Ressource
123 struct cdi_fs_res
* res
;
126 cdi_fs_error_t error
;
131 * Metaeigenschaften, die Ressourcen haben koennen
134 // R Groesse der Datei auslesen
136 // R Anzahl der Benutzten Dateisystemblocks (Irgendwo muesste man dann
137 // auch auf diese Blockgroesse zurgreiffen koennen)
138 CDI_FS_META_USEDBLOCKS
,
139 // R Optimale Blockgroesse mit der man auf die Datei zugreiffen sollte
140 CDI_FS_META_BESTBLOCKSZ
,
141 // R Interne Blockgroesse fuer USEDBLOCKS
143 // R Zeitpunkt an dem die Ressource erstellt wurde
144 CDI_FS_META_CREATETIME
,
145 // RW Letzter Zugriff auf die Ressource, auch lesend
146 CDI_FS_META_ACCESSTIME
,
147 // RW Letzte Veraenderung der Ressource
148 CDI_FS_META_CHANGETIME
153 * Siese Struktur stellt die Moeglichkeiten, die an einer Ressource zur
154 * Verfuegung stehen, dar.
156 struct cdi_fs_res_flags
{
157 // Ressource loeschen
159 // Ressource umbenennen
161 // Ressource verschieben
163 // Lesender Zugriff gestattet
165 // Schreibender Zugriff gestattet
167 // Ausfuehren gestattet
169 // Auflisten der Verzeichniseintraege gestattet
171 // Aufloesen des Links
175 // Anlegen eines Untereintrags
180 struct cdi_fs_res_res
;
181 struct cdi_fs_res_file
;
182 struct cdi_fs_res_dir
;
183 struct cdi_fs_res_link
;
184 struct cdi_fs_res_special
;
187 * Typ der eine Ressource, die zu der Klasse der Spezialdateien gehoert noch
198 * Konstanten fuer die einzelnen Klassen, um sie beim Funktionsaufruf zum
199 * zuweisen einer Klasse, identifizieren zu koennen.
206 } cdi_fs_res_class_t
;
209 * Dieser Typ dient dazu Ressourcen ganz oder teilweise zu sperren
218 * Das Dateisystem wird hier nur mit abstrakten Strukturen vom Typ
219 * cdi_fs_res dargestellt. Diese können beispielsweise sowohl regulaere
220 * Datei als auch Verzeichnis gleichzeitig darstellen.
222 * Weiter gilt, dass Ressourcen, die zu keiner Klasse gehoeren, nicht
226 // Name der Ressource
229 // Lock fuer diese Ressource
232 // Flag ob die Ressource geladen ist(1) oder nicht(0). Ist sie danicht,
233 // muss nur name und res definiert sein. In res darf nur load aufgerufen
237 // Referenzzaehler fuer Implementation. Muss beim erstellen der Ressource
238 // mit 0 initialisiert werden
242 // Verweis auf das Elternobjekt
243 struct cdi_fs_res
* parent
;
245 // Liste mit allfaelligen Kindobjekten
257 struct cdi_fs_res_flags flags
;
260 // Einzelne Klassen, zu denen die Ressourcen gehoeren kann, oder Null falls
261 // es zu einer Bestimmten Klasse nicht gehoert.
262 struct cdi_fs_res_res
* res
;
263 struct cdi_fs_res_file
* file
;
264 struct cdi_fs_res_dir
* dir
;
265 struct cdi_fs_res_link
* link
;
266 struct cdi_fs_res_special
* special
;
268 // Falls die Ressource zu einer Spezialklasse gehoert, wird hier angegeben,
269 // um welchen Typ von Spezialressource sie gehoert.
270 cdi_fs_res_type_t type
;
276 * Diese Dateisystemobjekte werden in Klassen eingeteilt, die das eigentliche
277 * "Verhalten" der Ressourcen steuern. Diese Klassen beinhalten die moeglichen
278 * Operationen und auch die Eigenschaften, die fuer die Ressourcen gelten,
279 * denen diese Klassen zugeordnet sind.
280 * Das Definieren der einzelnen Klassen uebernehmen dann die einzelnen Treiber.
282 * Die Flags koennen von der Ressource ueberschrieben werden. Es koennen
283 * allerdings nur Flags deaktiviert werden, die in der Klasse gesetzt sind un
285 * Das Selbe gilt auch fuer Klassen bei denen NULL-Pointer fuer Operationen
286 * eingetragen sind. Wenn zum Beispiel fuer write NULL eingetragen wird, dann
287 * bringt ein gesetztes write-Flag nichts.
291 * Diese Klasse gilt unabhaengig von den andern, also egal welche anderen
292 * Klassen angegeben sind, diese muss angegeben werden.
294 struct cdi_fs_res_res
{
298 * @param stream Stream
300 * @return Falls die Ressource erfolgreich geladen wurde 1, sonst 0
302 int (*load
)(struct cdi_fs_stream
* stream
);
305 * Ressource entladen; Darf von der Implementation nur aufgerufen werden,
306 * wenn keine geladenen Kind-Ressourcen existieren. Das gilt aber nur fuer
307 * Verzeichnisse. Wenn andere Kind-Eintraege existieren, werden die nicht
310 * @param stream Stream
312 * @return Falls die Ressource erfolgreich entladen wurde 1, sonst 0
314 int (*unload
)(struct cdi_fs_stream
* stream
);
317 * Ressource entfernen. Diese Funktion wird nur aufgerufen, wenn die
318 * Ressource keiner Klasse mehr zugewiesen ist.
320 * @param stream Stream
322 * @return Falls die Ressource erfolgreich geloescht wurde 1, sonst 0
324 int (*remove
)(struct cdi_fs_stream
* stream
);
327 * Namen einer Ressource aendern. Der Parameter name ist nur der
328 * Resourcennamen ohne Pfad. Zum verschieben wird move() benutzt.
330 * @param stream Stream
331 * @param name Neuer Name
333 * @return Falls die Ressource erfolgreich umbenennt wurde 1, sonst 0
335 int (*rename
)(struct cdi_fs_stream
* stream
, const char* name
);
338 * Ressource innerhalb des Dateisystems verschieben. Das Verschieben ueber
339 * Dateisystemgrenzen hinweg wird per kopieren und loeschen durchgefuehrt.
341 * @param stream Stream
342 * @param dest Pointer auf die Ressource, in die die Ressource verschoben
345 * @return Falls die Ressource erfolgreich verschoben wurde 1, sonst 0
347 int (*move
)(struct cdi_fs_stream
* stream
, struct cdi_fs_res
* dest
);
350 * Diese Ressource einer neuen Klasse zuweisen. Diese Funktion wird nur
351 * aufgerufen, wenn die Ressource nicht bereits dieser Klasse zugewiesen
354 * @param stream Stream
355 * @param class Konstante fuer den Typ der klasse, der die Ressource
356 * zugewiesen werden soll.
358 * @return 1 falls die Ressource erfolgreich der Klasse zugewiesen wurde, 0
361 int (*assign_class
)(struct cdi_fs_stream
* stream
,
362 cdi_fs_res_class_t
class);
365 * Diese Ressource aus einer Klasse entfernen. Diese Funktion wird nur
366 * aufgerufen, wenn die Ressource zu dieser Klasse gehoert.
368 * @param class Konstante fuer den Typ der klasse, aus der die Ressource
369 * entfernt werden soll.
371 * @return 1 falls die Ressource erfolgreich aus der Klasse entfernt wurde,
374 int (*remove_class
)(struct cdi_fs_stream
* stream
,
375 cdi_fs_res_class_t
class);
378 * Metaeigenschaft lesen
380 * @param stream Stream
381 * @param meta Konstante fuer die gewuenschte Metaeigenschaft
383 * @return Wert der Metaeigenschaft
385 int64_t (*meta_read
)(struct cdi_fs_stream
* stream
, cdi_fs_meta_t meta
);
388 * Metaeigenschaft schreiben
390 * @param stream Stream
391 * @param meta Konstante fuer die gewuenschte Metaeigenschaft
392 * @param value Neuen Wert fuer die Metaeigenschaft
394 * @return Falls die Metaeigenschaft erfolgreich geaendert wurde 1, sonst 0
396 int (*meta_write
)(struct cdi_fs_stream
* stream
, cdi_fs_meta_t meta
,
400 struct cdi_fs_res_file
{
401 // XXX (Aber wie geht das, wenn eine Datei nicht lesbar, aber ausfuehrbar
406 * Daten aus dieser Datei lesen. Wird nur aufgerufen, wenn es durch die
407 * Flags oder Berechtigungen nicht verhindert wird.
409 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
412 * @param stream Stream
413 * @param start Position von der an gelesen werden soll
414 * @param size Groesse der zu lesenden Daten
415 * @param buffer Puffer in den die Daten gelsen werden sollen
417 * @return Gelesene Bytes, oder 0 im Fehlerfall
419 size_t (*read
)(struct cdi_fs_stream
* stream
, uint64_t start
, size_t size
,
423 * Daten in diese Datei schreiben. Wird nur aufgerufen, wenn es durch die
424 * Flags oder Berechtigungen nicht verhindert wird.
426 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
429 * @param stream Stream
430 * @param start Position an die geschrieben werden soll
431 * @param size Groesse der zu schreibenden Daten
432 * @param buffer Puffer aus dem die Daten gelesen werden sollen
434 * @return Geschriebene Bytes oder 0 im Fehlerfall
436 size_t (*write
)(struct cdi_fs_stream
* stream
, uint64_t start
, size_t size
,
441 * Groesse der Datei anpassen. Diese Funktion kann sowohl fuers
442 * Vergroessern, als auch fuers Verkleinern benutzt werden.
444 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
447 * @param stream Stream
448 * @param size Neue Groesse der Datei
450 * @return 1 bei Erfolg, im Fehlerfall 0
452 int (*truncate
)(struct cdi_fs_stream
* stream
, uint64_t size
);
455 struct cdi_fs_res_dir
{
457 * Diese Funktion gibt einen Pointer auf die Liste mit den Eintraegen
458 * zurueck. Hier wird nicht einfach fix der Pointer in fs_res genommen,
459 * damit dort auch "versteckte" Eintraege vorhanden sein koennten. (Ich
460 * meine hier nicht irgend ein versteckt-Flag dass die Dateien vor dem
461 * Benutzer Verstecken soll, sondern eher von fuer den Internen gebrauch
462 * angelegten Eintraegen.
463 * Diese Liste muss nicht vom Aufrufer freigegeben werden, da einige
464 * Treiber hier direkt children aus fs_res benutzen, und andere dafuer eine
465 * eigene Liste erstellen, die sie intern abspeichern.
467 * @param stream Stream
469 * @return Pointer auf eine Liste mit den Untereintraegen vom Typ
472 cdi_list_t (*list
)(struct cdi_fs_stream
* stream
);
475 * Neue Ressource in der Aktuellen erstellen. Diese wird erstmal noch
476 * keiner Klasse zugewiesen. Diese Funktion wird mit einem NULL-Pointer als
477 * Ressource im Stream aufgerufen. Dieser NULL-Pointer muss bei
478 * Erfolgreichem Beenden durch einen Pointer auf die neue Ressource ersetzt
481 * @param stream Mit NULL-Pointer als Ressource
482 * @param name Name der neuen Ressource
483 * @param parent Ressource, der die neue Ressource als Kindressource
484 * zugeordnet werden soll.
486 * @return Falls die Ressource erfolgreich erstellt wurde 1, sonst 0
488 int (*create_child
)(struct cdi_fs_stream
* stream
,
489 const char* name
, struct cdi_fs_res
* parent
);
492 struct cdi_fs_res_link
{
494 * Diese Funktion liest den Pfad aus, auf den der Link zeigt
496 * @param stream Stream
498 * @return Pointer auf einen Buffer der den Pfad beinhaltet. Dieses Puffer
499 * darf vom Aufrufer nicht veraendert werden.
501 const char* (*read_link
)(struct cdi_fs_stream
* stream
);
504 * Aendert den Pfad auf den der Link zeigt
506 * @param stream Stream
507 * @param path Neuer Pfad
509 * @return Wenn der Link erfolgreich geschrieben wurde 1, 0 sonst
511 int (*write_link
)(struct cdi_fs_stream
* stream
, const char* path
);
514 struct cdi_fs_res_special
{
516 * Geraeteadresse der Spezialdatei Lesen
518 * @param stream Stream
519 * @param dev Pointer auf die Variable in der die Geraeteadresse
520 * gespeichert werden soll.
522 * @return Falls die Geraeteadresse erfolgreich gelesen wurde 1, sonst 0
524 int (*dev_read
)(struct cdi_fs_stream
* stream
, dev_t
* dev
);
527 * Geraeteadresse der Spezialdatei Aendern
529 * @param stream Stream
530 * @param dev Die neue Geraeteadresse
532 * @return Falls die Geraeteadresse erfolgreich geaendert wurde 1, sonst 0
534 int (*dev_write
)(struct cdi_fs_stream
* stream
, dev_t dev
);
540 * Die Berechtigunen werden mit Access controll lists, kurz ACLs verwaltet.
541 * Diese werden in Form von Listen gespeichert. Diese Listen enthalten
542 * eintraege von verschiedenen Typen.
546 CDI_FS_ACL_USER_NUMERIC
,
547 /// Ein Benutzername als String
548 CDI_FS_ACL_USER_STRING
,
550 CDI_FS_ACL_GROUP_NUMERIC
,
551 /// Ein Gruppenname als String
552 CDI_FS_ACL_GROUP_STRING
553 } cdi_fs_acl_entry_type_t
;
557 * Der Basiseintrag in einer ACL, von dem die anderen Typen der Eintraege
560 struct cdi_fs_acl_entry
{
561 // Typ des Eintrages, eine der obigen Konstanten
562 cdi_fs_acl_entry_type_t type
;
565 struct cdi_fs_res_flags flags
;
569 * Eintraege fuer die einzelnen Typen
571 struct cdi_fs_acl_entry_usr_num
{
572 struct cdi_fs_acl_entry entry
;
578 struct cdi_fs_acl_entry_usr_str
{
579 struct cdi_fs_acl_entry entry
;
585 struct cdi_fs_acl_entry_grp_num
{
586 struct cdi_fs_acl_entry entry
;
592 struct cdi_fs_acl_entry_grp_str
{
593 struct cdi_fs_acl_entry entry
;
601 void cdi_fs_driver_init(struct cdi_fs_driver
* driver
);
602 void cdi_fs_driver_destroy(struct cdi_fs_driver
* driver
);
603 void cdi_fs_driver_register(struct cdi_fs_driver
* driver
);
607 * Quelldateien fuer ein Dateisystem lesen
608 * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges?
610 * @param fs Pointer auf die FS-Struktur des Dateisystems
611 * @param start Position von der an gelesen werden soll
612 * @param size Groesse des zu lesenden Datenblocks
613 * @param buffer Puffer in dem die Daten abgelegt werden sollen
615 * @return die Anzahl der gelesenen Bytes
617 size_t cdi_fs_data_read(struct cdi_fs_filesystem
* fs
, uint64_t start
,
618 size_t size
, void* buffer
);
621 * Quellmedium eines Dateisystems beschreiben
622 * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges?
624 * @param fs Pointer auf die FS-Struktur des Dateisystems
625 * @param start Position an die geschrieben werden soll
626 * @param size Groesse des zu schreibenden Datenblocks
627 * @param buffer Puffer aus dem die Daten gelesen werden sollen
629 * @return die Anzahl der geschriebenen Bytes
631 size_t cdi_fs_data_write(struct cdi_fs_filesystem
* fs
, uint64_t start
,
632 size_t size
, const void* buffer
);