libmeinos: +llist2
[meinos.git] / apps / include / cdi / fs.h
blobfcae3a5b33034eaf5c522e937b46d76a21dfcc39
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 <sys/types.h>
15 #include <stdio.h>
17 #include "cdi.h"
18 #include "cdi/lists.h"
19 #include "cdi/cache.h"
21 struct cdi_fs_filesystem;
22 /**
23 * Diese Struktur wird fuer jeden Dateisystemtreiber einmal erstellt
25 struct cdi_fs_driver {
26 struct cdi_driver drv;
28 /**
29 * Neues Dateisystem initialisieren; Diese Funktion muss das root_object in
30 * der Dateisystemstruktur eintragen.
32 * @return Wenn das Dateisystem erfolgreich initialisiert wurde 1, sonst
33 * 0. Falls ein Fehler auftritt, muss das error-Feld in der
34 * Dateisystemstruktur gesetzt werden.
36 int (*fs_init)(struct cdi_fs_filesystem* fs);
38 /**
39 * Dateisystem deinitialisieren
41 * @return Wenn das Dateisystem erfolgreich deinitialisiert wurde 1, 0
42 * sonst. Falls ein Fehler auftritt, muss das error-Feld in der
43 * Dateisystemstruktur gesetzt werden.
45 int (*fs_destroy)(struct cdi_fs_filesystem* fs);
47 /**
48 * Dateisystem mit dem Volume synchronisieren
50 * @return Wenn das Dateisystem erfolgreich mit dem Volume synchronisiert
51 * wurde 1, 0 sonst. Falls ein Fehler auftritt, muss das
52 * error-Feld in der Dateisystemstruktur gesetzt werden.
54 int (*fs_sync)(struct cdi_fs_filesystem* fs);
56 /// @note meinOS specific
57 cdi_list_t filesystems;
60 struct cdi_fs_res;
61 /**
62 * Diese Struktur wird fuer jedes eingebundene Dateisystem einmal erstellt.
64 struct cdi_fs_filesystem {
66 /** Treiber, dem das Dateisystem gehoert */
67 struct cdi_fs_driver* driver;
69 /** Wurzelverzeichnis des Dateisystems */
70 struct cdi_fs_res* root_res;
72 /**
73 * Falls ein gravierender Fehler auftritt, wird diese Fehlernummer gesetzt.
74 * Wenn sie != 0 ist wird das Dateisystem fuer Schreibzugriffe gesperrt.
76 int error;
78 /**
79 * Das Dateisystem darf nicht geschrieben werden. Damit schlaegt unter
80 * anderem cdi_fs_write_data fehl.
82 int read_only;
85 * Hier sollte man wohl noch ein paar allgemeine Mount-Optionen oder
86 * sonstige Flags die das ganze Dateisystem betreffen.
90 /** OS-spezifisch: Deskriptor fuer den Datentraeger */
91 FILE* device;
93 /**
94 * Zeiger den der Treiber fuer eigene Daten zum Dateisystem benutzen kann
96 void* opaque;
98 /// @note meinOS specific
99 int fsid;
100 int last_fh;
101 cdi_list_t files;
102 const char *mountpoint;
103 const char *data_dev;
104 int data_fh;
108 // XXX Bei den Fehlernummern weiss ich noch nicht wirklich, was da notwendig
109 // ist, deshalb lasse ich das mal so stehen.
110 typedef enum {
111 CDI_FS_ERROR_NONE = 0,
112 // Fehler bei Eingabe/Ausgabeoperationen
113 CDI_FS_ERROR_IO,
114 // Operation nicht unterstuetzt
115 CDI_FS_ERROR_ONS,
116 // Ressource nicht gefunden
117 CDI_FS_ERROR_RNF,
118 // Beim lesen einer Datei wurde das Ende erreicht
119 CDI_FS_ERROR_EOF,
121 CDI_FS_ERROR_RO,
122 // Interner Fehler
123 CDI_FS_ERROR_INTERNAL,
124 // Funktion noch nicht implementiert
125 CDI_FS_ERROR_NOT_IMPLEMENTED,
126 // Unbekannter Fehler
127 CDI_FS_ERROR_UNKNOWN
128 } cdi_fs_error_t;
131 * Der Stream stellt die Verbindung zwischen Aufrufer und Ressource dar.
133 struct cdi_fs_stream {
134 // Dateisystem
135 struct cdi_fs_filesystem* fs;
137 // Betroffene Ressource
138 struct cdi_fs_res* res;
140 // Fehlernummer
141 cdi_fs_error_t error;
146 * Metaeigenschaften, die Ressourcen haben koennen
148 typedef enum {
149 // R Groesse der Datei auslesen
150 CDI_FS_META_SIZE,
151 // R Anzahl der Benutzten Dateisystemblocks (Irgendwo muesste man dann
152 // auch auf diese Blockgroesse zurgreiffen koennen)
153 CDI_FS_META_USEDBLOCKS,
154 // R Optimale Blockgroesse mit der man auf die Datei zugreiffen sollte
155 CDI_FS_META_BESTBLOCKSZ,
156 // R Interne Blockgroesse fuer USEDBLOCKS
157 CDI_FS_META_BLOCKSZ,
158 // R Zeitpunkt an dem die Ressource erstellt wurde
159 CDI_FS_META_CREATETIME,
160 // RW Letzter Zugriff auf die Ressource, auch lesend
161 CDI_FS_META_ACCESSTIME,
162 // RW Letzte Veraenderung der Ressource
163 CDI_FS_META_CHANGETIME
164 } cdi_fs_meta_t;
168 * Siese Struktur stellt die Moeglichkeiten, die an einer Ressource zur
169 * Verfuegung stehen, dar.
171 struct cdi_fs_res_flags {
172 // Ressource loeschen
173 int remove;
174 // Ressource umbenennen
175 int rename;
176 // Ressource verschieben
177 int move;
178 // Lesender Zugriff gestattet
179 int read;
180 // Schreibender Zugriff gestattet
181 int write;
182 // Ausfuehren gestattet
183 int execute;
184 // Auflisten der Verzeichniseintraege gestattet
185 int browse;
186 // Aufloesen des Links
187 int read_link;
188 // Aendern des Links
189 int write_link;
190 // Anlegen eines Untereintrags
191 int create_child;
195 struct cdi_fs_res_res;
196 struct cdi_fs_res_file;
197 struct cdi_fs_res_dir;
198 struct cdi_fs_res_link;
199 struct cdi_fs_res_special;
202 * Typ der eine Ressource, die zu der Klasse der Spezialdateien gehoert noch
203 * genauer beschreibt
205 typedef enum {
206 CDI_FS_BLOCK,
207 CDI_FS_CHAR,
208 CDI_FS_FIFO,
209 CDI_FS_SOCKET
210 } cdi_fs_res_type_t;
213 * Konstanten fuer die einzelnen Klassen, um sie beim Funktionsaufruf zum
214 * zuweisen einer Klasse, identifizieren zu koennen.
216 typedef enum {
217 CDI_FS_CLASS_FILE,
218 CDI_FS_CLASS_DIR,
219 CDI_FS_CLASS_LINK,
220 CDI_FS_CLASS_SPECIAL
221 } cdi_fs_res_class_t;
224 * Dieser Typ dient dazu Ressourcen ganz oder teilweise zu sperren
226 typedef enum {
227 CDI_FS_LOCK_NONE,
228 CDI_FS_LOCK_WRITE,
229 CDI_FS_LOCK_ALL
230 } cdi_fs_lock_t;
233 * Das Dateisystem wird hier nur mit abstrakten Strukturen vom Typ
234 * cdi_fs_res dargestellt. Diese können beispielsweise sowohl regulaere
235 * Datei als auch Verzeichnis gleichzeitig darstellen.
237 * Weiter gilt, dass Ressourcen, die zu keiner Klasse gehoeren, nicht
238 * persistent sind.
240 struct cdi_fs_res {
241 // Name der Ressource
242 char* name;
244 // Lock fuer diese Ressource
245 cdi_fs_lock_t lock;
247 // Flag ob die Ressource geladen ist(1) oder nicht(0). Ist sie danicht,
248 // muss nur name und res definiert sein. In res darf nur load aufgerufen
249 // werden.
250 int loaded;
252 // Referenzzaehler fuer Implementation. Muss beim erstellen der Ressource
253 // mit 0 initialisiert werden
254 int stream_cnt;
257 // Verweis auf das Elternobjekt
258 struct cdi_fs_res* parent;
260 // Liste mit allfaelligen Kindobjekten
261 cdi_list_t children;
264 // Link-Pfad
265 char* link_path;
268 // ACL; siehe Unten
269 cdi_list_t acl;
271 // Flags
272 struct cdi_fs_res_flags flags;
275 // Einzelne Klassen, zu denen die Ressourcen gehoeren kann, oder Null falls
276 // es zu einer Bestimmten Klasse nicht gehoert.
277 struct cdi_fs_res_res* res;
278 struct cdi_fs_res_file* file;
279 struct cdi_fs_res_dir* dir;
280 struct cdi_fs_res_link* link;
281 struct cdi_fs_res_special* special;
283 // Falls die Ressource zu einer Spezialklasse gehoert, wird hier angegeben,
284 // um welchen Typ von Spezialressource sie gehoert.
285 cdi_fs_res_type_t type;
291 * Diese Dateisystemobjekte werden in Klassen eingeteilt, die das eigentliche
292 * "Verhalten" der Ressourcen steuern. Diese Klassen beinhalten die moeglichen
293 * Operationen und auch die Eigenschaften, die fuer die Ressourcen gelten,
294 * denen diese Klassen zugeordnet sind.
295 * Das Definieren der einzelnen Klassen uebernehmen dann die einzelnen Treiber.
297 * Die Flags koennen von der Ressource ueberschrieben werden. Es koennen
298 * allerdings nur Flags deaktiviert werden, die in der Klasse gesetzt sind un
299 * nicht umgekehrt.
300 * Das Selbe gilt auch fuer Klassen bei denen NULL-Pointer fuer Operationen
301 * eingetragen sind. Wenn zum Beispiel fuer write NULL eingetragen wird, dann
302 * bringt ein gesetztes write-Flag nichts.
306 * Diese Klasse gilt unabhaengig von den andern, also egal welche anderen
307 * Klassen angegeben sind, diese muss angegeben werden.
309 struct cdi_fs_res_res {
311 * Ressource laden
313 * @param stream Stream
315 * @return Falls die Ressource erfolgreich geladen wurde 1, sonst 0
317 int (*load)(struct cdi_fs_stream* stream);
320 * Ressource entladen; Darf von der Implementation nur aufgerufen werden,
321 * wenn keine geladenen Kind-Ressourcen existieren. Das gilt aber nur fuer
322 * Verzeichnisse. Wenn andere Kind-Eintraege existieren, werden die nicht
323 * beruecksichtigt.
325 * @param stream Stream
327 * @return Falls die Ressource erfolgreich entladen wurde 1, sonst 0
329 int (*unload)(struct cdi_fs_stream* stream);
332 * Ressource entfernen. Diese Funktion wird nur aufgerufen, wenn die
333 * Ressource keiner Klasse mehr zugewiesen ist.
335 * @param stream Stream
337 * @return Falls die Ressource erfolgreich geloescht wurde 1, sonst 0
339 int (*remove)(struct cdi_fs_stream* stream);
342 * Namen einer Ressource aendern. Der Parameter name ist nur der
343 * Resourcennamen ohne Pfad. Zum verschieben wird move() benutzt.
345 * @param stream Stream
346 * @param name Neuer Name
348 * @return Falls die Ressource erfolgreich umbenennt wurde 1, sonst 0
350 int (*rename)(struct cdi_fs_stream* stream, const char* name);
353 * Ressource innerhalb des Dateisystems verschieben. Das Verschieben ueber
354 * Dateisystemgrenzen hinweg wird per kopieren und loeschen durchgefuehrt.
356 * @param stream Stream
357 * @param dest Pointer auf die Ressource, in die die Ressource verschoben
358 * werden soll
360 * @return Falls die Ressource erfolgreich verschoben wurde 1, sonst 0
362 int (*move)(struct cdi_fs_stream* stream, struct cdi_fs_res* dest);
365 * Diese Ressource einer neuen Klasse zuweisen. Diese Funktion wird nur
366 * aufgerufen, wenn die Ressource nicht bereits dieser Klasse zugewiesen
367 * ist.
369 * @param stream Stream
370 * @param class Konstante fuer den Typ der klasse, der die Ressource
371 * zugewiesen werden soll.
373 * @return 1 falls die Ressource erfolgreich der Klasse zugewiesen wurde, 0
374 * sonst
376 int (*assign_class)(struct cdi_fs_stream* stream,
377 cdi_fs_res_class_t class);
380 * Diese Ressource aus einer Klasse entfernen. Diese Funktion wird nur
381 * aufgerufen, wenn die Ressource zu dieser Klasse gehoert.
383 * @param class Konstante fuer den Typ der klasse, aus der die Ressource
384 * entfernt werden soll.
386 * @return 1 falls die Ressource erfolgreich aus der Klasse entfernt wurde,
387 * 0 sonst
389 int (*remove_class)(struct cdi_fs_stream* stream,
390 cdi_fs_res_class_t class);
393 * Metaeigenschaft lesen
395 * @param stream Stream
396 * @param meta Konstante fuer die gewuenschte Metaeigenschaft
398 * @return Wert der Metaeigenschaft
400 int64_t (*meta_read)(struct cdi_fs_stream* stream, cdi_fs_meta_t meta);
403 * Metaeigenschaft schreiben
405 * @param stream Stream
406 * @param meta Konstante fuer die gewuenschte Metaeigenschaft
407 * @param value Neuen Wert fuer die Metaeigenschaft
409 * @return Falls die Metaeigenschaft erfolgreich geaendert wurde 1, sonst 0
411 int (*meta_write)(struct cdi_fs_stream* stream, cdi_fs_meta_t meta,
412 int64_t value);
415 struct cdi_fs_res_file {
416 // XXX (Aber wie geht das, wenn eine Datei nicht lesbar, aber ausfuehrbar
417 // sein soll?)
418 int executable;
421 * Daten aus dieser Datei lesen. Wird nur aufgerufen, wenn es durch die
422 * Flags oder Berechtigungen nicht verhindert wird.
424 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
425 * Device gesetzt.
427 * @param stream Stream
428 * @param start Position von der an gelesen werden soll
429 * @param size Groesse der zu lesenden Daten
430 * @param buffer Puffer in den die Daten gelsen werden sollen
432 * @return Gelesene Bytes, oder 0 im Fehlerfall
434 size_t (*read)(struct cdi_fs_stream* stream, uint64_t start, size_t size,
435 void* buffer);
438 * Daten in diese Datei schreiben. Wird nur aufgerufen, wenn es durch die
439 * Flags oder Berechtigungen nicht verhindert wird.
441 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
442 * Device gesetzt.
444 * @param stream Stream
445 * @param start Position an die geschrieben werden soll
446 * @param size Groesse der zu schreibenden Daten
447 * @param buffer Puffer aus dem die Daten gelesen werden sollen
449 * @return Geschriebene Bytes oder 0 im Fehlerfall
451 size_t (*write)(struct cdi_fs_stream* stream, uint64_t start, size_t size,
452 const void* buffer);
456 * Groesse der Datei anpassen. Diese Funktion kann sowohl fuers
457 * Vergroessern, als auch fuers Verkleinern benutzt werden.
459 * Im Fehlerfall wird je nach Fehler die Fehlernummer im Handle und die im
460 * Device gesetzt.
462 * @param stream Stream
463 * @param size Neue Groesse der Datei
465 * @return 1 bei Erfolg, im Fehlerfall 0
467 int (*truncate)(struct cdi_fs_stream* stream, uint64_t size);
470 struct cdi_fs_res_dir {
472 * Diese Funktion gibt einen Pointer auf die Liste mit den Eintraegen
473 * zurueck. Hier wird nicht einfach fix der Pointer in fs_res genommen,
474 * damit dort auch "versteckte" Eintraege vorhanden sein koennten. (Ich
475 * meine hier nicht irgend ein versteckt-Flag dass die Dateien vor dem
476 * Benutzer Verstecken soll, sondern eher von fuer den Internen gebrauch
477 * angelegten Eintraegen.
478 * Diese Liste muss nicht vom Aufrufer freigegeben werden, da einige
479 * Treiber hier direkt children aus fs_res benutzen, und andere dafuer eine
480 * eigene Liste erstellen, die sie intern abspeichern.
482 * @param stream Stream
484 * @return Pointer auf eine Liste mit den Untereintraegen vom Typ
485 * cdi_fs_res.
487 cdi_list_t (*list)(struct cdi_fs_stream* stream);
490 * Neue Ressource in der Aktuellen erstellen. Diese wird erstmal noch
491 * keiner Klasse zugewiesen. Diese Funktion wird mit einem NULL-Pointer als
492 * Ressource im Stream aufgerufen. Dieser NULL-Pointer muss bei
493 * Erfolgreichem Beenden durch einen Pointer auf die neue Ressource ersetzt
494 * worden sein.
496 * @param stream Mit NULL-Pointer als Ressource
497 * @param name Name der neuen Ressource
498 * @param parent Ressource, der die neue Ressource als Kindressource
499 * zugeordnet werden soll.
501 * @return Falls die Ressource erfolgreich erstellt wurde 1, sonst 0
503 int (*create_child)(struct cdi_fs_stream* stream,
504 const char* name, struct cdi_fs_res* parent);
507 struct cdi_fs_res_link {
509 * Diese Funktion liest den Pfad aus, auf den der Link zeigt
511 * @param stream Stream
513 * @return Pointer auf einen Buffer der den Pfad beinhaltet. Dieses Puffer
514 * darf vom Aufrufer nicht veraendert werden.
516 const char* (*read_link)(struct cdi_fs_stream* stream);
519 * Aendert den Pfad auf den der Link zeigt
521 * @param stream Stream
522 * @param path Neuer Pfad
524 * @return Wenn der Link erfolgreich geschrieben wurde 1, 0 sonst
526 int (*write_link)(struct cdi_fs_stream* stream, const char* path);
529 struct cdi_fs_res_special {
531 * Geraeteadresse der Spezialdatei Lesen
533 * @param stream Stream
534 * @param dev Pointer auf die Variable in der die Geraeteadresse
535 * gespeichert werden soll.
537 * @return Falls die Geraeteadresse erfolgreich gelesen wurde 1, sonst 0
539 int (*dev_read)(struct cdi_fs_stream* stream, dev_t* dev);
542 * Geraeteadresse der Spezialdatei Aendern
544 * @param stream Stream
545 * @param dev Die neue Geraeteadresse
547 * @return Falls die Geraeteadresse erfolgreich geaendert wurde 1, sonst 0
549 int (*dev_write)(struct cdi_fs_stream* stream, dev_t dev);
555 * Die Berechtigunen werden mit Access controll lists, kurz ACLs verwaltet.
556 * Diese werden in Form von Listen gespeichert. Diese Listen enthalten
557 * eintraege von verschiedenen Typen.
559 typedef enum {
560 /// Eine UID
561 CDI_FS_ACL_USER_NUMERIC,
562 /// Ein Benutzername als String
563 CDI_FS_ACL_USER_STRING,
564 /// Eine GID
565 CDI_FS_ACL_GROUP_NUMERIC,
566 /// Ein Gruppenname als String
567 CDI_FS_ACL_GROUP_STRING
568 } cdi_fs_acl_entry_type_t;
572 * Der Basiseintrag in einer ACL, von dem die anderen Typen der Eintraege
573 * abgeleitet sind.
575 struct cdi_fs_acl_entry {
576 // Typ des Eintrages, eine der obigen Konstanten
577 cdi_fs_acl_entry_type_t type;
579 // Flags
580 struct cdi_fs_res_flags flags;
584 * Eintraege fuer die einzelnen Typen
586 struct cdi_fs_acl_entry_usr_num {
587 struct cdi_fs_acl_entry entry;
589 // Benutzer-ID
590 uid_t user_id;
593 struct cdi_fs_acl_entry_usr_str {
594 struct cdi_fs_acl_entry entry;
596 // Benutzername
597 char* user_name;
600 struct cdi_fs_acl_entry_grp_num {
601 struct cdi_fs_acl_entry entry;
603 // Gruppen-ID
604 gid_t group_id;
607 struct cdi_fs_acl_entry_grp_str {
608 struct cdi_fs_acl_entry entry;
610 // Gruppenname
611 char* group_name;
616 void cdi_fs_driver_init(struct cdi_fs_driver* driver);
617 void cdi_fs_driver_destroy(struct cdi_fs_driver* driver);
618 void cdi_fs_driver_register(struct cdi_fs_driver* driver);
622 * Quelldateien fuer ein Dateisystem lesen
623 * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges?
625 * @param fs Pointer auf die FS-Struktur des Dateisystems
626 * @param start Position von der an gelesen werden soll
627 * @param size Groesse des zu lesenden Datenblocks
628 * @param buffer Puffer in dem die Daten abgelegt werden sollen
630 * @return die Anzahl der gelesenen Bytes
632 size_t cdi_fs_data_read(struct cdi_fs_filesystem* fs, uint64_t start,
633 size_t size, void* buffer);
636 * Quellmedium eines Dateisystems beschreiben
637 * XXX Brauchen wir hier auch noch irgendwas errno-Maessiges?
639 * @param fs Pointer auf die FS-Struktur des Dateisystems
640 * @param start Position an die geschrieben werden soll
641 * @param size Groesse des zu schreibenden Datenblocks
642 * @param buffer Puffer aus dem die Daten gelesen werden sollen
644 * @return die Anzahl der geschriebenen Bytes
646 size_t cdi_fs_data_write(struct cdi_fs_filesystem* fs, uint64_t start,
647 size_t size, const void* buffer);
650 #endif