bs Implementierung der Dateiverwaltung Für hohe Effizienz: Caching – vielfach werden Kopien von Plattendaten für längere Zeit im Arbeitsspeicher gehalten: Dateitabelle (Unix: i-node table) enthält aktive Deskriptoren, d.h. von Dateien, die gerade in Benutzung sind ( Dateitabelle auf dem Datenträger!) Blockpuffer (Unix: buffer cache) enthält Kopien von Datenblöcken, Deskriptorblöcken, Superblöcken
bs-6.32 Temporäre Verwaltungsdaten, die kein Äquivalent auf dem Datenträger haben: Kanaltabelle enthält die Iteratoren für „offene“ sequentielle Dateien(6.1.2 )6.1.2 Mount-Tabelle enthält Einträge für die in den Dateibaum eingehängten Dateisysteme
bs-6.33 Temporäre Verwaltungsdaten, die kein Äquivalent auf dem Datenträger haben: Kanaltabelle enthält die Iteratoren für „offene“ sequentielle Dateien(6.1.2 )6.1.2 Mount-Tabelle enthält Einträge für die in den Dateibaum eingehängten Dateisysteme Verweisstruktur: Kanal- tabelle Mount- Tabelle Blockpuffer Datei- tabelle
bs-6.34 öffentlich Blockpuffer devno blkno owner block dirty Operationen geeignet synchronisiert ! weil Prozesse nebenläufig auf den Puffer und seine Einträge zugreifen B (Alles folgende für Beispiel Unix)
bs-6.35 bufno = reqBlock(devno,blkno) stellt sicher, dass der gewünschte Block sich im Puffer bufno befindet, und sperrt ihn; abstrahiert dabei von Pufferverwaltung, Ein/Ausgabe, Synchronisation Vor. (mit Warten!) B devno,blkno .owner == null, falls Eintrag vorhanden; sonst: es existiert Eintrag mit owner == null Eff.:falls B devno,blkno vorhanden, B[bufno] == B devno,blkno && B[bufno].owner == current ; sonst B[bufno] == (devno,blkno,current, DISK[devno,blkno],false)
bs-6.36 Implementierung: benutzt Hilfsroutine getBlock(devno,blkno), die für Eintrag (devno,blkno,current,_,_) sorgt. bufno = req2Blocks(devno1,blkno1,devno2,blkno2) Vor./Eff. wie bufno = reqBlock(devno,blkno) - und evtl. Einlagerung gestartet für 2. Block
bs-6.37 saveBlock(bufno,sync) erzwingt sofortige Auslagerung von B[bufno].block Vor.: B[bufno].owner == current Eff.:wenn nicht sync : Auslagerung ist gestartet; sonst mit d == B[bufno].devno b == B[bufno].blkno : DISK[d,b] == B[bufno].block && B[bufno].owner==null && !B[bufno].dirty
bs-6.38 relBlock(bufno) gibt Position bufno im Blockpuffer frei (Entsperren) Vor.: B[bufno].owner == current Eff.: B[bufno].owner == null && Wenn Gerätetreiber mitteilt, dass Auslagerung des Blocks in Position bufno abgeschlossen ist: B[bufno].dirty löschen B[bufno].owner löschen Höhere Schichten modifizieren gepufferte Blöcke und dirty
bs Dateitabelle (interne Dateitabelle externe Dateitabelle auf Datenträger!) dient zur Aufnahme der aktiven Dateideskriptoren, d.h. für diejenigen Dateien, auf die sich ein Kanal bezieht („offene“ Dateien). Aktiver Deskriptor = Deskriptor + Gerätenummer, Dateinummer, Verweiszähler *(Verweise aus Kanaltabelle), Status: file modified, descriptor modified, is mount point, owner,.....
bs Verwaltung ähnlich wie beim Blockpuffer, allerdings ohne Verdrängung devno filno refcnt status type file map öffentlich D
bs dno = reqDesc(devno,filno) stellt sicher, dass der gewünschte Deskriptor sich in der Tabelle befindet, und sperrt ihn; abstrahiert dabei von Tabellenverwaltung, Ein/Ausgabe von Deskriptoren, Synchronisation; liefert die Position des Deskriptors in der Tabelle. Vor.: D devno,filno .owner == null, falls Eintrag vorhanden (mit Warten!) ; sonst: es existieren freie Positionen ( refcnt==0 ) Eff.:
bs Eff.:falls D devno,filno vorhanden: D[dno] == D devno,filno && D[dno].owner == current && D[dno].refcnt == 'D[dno].refcnt+1 sonst* 'D[dno].refcnt == 0 && D[dno] == (devno,filno,1,current,..., DISK[devno,S+filno/N][filno%N]) mit S = Nummer des ersten Blocks der Dateitabelle auf dem Datenträger, N = Anzahl der Deskriptoren je Block Implementierung:Falls Eintrag nicht vorhanden, reqBlock(devno,S+filno/N) usw.
bs relDesc(dno) gibt Deskriptor frei, ggfls. – wenn nicht mehr aktiv – mit Zurückschreiben auf den Datenträger und ggfls. – wenn Verweiszähler für Datei gleich 0 – mit Löschen von Deskriptor und Datei auf Datenträger Vor.: D[dno].owner == current || D[dno].owner == null Eff.: D[dno].owner == null && D[dno].refcnt == 'D[dno].refcnt-1 und wenn D[dno].refcnt == 0, dann wenn link count = 0, Löschen von.devno,.filno und Löschen auf Datenträger, sonstDeskriptor auf Datenträger ändern (Deskriptor bleibt zunächst in Tabelle!)
bs Implementierung: evtl. reqBlock, saveBlock für den Block, der den Deskriptor enthält, evtl.Platzfreigabe auf Datenträger mit deallocateBlock(devno,blkno) deallocateDesc (devno,filno) ( 6.3.3)
bs Tertiärspeicherverwaltung für Blöcke und Deskriptoren mit Hilfe von Mount-Tabelle mit Einträgen für die bekannten Dateisysteme: devno root mtpt super block Blockpuffer (6.3.1) Dateitabelle (6.3.2) Mount- Tabelle
bs Blockverwaltung: bufno = allocateBlock(devno) reserviert Block auf Gerät devno (Blocknummer sei blkno ), trägt im Blockpuffer ein: (devno,blkno,current,0,1), markiert Superblock von devno als dirty; liefert Nummer des Blockpuffer-Eintrags. Implementierung: bufno = getBlock(devno,blkno) sorgt für Eintrag (devno,blkno,current,_,_) ; evtl. req/relBlock für Block, der auf weitere freie Blöcke verweist *.
bs deallocateBlock(devno,blkno) gibt Block blkno auf Gerät devno frei (der Block vermodert im Blockpuffer) Implementierung: evtl. req/relBlock analog zu allocateBlock
bs-6.3 Deskriptorverwaltung: dno = allocateDesc(devno) reserviert freie Position filno in der Dateitabelle auf devno, erzeugt und initialisiert entsprechenden aktiven Deskriptor (devno,filno,1,current,...) und liefert dessen Position. Implementierung: evtl. req/relBlock für externe Dateitabelle auf Gerät, um freie Stelle filno zu finden; dno = reqDesc(devno,filno) schafft Eintrag in interner Dateitabelle; partielle Initialisierung des Deskriptors (extern und intern) (z.B. type 0 bedeutet „belegt“).
bs deallocateDesc(devno,filno) gibt die Position für filno in der externen Dateitabelle von devno frei Implementierung: Übung!
bs Auflösung eines Wegnamens hat die Aufgabe, zu einem vorgegebenen, syntaktisch korrekten Wegnamen den zugehörigen Dateideskriptor in der internen Dateitabelle bereitzustellen: dno = path2dno(path) Vor.: path syntaktisch korrekt Eff.: D[dno] ist der Deskriptor der gesuchten Datei, gesperrt mit.owner = current
bs Implementierung: Die Einträge in einem Verzeichnis sind Paare (name, fileIndex). Ein mount point, d.h. eine Datei, die mit der Wurzel eines fremden Dateisystems überlagert wurde, ist am Status ihres Deskriptors erkennbar. In der Mount-Tabelle kann dann der Eintrag gefunden werden, der auf diesen Deskriptor verweist, und aus diesem Eintrag kann der Verweis auf den Deskriptor der Wurzel entnommen werden.
bs Implementierung – erfolgreiche Suche vorausgestzt: d = reqDesc(root) oder d = reqDesc(curdir) ; i = 0; b = reqBlock(devno, getblkno(i++,d)); search block b for name ; relBlock(b); (name, next file) found ? relDesc(d); d = reqDesc( next file ); path exhausted ? dno = d; no yes