Added iso9660 driver (not yet working).
[planlOS.git] / system / modules / include / cdi / fs.h
blob764ddbb03e8c5c1d49cec550e35306a4220b744a
1 /*
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.
9 */
11 #ifndef _CDI_FS_
12 #define _CDI_FS_
14 #include <stdio.h>
16 #include "cdi.h"
17 #include "cdi/lists.h"
18 #include "cdi/cache.h"
20 #include <sys/types.h>
22 struct cdi_fs_filesystem;
23 /**
24 * Diese Struktur wird fuer jeden Dateisystemtreiber einmal erstellt
26 struct cdi_fs_driver {
27 struct cdi_driver drv;
29 /**
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);
39 /**
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);
49 struct cdi_fs_res;
50 /**
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;
61 /**
62 * Falls ein gravierender Fehler auftritt, wird diese Fehlernummer gesetzt.
63 * Wenn sie != 0 ist wird das Dateisystem fuer Schreibzugriffe gesperrt.
65 int error;
67 /**
68 * Das Dateisystem darf nicht geschrieben werden. Damit schlaegt unter
69 * anderem cdi_fs_write_data fehl.
71 int read_only;
73 /*
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 */
80 FILE* device;
82 /**
83 * Zeiger den der Treiber fuer eigene Daten zum Dateisystem benutzen kann
85 void* opaque;
87 // planlOS
88 cdi_list_t files;
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.
95 typedef enum {
96 CDI_FS_ERROR_NONE = 0,
97 // Fehler bei Eingabe/Ausgabeoperationen
98 CDI_FS_ERROR_IO,
99 // Operation nicht unterstuetzt
100 CDI_FS_ERROR_ONS,
101 // Ressource nicht gefunden
102 CDI_FS_ERROR_RNF,
103 // Beim lesen einer Datei wurde das Ende erreicht
104 CDI_FS_ERROR_EOF,
105 //n
106 CDI_FS_ERROR_RO,
107 // Interner Fehler
108 CDI_FS_ERROR_INTERNAL,
109 // Funktion noch nicht implementiert
110 CDI_FS_ERROR_NOT_IMPLEMENTED,
111 // Unbekannter Fehler
112 CDI_FS_ERROR_UNKNOWN
113 } cdi_fs_error_t;
116 * Der Stream stellt die Verbindung zwischen Aufrufer und Ressource dar.
118 struct cdi_fs_stream {
119 // Dateisystem
120 struct cdi_fs_filesystem* fs;
122 // Betroffene Ressource
123 struct cdi_fs_res* res;
125 // Fehlernummer
126 cdi_fs_error_t error;
131 * Metaeigenschaften, die Ressourcen haben koennen
133 typedef enum {
134 // R Groesse der Datei auslesen
135 CDI_FS_META_SIZE,
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
142 CDI_FS_META_BLOCKSZ,
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
149 } cdi_fs_meta_t;
153 * Siese Struktur stellt die Moeglichkeiten, die an einer Ressource zur
154 * Verfuegung stehen, dar.
156 struct cdi_fs_res_flags {
157 // Ressource loeschen
158 int remove;
159 // Ressource umbenennen
160 int rename;
161 // Ressource verschieben
162 int move;
163 // Lesender Zugriff gestattet
164 int read;
165 // Schreibender Zugriff gestattet
166 int write;
167 // Ausfuehren gestattet
168 int execute;
169 // Auflisten der Verzeichniseintraege gestattet
170 int browse;
171 // Aufloesen des Links
172 int read_link;
173 // Aendern des Links
174 int write_link;
175 // Anlegen eines Untereintrags
176 int create_child;
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
188 * genauer beschreibt
190 typedef enum {
191 CDI_FS_BLOCK,
192 CDI_FS_CHAR,
193 CDI_FS_FIFO,
194 CDI_FS_SOCKET
195 } cdi_fs_res_type_t;
198 * Konstanten fuer die einzelnen Klassen, um sie beim Funktionsaufruf zum
199 * zuweisen einer Klasse, identifizieren zu koennen.
201 typedef enum {
202 CDI_FS_CLASS_FILE,
203 CDI_FS_CLASS_DIR,
204 CDI_FS_CLASS_LINK,
205 CDI_FS_CLASS_SPECIAL
206 } cdi_fs_res_class_t;
209 * Dieser Typ dient dazu Ressourcen ganz oder teilweise zu sperren
211 typedef enum {
212 CDI_FS_LOCK_NONE,
213 CDI_FS_LOCK_WRITE,
214 CDI_FS_LOCK_ALL
215 } cdi_fs_lock_t;
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
223 * persistent sind.
225 struct cdi_fs_res {
226 // Name der Ressource
227 char* name;
229 // Lock fuer diese Ressource
230 cdi_fs_lock_t lock;
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
234 // werden.
235 int loaded;
237 // Referenzzaehler fuer Implementation. Muss beim erstellen der Ressource
238 // mit 0 initialisiert werden
239 int stream_cnt;
242 // Verweis auf das Elternobjekt
243 struct cdi_fs_res* parent;
245 // Liste mit allfaelligen Kindobjekten
246 cdi_list_t children;
249 // Link-Pfad
250 char* link_path;
253 // ACL; siehe Unten
254 cdi_list_t acl;
256 // Flags
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
284 * nicht umgekehrt.
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 {
296 * Ressource laden
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
308 * beruecksichtigt.
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
343 * werden soll
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
352 * ist.
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
359 * sonst
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,
372 * 0 sonst
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,
397 int64_t value);
400 struct cdi_fs_res_file {
401 // XXX (Aber wie geht das, wenn eine Datei nicht lesbar, aber ausfuehrbar
402 // sein soll?)
403 int executable;
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
410 * Device gesetzt.
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,
420 void* buffer);
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
427 * Device gesetzt.
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,
437 const void* buffer);
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
445 * Device gesetzt.
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
470 * cdi_fs_res.
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
479 * worden sein.
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.
544 typedef enum {
545 /// Eine UID
546 CDI_FS_ACL_USER_NUMERIC,
547 /// Ein Benutzername als String
548 CDI_FS_ACL_USER_STRING,
549 /// Eine GID
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
558 * abgeleitet sind.
560 struct cdi_fs_acl_entry {
561 // Typ des Eintrages, eine der obigen Konstanten
562 cdi_fs_acl_entry_type_t type;
564 // Flags
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;
574 // Benutzer-ID
575 uid_t user_id;
578 struct cdi_fs_acl_entry_usr_str {
579 struct cdi_fs_acl_entry entry;
581 // Benutzername
582 char* user_name;
585 struct cdi_fs_acl_entry_grp_num {
586 struct cdi_fs_acl_entry entry;
588 // Gruppen-ID
589 gid_t group_id;
592 struct cdi_fs_acl_entry_grp_str {
593 struct cdi_fs_acl_entry entry;
595 // Gruppenname
596 char* group_name;
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);
635 #endif