IMMD Hauptseite Zurück Nach oben Hilfe BS - 12. März 1999

AKBP-II 1999: Gruppe 6


FAT 16 Filesystem für Solaris

Bearbeiter: Christian Wawersich, Hendrik Kück

Aufgabenstellung

Die Aufgabe die wir uns gestellt haben war, ein FAT16 Filesystem für Solaris zu implementieren. Es gibt zwar schon das pcfs-Filesystem welches aber nur FAT12 für Disketten unterstützt. Wir haben uns auf FAT16 beschränkt, also FAT12, VFAT (lange Dateinamen) und FAT32 aussen vor gelassen. Das Filesystem sollte als ladbares Modul implementiert werden.

Aufbau des Fat16 Filesystems

Eine FAT16 Partition beginnt mit dem Superblock. In diesem stehen Informationen über das Filesystem, wie zum Beispiel die Grösse eines Sektors ( in Bytes ) die Anzahl der Sektoren pro Cluster, die Anzahl der FATs, Länge einer FAT und anderes mehr. Die für uns relevanten Informationen aus dem Superblock lesen wir beim mounten aus und speichern sie im privaten Teil der vfs Struktur ab.

Nach dem Superblock folgen die FATs ( FAT = file allocation table ). Diese sind zentraler Bestandteil des Filesystems. Wie der Name schon nahelegt wird die FAT benutzt, um den Files die zugehörigen Datenblöcke zuzuordnen. Genauer werden nicht Blöcke zugeordnet sondern Cluster. Ein Cluster besteht aus einem oder mehreren Sektoren. Ein Sektor kann wiederum aus mehreren 512 Byte grosses Blöcken bestehen. Ueblicherweise sind aber Sektoren bei FAT16 auch 512 Bytes gross, bestehen also aus genau einem Block. Die FAT ist ein Array aus 16bit langen Adressen. Jedem Eintrag in der FAT ist ein Daten-Cluster zugeordnet. Die Adresse in dem Eintrag gibt den nachfolgenden Cluster an und kann direkt als Index in die FAT verwendet werden. Spezielle Einträge in der FAT markieren den zugehörigen Cluster als frei (Eintrag 0x0000) oder das Ende eines Files (Eintrag 0xFFF8h - 0xFFFF). Um nun die an die Datenblöcke eines Files zu gelangen, liest man zunächst die Adresse des ersten Clusters aus dem Verzeichniseintrag aus. Ueber diesen kann man dann direkt den ersten Cluster auslesen und den zugehörigen Eintrag in der FAT finden. Solange in der FAT nicht die Markierung für das Dateiende steht, macht man mit dem Cluster, der in dem FAT-Eintrag angegeben ist, weiter.

Es kann mehrere FATs pro Filesystem geben (üblicherweise sind es bei FAT16 zwei). Wenn man die FAT verändert, muss man dann darauf achten, die Aenderung in allen FATs vorzunehmen um diese konsistent zu halten.

Nach den FATs folgt das Root-Verzeichnis. Für das Root-Verzeichnis ist ein Bereich fester Länge vorgesehen, während alle anderen Verzeichnisse wie normale Dateien im Datenbereich liegen und dynamisch erweitert werden können. Die Sonderstellung des Root-Verzeichnisses stammt aus den Anfängen von MS-DOS als es nur ein einziges Verzeichnis ohne Unterverzeichnisse gab. Durch die feste Länge des Root-Verzeichnis kann es dann natürlich vorkommen, dass dieses dann irgendwann einfach voll ist. Vom Inhalt der Blöcke her sind das Root-Verzeichnis und alle anderen Verzeichnisse gleich aufgebaut. Die Datenblöcke enthalten 32 Bytes lange Einträge für die im Verzeichnis enthaltenen Dateien und Unterverzeichnisse. Bei FAT16 werden von diesen 32Byte allerdings nicht alle verwendet:

Offset Länge   Value
0 8 bytes   Name
8 3 bytes   Extension
11 byte   Attribute (00ARSHDV)
  0: unused bit
  A: archive bit,
  R: read-only bit
  S: system bit
  D: directory bit
  V: volume bit
22 word   Zeit
24 word   Datum
26 word   erster Cluster
28 dword   File Grösse
Note: WORD = 2 bytes, DWORD = 4 bytes
Bei VFAT werden die langen Dateinamen mit im Directory gespeichert. Dafür werden ebenfalls 32 Byte lange Erweiterungs-Blöcke verwendet, die durch eine spezielle Kombination von Attribut-Bits markiert sind. Diese Blöcke ignorieren wir einfach. Gelöschte Einträge werden einfach durch den Wert 0xe5 im ersten Byte des Namens markiert. Ebenso erkennt man das Ende des Verzeichnis durch ein 0 Byte als erstes Byte des Namens.

Implementierung

High-Endian <-> Low-Endian
Im Fat16 Filesystem sind alle 16bit und 32bit-Werte als low-endian gespeichert, die höherwertigen Bytes kommen also als letzte. Da das auf den Suns genau andersrum ist (high-endian) müssen wir beim Lesen und Schreiben die Werte entsprechend umrechnen.

MS-DOS-Datei <-> Unix - Datei
In einem Verzeichnis-Eintrag für eine Datei im FAT16 Filesystem sind viele Informationen nicht gespeichert, die UNIX benötigt (über die Funktion getattr). So gibt zum Beispiel keine UderIDs und GroupIDs, keine Zugriffsrechte wie unter Unix (lediglich ein Read-only bit) und neu eine Zeit (modification time) statt 3 wie unter Unix. Die User-ID,Group-ID und die Zugriffsrechte speichern wir daher in für das Filesystem globalen Variablen, die über den mount-Befehl gesetzt werden können. Ausserdem setzen wir das x Bit für alle Verzeichnisse und löschen die read Bits für alle Read-only Dateien. Da die Zeiten unter DOS ein völlig anderes Format haben als unter Unix, müssen wir diese jeweils umrechnen.

Inode-Nummern
Jedem File sollte eine eindeutige Inode-Nummer zugewiesen werden. Unser erster Ansatz war, die erste Cluster-Nummer dafür zu verwenden. Allerdings gab das Probleme, da Dateien der Länge 0 im FAT16 Filesystem keinen Datencluster zugeordnet haben und daher alle die Inodenummer 0 erhalten. Der nächste Ansatz war, die Position des Directory-Eintrags auf der Platte geeignet zu kodieren, da diese für jedes File eindeutig ist. Dazu nehmen wir die Blocknummer, in der der Eintrag zu finden ist und den Index des Eintrags in diesem Block. Erst hatten wir die Blocknummer um 16 Bit nach links geshiftet und dann den Index aufaddiert, was eigentlich keine Probleme machen sollte, da eine Inodenummer als u_longlong_t definiert ist, also 64 bit lang ist. Allerdings stellte sich heraus, dass diverse Programme dann doch Probleme haben mit Inodenummern die nicht in einen 32bit int passen. Daher shiften wir die Blocknummer jetzt nur noch um 8 bit, wodurch die erzeugten Inodenummern in ein int passen. Und 8bit reichen für den Index innerhalb eines Blocks auch locker aus, da in einen 512 byte Block genau 16 Verzeichniseinträge passen.

Kommunikation mit dem Device
Wir arbeiten auf einem blockorientierten Device. Zur Kommunikation mit dem Device verwenden wir die Funktionen bread, bwrite und brelse aus sys/buf.h . Diese ermöglichen gepuffertes blockweises Lesen auf dem Device.

Benutzung des Moduls und Features

Um das Dateisystem zu benutzen braucht man als erstesmal ein Device mit einer gültigen DOS-Partition. Da Sun's Plattenpartionen anderst sind ist es nicht möglich eine PC-Platte von Linux oder Windows einfach anzuschliessen und fertig ist das ganze. Da wir nicht auch noch diese Aufgabe übernehmen wollten haben wir einfach das Loopback-Device von Thomas Jensen und Oliver Podszun und als Datei ein Image von einer 100MB ZIP-Diskette gezogen.

Vorgehensweise

Auf einem Linux-Rechner ein Image erzeugen.
# cat /dev/sda2 > zipimage
Auf eine Festplatte des Solarisrechners kopieren, und ans Loopdevice hängen.
# ./loplk -link /usr/tmp/zipimage /dev/rloop0
Das FAT-Dateisystem laden und das Device mounten.
# modload fatfs
# ./fatmount -u cnwawers -p 640 /dev/loop0 /mnt
starting mount command
mount: trying to mount ... done
und fertig ist die kleine Spielwiese.
# cd /mnt
# ls -la
total 2
drwxr-xrwx   1 root     wheel          0 Jan  1  1970 .
drwxr-xr-x  27 root     other       1024 Mar 12 09:13 ..
drwxr-x--x   1 cnwawers immdstud    2048 Jan  7 20:20 backup
-rw-r-----   1 cnwawers immdstud   83161 Jun 13  1998 bookma~1.htm
drwxr-x--x   1 cnwawers immdstud    2048 Jun 12  1998 cbm
drwxr-x--x   1 cnwawers immdstud    2048 May 19  1998 dl
drwxr-x--x   1 cnwawers immdstud    2048 Jun 20  1998 docs
-rw-r-----   1 cnwawers immdstud   75854 Jan 10 17:35 homewo~1.gz
-rw-r-----   1 cnwawers immdstud     679 Mar  8 16:06 maindir
drwxr-x--x   1 cnwawers immdstud    4096 Mar  8 22:07 pix
-rw-r-----   1 cnwawers immdstud   74767 Jan  8 21:45 takeme~1.gz
-rw-r-----   1 cnwawers immdstud 2810635 Mar 11 22:16 tar.tgz
-rw-r-----   1 cnwawers immdstud     631 Mar  8 16:05 test
# 

Features

Bekannte Fehler und Probleme (Known BUGS)

Unsere Quellen für FAT16 und Dateisysteme unter Solaris

  1. Linux 2.0.36 Kernelsourcen fat16, vfat und msdos filesystem
    Werner Almesberger albert@ccs.neu.edu
  2. Solaris 5.3 Kernelsourcen
    Sun Microsystems
  3. The Magic Garden explained: "The Internals of UNIX SYSTEM VR4"
    Berny Goodheart und James Cox

Unser Server | Brief an Webmaster | Navigationshinweise | Suche