====== Die Dateisystem-Sammlung ====== Sechs Units, die **fremde Dateisysteme lesen** — jedes in einer eigenen Unit, weil sie sich im Aufbau grundlegend unterscheiden. Dazu eine siebte, die die Frage davor beantwortet: wo auf dem Datenträger fängt das Dateisystem überhaupt an? → [[lyx_-_programmiersprache:units:fs|std.fs (Datei-I/O)]] · [[lyx_-_programmiersprache:units|Units-Übersicht]] · [[lyx_-_programmiersprache:guides:dateisysteme-lesen|Guide: Fremde Dateisysteme lesen]] · [[lyxos:iofs|Lyx OS: IOFS]] ---- ===== Die Units ===== ^ Unit ^ Liest ^ Aufbauprinzip ^ Umfang ^ | [[lyx_-_programmiersprache:units:fs:part|std.fs.part]] | MBR und GPT | Partitionstabelle — **kein** Dateisystem | 12 Funktionen | | [[lyx_-_programmiersprache:units:fs:fat|std.fs.fat]] | FAT12/16/32 | Clusterkette in einer Zuordnungstabelle | 21 Funktionen | | [[lyx_-_programmiersprache:units:fs:exfat|std.fs.exfat]] | exFAT | Clusterkette, aber ganz andere Strukturen als FAT32 | 15 Funktionen | | [[lyx_-_programmiersprache:units:fs:ext4|std.fs.ext4]] | ext2, ext3, ext4 | **Inode-Tabelle** plus Extent-Bäume | 13 Funktionen | | [[lyx_-_programmiersprache:units:fs:ntfs|std.fs.ntfs]] | NTFS | **Master File Table**, Attribute, Datenläufe | 14 Funktionen | | [[lyx_-_programmiersprache:units:fs:squashfs|std.fs.squashfs]] | SquashFS 4.0 | **komprimierte** Metadatenblöcke, Inode-Referenzen | 20 Funktionen | **Alle sechs lesen nur.** Schreiben verlangt bei jedem Format mehr als das Spiegelbild des Lesens: bei FAT die Pflege beider FAT-Kopien, bei exFAT zusätzlich Belegungsbitmap und Prüfsummen, bei ext3/ext4 und NTFS die Journalführung — und ein Schreiber, der das Journal nicht führt, macht aus einem Absturz einen Datenverlust. SquashFS ist von Haus aus nur lesbar; ein Abbild zu ändern hieße, es neu zu bauen (''mksquashfs''). ---- ===== Das gemeinsame Muster ===== Alle Units arbeiten gleich: **offener Deskriptor plus Byte-Versatz**. Ob dahinter eine Abbilddatei, eine Partition oder ein ganzes Gerät liegt, ist ihnen gleich. var fd: int64 := open("/dev/sda"c, 0, 0); var t: PartTable := PartScan(fd, 512); // wo faengt was an? var off: int64 := PartByteOffset(t, 0); // Byte-Versatz der 1. Partition var vol: Ext4Volume := Ext4Mount(fd, off); // dort einhaengen Damit ist ''PartByteOffset'' das Bindeglied: sein Rückgabewert ist genau das, was ''FatMount'', ''ExfatMount'', ''Ext4Mount'', ''NtfsMount'' und ''SquashMount'' als zweites Argument erwarten. ^ Schritt ^ FAT ^ exFAT ^ ext4 ^ NTFS ^ SquashFS ^ | Einhängen | ''FatMount'' | ''ExfatMount'' | ''Ext4Mount'' | ''NtfsMount'' | ''SquashMount'' | | Verzeichnis öffnen | ''FatDirOpen'' | ''ExfatDirOpen'' | ''Ext4DirOpen'' | (über ''NtfsFindInDir'') | ''SquashDirOpen'' | | Eintrag holen | ''FatDirNext'' | ''ExfatDirNext'' | ''Ext4DirNext'' | ''NtfsDirCount'' | ''SquashDirNext'' | | Pfad auflösen | ''FatFindPath'' | ''ExfatFindPath'' | ''Ext4FindPath'' | ''NtfsFindPath'' | ''SquashFindPath'' | | Datei lesen | ''FatReadFile'' | ''ExfatReadFile'' | ''Ext4ReadFile'' | ''NtfsReadFile'' | ''SquashReadFile'' | Die Namen folgen demselben Schnitt — der **Aufbau dahinter** ist jedes Mal ein anderer, und genau deshalb gibt es keine gemeinsame Oberschicht: eine Schnittstelle, die FAT-Clusterketten und NTFS-Datenläufe unter einen Hut zwängt, verliert bei beiden die Eigenheiten, auf die es beim Lesen ankommt. ---- ===== Warum je eine eigene Unit ===== * **exFAT ist kein FAT32.** Es teilt den Namen und die Grundidee — Cluster, eine Zuordnungstabelle —, aber kaum ein Strukturfeld. Sektor- und Clustergröße stehen als **Zweierpotenz-Exponent** da, nicht als Zahl; es gibt keine feste Wurzel und keine 8.3-Namen; und zusammenhängende Dateien tragen ''NoFatChain'' und stehen **gar nicht** in der Tabelle. * **ext4 kennt Inodes.** Der Verzeichniseintrag trägt nur einen Namen und eine Nummer, alles Weitere steht im Inode — Größe, Rechte, Zeiten und der Weg zu den Blöcken. * **NTFS hat die Master File Table.** Statt einer Tabelle, die Blöcke aufzählt, ist dort jede Datei ein Satz aus Attributen; die Daten sind nur eines davon (''$DATA''), und bei kleinen Dateien stehen sie **mitten im Satz**. * **SquashFS ist komprimiert.** Es gibt keine Cluster und keine Zuordnungstabelle; eine Inode-Referenz ist keine Nummer, sondern ein Paar aus Blockadresse und Versatz im entpackten Block. ---- ===== Grenzen im Überblick ===== ^ Unit ^ Nicht enthalten — und im Zweifel **gemeldet**, nicht geraten ^ | ''std.fs.part'' | Nur MBR und GPT; kein APM, keine BSD-Disklabels. Höchstens ''PART_MAX'' = 128 Einträge, damit ein beschädigtes Eintragsfeld nicht in eine unbegrenzte Belegung läuft | | ''std.fs.ext4'' | Die **doppelt indirekte** Blockzuordnung (jenseits von 12 + n + n² Blöcken, bei 4-KiB-Blöcken erst über 4 GiB); still das Falsche zu liefern wäre schlimmer als die Meldung | | ''std.fs.ntfs'' | Komprimierte und verschlüsselte Dateien | | ''std.fs.squashfs'' | Erweiterte Attribute, Gerätedateien, Sockets. Welche Kompressionsverfahren wirklich gehen, sagt ''SquashCompressionUnterstuetzt'' | ---- ===== Prüfstand ===== Jede Unit hat einen eigenen Testlauf gegen **echte Abbilder**, die im Test erzeugt werden: ^ Unit ^ Test ^ Prüfungen ^ | ''std.fs.fat'' | ''tests/fat_test.sh'' | 94 | | ''std.fs.exfat'' | ''tests/exfat_test.sh'' | 42 | | ''std.fs.ext4'' | ''tests/ext4_test.sh'' | 53 | | ''std.fs.ntfs'' | ''tests/ntfs_test.sh'' | 33 | | ''std.fs.part'' | ''tests/part_test.sh'' | 47 | | ''std.fs.squashfs'' | ''tests/squashfs_test.sh'' | 37 | Letzte Aktualisierung: 2026-09-05 — Seite neu angelegt; erhoben aus ''std/fs/*.lyx'' im Compiler-Repo. Prüflauf 2026-09-05 mit ''doku-pruefer.py'' (Repo-Compiler **lyxc 1.2.2A**): 7 Vollprogramme der Sammlung, 7 übersetzen, 0 echte Fehler; 53 Aufrufe gegen die ''pub fn''-Signaturen gehalten, 0 Abweichungen.