Das virtuelle Dateisystem von Linux (VFS) Idee: uniformer Zugriff auf unterschiedliche Dateisysteme ext2 Block Device Programm (cp, rm) VFS NTFS Block Device NFS Netzwerk Arten von Dateisystemen: plattenbasiert (Disc, CD, HD) NW-basiert (NFS) besondere (proc) Transparente Einbindung in globale Verzeichnisstruktur (/home/troll, /cdrom) Allgemeine Objekte im VFS Superblock speichert Informationen über ein Dateisystem Inode speichert Informationen über eine Datei jeder Inode besitzt eine eindeutige Nummer Fileobject speichert Information zur Interaktion zwischen einer geöffneten Datei und einem Prozess existiert nur zur Laufzeit im Kernelspeicher Dentry speichert die Verbindung zwischen einem Verzeichniseintrag und der Datei 1
Interaktion von VFS Objekten Storage Device proc1 proc2 fd fd File object File object i_sb superblock inode f_dentry d_inode dentry dentry f_dentry Hardlink Dentry cache Superblock-Objekt (struct super_block, include/linux/fs.h) Verwaltung aller Superblöcke in einer Liste Superblock enthält: struct file_system_type s_type unsigned long s_blocksize struct dentry s_root Wurzel des Dateisystems struct super_operations s_op Speicherung dateisystemspezifischer Informationen in: union { struct minix_sb_infominix_sb; struct ext2_sb_info ext2_sb;... } u; 2
Superblock-Operations read_inode(inode) // inode.i_no ist gesetzt füllt die inode Struktur mit den gespeicherten Daten write_inode(inode) put_inode(inode) gibt die Struktur zur Wiederverwendung frei delete_inode(inode) löscht Struktur und die gespeicherten Daten write_super(super) speichert die Superblock-Struktur remount_fs(super,flags,data) bindet Dateisystem mit geänderten Parametern neu ein Inode-Objekt (include/linux/fs.h) 1 Datei hat genau 1 Inode Dateiname ist nicht im Inode enthalten Listen: aktuell nicht benutzte Inodes aktuell benutzte Inodes Inkonsistente Inodes (d.h. noch nicht gespeichert) Inode enthält: allgemeine Info. (Besitzer, Zugriffsrechte, Operationen) DS-spezifische Information in einer Union (wie bei Superblock) 3
Inode-Operationen (include/linux/fs.h) create(dir,dentry,mode) erzeugt neuen Inode in dir für dentry->d_name lookup(dir,dentry) sucht in dir eine Datei mit dentry->d_name mkdir(dir,dentr) legt ein Verzeichnis in dir an über inode.i_mapping.address_space_operations readpage(struct file *f,struct page *pg) liest eine Page aus einer Datei in Speicher writepage(file,ps) File-Objekt (struct file) Ist transient, zum prozessseitigen Zugriff auf Dateien verwaltet einen Positionszeiger Enthält nur allgemeine (=uniforme) Informationen, z.b: f_dentry f_mode Zugriffsmodus des Prozesses (RWC) f_count Benutzungszähler (z.b. für Threads) f_uid, f_guid struct file_operations *op Listen: aktuell benutzte Fileobjekte aktuell ungenutzte Fileobjekte 4
File-Objekt-Operationen (struct file_operations) lseek(file,off,whence) aktualisiert den Positionszeiger (wie Systemaufruf) read(file,buff,count,off) write(file,buf,count,off) ioctl(inode,file,cmd,arg) sendet ein Kommando an das entsprechende Gerät mmap(file, struct vm_area_struct *vma) bildet die Datei auf Speicher ab open(inode,file) öffnet Datei und generiert neues Fileobjekt fsync(file,dentry) sichert alle gecachten Daten flush(file) wird aufgerufen, wenn (Benutzungszähler = 0); Semantik hängt vom Dateisystem ab Verzeichnisse Verzeichnisse sind gewöhnliche Dateien Aus dem Inhalt einer Verzeichnisdatei lassen sich dentry- Objekte erzeugen. Zugriff mit (in file_operations) int readdir(struct file *,void *dirent, filldir_t fill_fct) füllt mit fill_fct die Struktur dirent Sonderbehandlung für nebenläufigen Zugriff auf Verzeichnisdateien keine Sperrung bei Lese-/Schreibzugriffen (würde alle Unterverzeichnisse sperren) global_event dient als Zeitstempel im Inode und im Fileobjekt readdir überprüft global_event und veranlasst evtl. Aktualisierung 5
Dentry-Objekt (struct dentry, include/linux/dcache.h) Abbildung: Dateiname -> Inode Enthält u.a.: d_inode d_name d_subdirs struct superblock *d_sb d_parent existiert für alle gültigen D-Objekte außer der Wurzel struct dentry d_covers zeigt auf Mountpoint (s.sp.) Einbinden eines Dateisystems (Mounten) Registrierung des Dateisystems mit int register_filesystem(struct file_system_type *ft) (ft enthält u.a. Name, Zugriff auf Superblock) Einbinden durch Einhängen in den Dentry-Objekten Vor dem Einbinden / Nach dem Einbinden / d_covers mnt mnt d_covers d_mounts s_root d_mounts sb Verzeichnisbaum unter mnt wird verdeckt. 6
Blockorientierte Geräte 2 Arten von Geräten (plus Spezialgeräte) zeichenorientiert: zeichenweises Lesen/Schreiben (z.b. Maus, Drucker) blockorientiert: Verwaltung von Datenblöcken mit direktem Zugriff, wird i.a. für Dateisysteme genutzt (z.b. Festplatte) Uniformer Zugriff auf blockorientierte Geräte mit VFS => Einsatz von Dateisystemen für unterschiedlichste Endsysteme struct buffer_head ist Puffer + Verwaltungsinformation + Synchronisationsmechanismen Lesen/Schreiben von Blöcken (drivers/block/ll_rw_block.c) void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) Lesen/Schreiben einer regulären Datei Lesen/Schreiben von Dateien immer in Pages (s. Speicherverwaltung) VFS bietet Standardfunktionen an, um auf Pages mit den üblichen Lese-/Schreibfunktionen zuzugreifen (Signaturen in include/linux/fs.h, Implementierungen in mm/filemap.c) generic_file_read() generic_file_write() Dateien lassen sich auf Speicher abbilden, Standardfunktion: generic_file_mmap() Einsatz dieser Standardfunktionen in file_operations 7
Das Ext2 Dateisystem Linux nutzte zuerst das Minix-FS, dann Extended-FS und jetzt ext2 (ext3 ist in Arbeit) Einige Eigenschaften: Freie Wahl der Blockgröße bei der Formatierung, der Menge an Inodes Blöcke sind in Gruppen eingeteilt (erleichtert Suche) Präallokation von Blöcken für Files Automatische Konsistenzüberprüfung Nichtveränderbare Dateien, bzw. Dateien, an die nur angehängt werden kann Layout des ext2 Dateisystems Boot Block Block Group 0... Block Group N Super Block Group Data block Descriptors Bitmap Inode Bitmap Inode Table Data Blocks Jede Gruppe hat eine Kopie des Superblocks. 8
Datenstrukturen+Implementierung Persistente Datenstrukturen (in include/linux/ext2_fs.h) ext2_superblock ext2_inode ext2_group_desc ext2_inode_table Transiente Datenstrukturen (über Union u in allgemeine Strukturen integriert, in.../ext2_fs_i.h und.../ext2_fs_sb.h) ext2_sb_info ext2_inode_info Funktionen sind in fs/ext2/*.c definiert. 9