Bestandssystemen
open en read tot fsync, rename, koppelingen en toegangsrechten. Bekijk hoe een eenvoudig bestandssysteem inodes, bitmaps en gegevensblokken indeelt, hoe het Fast File System verwante gegevens dicht bij elkaar houdt en hoe fsck en journaalregistratie de schijf na een crash consistent houden. Sluit af met loggestructureerde bestandssystemen en met hoe NFS en AFS bestanden via een netwerk delen.GemiddeldLes 8 van 9 in Cursus Besturingssystemen: processen, geheugen, threads en bestandssystemen
Wat je leert
- Gebruik de systeemaanroepen waarop een programma vertrouwt om bestanden aan te maken, te lezen, te schrijven, te benoemen, te beschermen en te ordenen, en voorspel wat elke aanroep doet met bestandsposities, namen en gegevens op schijf.
- Lees en schrijf bestanden via bestandsdescriptorenOpen bestanden, lees en schrijf ze via bestandsdescriptoren, verplaats de bestandspositie en leg uit hoe processen geopende bestanden delen.
- Maak schrijfbewerkingen duurzaam en wijzigingen atomairDwing gegevens naar stabiele opslag wanneer ze een crash moeten overleven, en vervang de inhoud van een bestand zo dat lezers óf de oude óf de nieuwe versie zien.
- Orden namen met directory's en koppelingenMaak directory's aan, geef ze weer en verwijder ze, en leg uit hoe harde koppelingen, symbolische koppelingen en het verwijderen van een bestand namen en inodes beïnvloeden.
- Lees metadata, regel toegang en koppel bestandssystemen aanLees de metadata van een bestand met stat, stel toegangsrechtenbits in en interpreteer ze, en leg uit hoe afzonderlijke bestandssystemen tot één directoryboom worden samengevoegd.
- Lees en schrijf bestanden via bestandsdescriptoren
- Beschrijf de structuren op schijf van een eenvoudig Unix-achtig bestandssysteem, bereken waar een inode en de blokken van een bestand staan en volg de lees- en schrijfbewerkingen op schijf achter het openen, lezen en schrijven van een bestand.
- Deel een schijf in met blokken, bitmaps, inodes en directory'sDeel een schijf in in het superblok, toewijzingsbitmaps, de inodetabel en het gegevensgebied, zoek een inode op nummer en beschrijf hoe directory's en vrije ruimte worden opgeslagen.
- Vind de gegevens van een bestand met pointers, indirecte blokken en extentsLeg uit hoe directe pointers, indirecte blokken en extents van een inode bestandsposities aan schijfblokken koppelen en bereken het grootste bestand dat een pointerindeling ondersteunt.
- Volg de schijf-I/O van bestandsbewerkingen en onderzoek het effect van cachingTel de bloklees- en schrijfbewerkingen achter het openen, lezen, aanmaken en schrijven van een bestand en leg uit hoe caching en schrijfbuffering dat verkeer veranderen.
- Deel een schijf in met blokken, bitmaps, inodes en directory's
- Onderzoek waarom vroege Unix-bestandssystemen traag waren op harde schijven en leg uit hoe de groepen, plaatsingsregels en het beleid voor grote bestanden van het Fast File System verwante gegevens dicht bij elkaar houden.
- Leg uit waarom vroege Unix-bestandssystemen traag waren en hoe groepen dat verhelpenHerken de indelingsproblemen die schijfbandbreedte verspilden in het oorspronkelijke Unix-bestandssysteem en beschrijf hoe cilindergroepen en blokgroepen de schijf indelen.
- Pas de plaatsingsregels van FFS toe en bepaal de deelgroottes voor grote bestandenGebruik de plaatsingsregels van FFS voor directory's en bestanden, pas de uitzonderingsregel voor grote bestanden toe, bereken hoe groot een deel moet zijn om de positioneringskosten te amortiseren en beschrijf de overige verbeteringen van FFS.
- Leg uit waarom vroege Unix-bestandssystemen traag waren en hoe groepen dat verhelpen
- Leg uit waarom een crash midden in een wijziging een bestandssysteem kan beschadigen en vergelijk herstel achteraf met fsck, schade voorkomen met journaalregistratie en andere benaderingen.
- Leg het probleem van consistentie na een crash uitLaat zien waarom één bestandsbewerking meerdere blokschrijfbewerkingen nodig heeft, noem wat een crash daartussen op schijf kan achterlaten en classificeer elke uitkomst.
- Controleer en herstel een bestandssysteem met fsckBeschrijf wat de bestandssysteemcontrole na een crash onderzoekt en herstelt, en leg uit waarom een controle van de hele schijf slecht schaalt en niet elk probleem kan opsporen.
- Bescherm wijzigingen met gegevensregistratie in een journaal en pas de wijzigingen uit het logboek opnieuw toeSchrijf een wijziging naar een journaal voordat je het bestandssysteem op de bestaande plaats wijzigt, leg uit waarom het vastleggingsblok als laatste wordt geschreven en herstel na een crash door vastgelegde transacties opnieuw toe te passen.
- Verlaag de kosten van journaalregistratie en vergelijk andere benaderingenLeg uit hoe metadataregistratie in een journaal voorkomt dat gegevens twee keer worden geschreven, waarom geordende journaalregistratie gegevens vóór het vastleggen schrijft, hoe intrekkingsrecords een fout bij hergebruik van blokken voorkomen en hoe andere ontwerpen bestandssystemen consistent houden.
- Leg het probleem van consistentie na een crash uit
- Leg uit waarom alles sequentieel naar een logboek schrijven schrijfbewerkingen versnelt, hoe de inodevertaaltabel en het checkpointgebied het bestandssysteem gegevens in dat logboek laten vinden en hoe opruimen en herstel na een crash werken.
- Schrijf sequentieel in segmenten en vind inodes via de inodevertaaltabelLeg de aanleiding voor een loggestructureerd bestandssysteem uit, bepaal de segmentgrootte voor een gewenste bandbreedte en volg hoe de inodevertaaltabel en het checkpointgebied een bestand vinden.
- Maak ruimte vrij met de segmentopruimer en herstel na een crashLeg uit hoe LFS nog gebruikte blokken vindt en samenvoegt, kiest welke segmenten worden opgeruimd en herstelt na een crash, en hoe de ideeën voortleven in bestandssystemen met kopiëren bij schrijven en voor flashgeheugen.
- Schrijf sequentieel in segmenten en vind inodes via de inodevertaaltabel
- Leg uit hoe NFS en AFS veel clientmachines bestanden op servers laten gebruiken, hoe ze crashes afhandelen en hoe hun keuzes voor caching bepalen wanneer een client de wijzigingen van een andere ziet.
- Leg uit hoe NFS met toestandsloze verzoeken van storingen hersteltBeschrijf de client-serverstructuur van NFS, hoe bestandshandles en idempotente verzoeken een client laten herstellen van servercrashes door verzoeken te herhalen en waarom de server schrijfbewerkingen vóór het antwoord moet vastleggen.
- Vergelijk caching en consistentie bij NFS en AFSLeg uit hoe NFS en AFS bestandsgegevens op clients cachen, wanneer elk de wijzigingen van een client zichtbaar maakt voor anderen en welke werklasten gunstig zijn voor elk ontwerp.
- Leg uit hoe NFS met toestandsloze verzoeken van storingen herstelt
Bestandssystemen: uitleg
1Gebruik de interface voor bestanden en directory's
Bestandsbewerkingen maken verschillende soorten toestand zichtbaar: bytes, namen, bestandsposities van geopende bestanden en toegangsrechten. Volg een descriptor tijdens leesbewerkingen en bij gedeelde bestandsposities en onderscheid daarna een voltooide aanroep van duurzaam opslaan. Directory's en koppelingen verklaren waarom het verwijderen van een naam het object niet hoeft te verwijderen. Metadata en aankoppeling maken het beeld compleet van hoe een programma via één directoryboom een bestand bereikt en gebruikt.
1.1 Lees en schrijf bestanden via bestandsdescriptoren
Een bestand is een persistente reeks bytes. Het bestandssysteem slaat die bytes op zonder te bepalen of ze tekst, een afbeelding of machinecode voorstellen. Een directory geeft het bestand een leesbare naam; het inodenummer identificeert het binnen het bestandssysteem.
Open een bestand en controleer het resultaat
open(path, flags, mode) geeft een bestandsdescriptor terug, een niet-negatief geheel getal dat in latere aanroepen wordt gebruikt. Bij een fout geeft de aanroep -1 terug en stelt errno in. Kies O_RDONLY, O_WRONLY of O_RDWR voor de toegang. O_CREAT maakt een ontbrekend bestand aan, O_TRUNC maakt een bestaand bestand leeg en O_APPEND plaatst elke schrijfbewerking aan het huidige einde.
Voor een nieuw bestand vraagt mode toegangsrechten aan en verwijdert de umask van het proces bits. Zonder standaardtoegangscontrolelijst (ACL) op de directory is het resultaat mode & ~umask. Als je 0666 aanvraagt met umask 0022, krijg je 0644, oftewel rw-r--r--. Dit argument verandert de toegangsrechten van een al bestaand bestand niet.
Descriptoren horen bij een proces. Normaal zijn 0, 1 en 2 de standaardinvoer, standaarduitvoer en standaardfoutuitvoer. open kiest de laagste ongebruikte descriptor, vaak 3. Op Linux laat strace cat notes.txt de aanroepen zien: de invoer openen, die lezen, naar descriptor 1 schrijven en de invoer sluiten.
Volg de bestandspositie, niet het gevraagde aantal
read(fd, buf, n) geeft het daadwerkelijk gelezen aantal bytes terug, maximaal n. Bij een verzoek om een aantal groter dan nul voor een gewoon bestand betekent nul dat op of voorbij het bestandseinde geen bytes over zijn; -1 betekent een fout. write geeft ook een werkelijk aantal terug, dat lager kan zijn dan gevraagd. Controleer dat aantal voordat je verdergaat in een buffer of besluit dat de bewerking voltooid is.
Stel dat log.txt 300 bytes bevat. Vier verzoeken om 100 bytes geven 100, 100, 100 en 0 terug. De bestandspositie, de positie van de volgende bewerking, wordt 100, 200, 300 en 300. Het bestandseinde is een teruggegeven aantal, geen speciale byte die in het bestand is opgeslagen.
lseek(fd, 200, SEEK_SET) stelt de positie in op 200. Een daaropvolgende leesbewerking van 50 bytes geeft bytes 200–249 terug en laat de positie op 250 staan. SEEK_CUR meet vanaf de huidige positie; SEEK_END meet vanaf het bestandseinde. De positie verplaatsen verandert een getal in het geheugen. Het verplaatst geen schijfkop en leest zelf geen gegevens. pread en pwrite gebruiken een expliciete positie zonder deze bestandspositie te veranderen.
Bepaal welke descriptoren een bestandspositie delen
De descriptortabel van het proces verwijst naar vermeldingen in de tabel met geopende bestanden van de kernel. Elke vermelding bevat de toegangsmodus, bestandspositie, inodeverwijzing en verwijzingsteller.
| Hoe descriptoren ontstaan | Gedrag van de bestandspositie |
|---|---|
Twee afzonderlijke open-aanroepen | Onafhankelijke posities, ook voor dezelfde inode |
dup of dup2 | Eén gedeelde vermelding en bestandspositie |
Descriptoren overgeërfd via fork | Ouder- en kindproces delen de vermelding en bestandspositie |
Als een kindproces een gedeelde descriptor naar byte 10 verplaatst, begint de volgende leesbewerking van het ouderproces via die vermelding ook op 10. De inode identificeert het bestand, maar de vermelding bevat de bestandspositie: twee lezers kunnen een bestand delen zonder hun positie te delen. De shell gebruikt dup2 bij omleiding om de standaarduitvoer naar een andere vermelding te laten verwijzen. close geeft één descriptor vrij; de vermelding verdwijnt nadat de laatste verwijzing is vrijgegeven. Sluiten alleen dwingt gebufferde gegevens niet naar stabiele opslag.
Belangrijkste punten
- Controleer het teruggegeven aantal bytes van elke
readenwrite. - Een bestandspositie hoort bij een vermelding in de tabel met geopende bestanden, niet bij de inode.
- Afzonderlijk geopende bestanden hebben afzonderlijke posities; gedupliceerde en overgeërfde descriptoren delen er één.
lseekverandert de bestandspositie zonder schijf-I/O uit te voeren.closegeeft een descriptor vrij; het garandeert geen duurzaamheid.
1.2 Maak schrijfbewerkingen duurzaam en wijzigingen atomair
Een geslaagde schrijfbewerking en een wijziging die een crash overleeft, beantwoorden verschillende vragen. Een schrijfbewerking meldt dat bytes zijn geaccepteerd. Duurzaamheid gaat over de vraag of ze een crash overleven; atomiciteit gaat over de vraag of een wijziging alleen als geheel zichtbaar kan zijn.
Dwing de bytes naar stabiele opslag
Besturingssystemen bufferen schrijfbewerkingen meestal in het geheugen en sturen gewijzigde blokken later naar opslag, vaak binnen ongeveer 5–30 seconden. Dit combineert kleine schrijfbewerkingen en laat het programma snel doorgaan. Een crash kan gegevens wissen die nog in die buffers wachten.
fsync(fd) dwingt de gewijzigde gegevens en metadata van het bestand naar opslag en wacht tot het apparaat voltooiing meldt. Een programma moet het resultaat controleren voordat het meldt dat gegevens duurzaam zijn opgeslagen. close geeft de descriptor vrij en vervangt dit wachten niet.
Een bestand heeft ook een duurzaam opgeslagen naam nodig. De vermelding die de naam aan de inode koppelt, is onderdeel van de gegevens van de directory, niet van het bestand. Als je na het aanmaken van een bestand alleen het bestand synchroniseert, kunnen de bytes duurzaam zijn opgeslagen zonder de garantie dat de nieuwe naam behouden blijft. Open de bovenliggende directory en synchroniseer die wanneer de naam behouden moet blijven.
Vervang een bestand zonder een gedeeltelijke versie te tonen
Een document op de bestaande plaats overschrijven creëert een periode waarin lezers onvolledige inhoud kunnen aantreffen. O_TRUNC stelt de lengte eerst in op nul. Als een crash de latere schrijfbewerkingen onderbreekt, is de oude volledige kopie al verdwenen.
Schrijf de vervanging daarom onder een tijdelijke naam in dezelfde directory. Gebruik daarna rename om het doel te vervangen. Voor een bestaand doel op hetzelfde bestandssysteem maakt POSIX die vervanging atomair: de doelnaam verwijst naar het oude bestand of naar de vervanging, zonder dat de naam tussendoor ontbreekt. Lezers zien via die naam geen mengsel van de inhoud van beide bestanden.
Voor settings.json is de volgorde voor duurzame vervanging:
- Schrijf de volledige nieuwe inhoud naar
settings.json.tmpen controleer op schrijfbewerkingen met minder geschreven bytes dan aangevraagd en op fouten. - Roep
fsyncaan op het tijdelijke bestand en controleer of dat lukt. - Roep
rename("settings.json.tmp", "settings.json")aan en controleer of dat lukt. - Roep
fsyncaan op de bovenliggende directory en controleer of dat lukt.
Het tijdelijke bestand is volledig en duurzaam opgeslagen voordat de naam verandert. De laatste synchronisatie van de directory maakt die naamswijziging duurzaam. Een crash tijdens de reeks laat het doel achter met een volledige oude of volledige nieuwe versie; na de laatste geslaagde synchronisatie is de nieuwe versie duurzaam opgeslagen. Alleen atomaire vervanging van de naam garandeert niet dat een niet-gesynchroniseerde hernoeming stroomuitval overleeft.
rename tussen bestandssystemen mislukt met EXDEV. Een commando dat daarop reageert door te kopiëren en te verwijderen, voert meerdere bewerkingen uit, zodat die terugvaloptie geen atomaire vervanging garandeert.
Verander de lengte zonder elke byte te schrijven
truncate(path, length) en ftruncate(fd, length) stellen de lengte van het bestand in. Inkorten verwijdert bytes voorbij het nieuwe einde. Bij verlengen wordt het nieuwe gebied als nullen gelezen. Ook als je de positie voorbij het einde verplaatst en daarna schrijft, ontstaat een tussenruimte die als nullen wordt gelezen.
Een dunbezet bestand kan zo'n tussenruimte voorstellen zonder er gegevensblokken voor toe te wijzen. Als je met een leeg bestand begint en één byte op positie 8192 schrijft, ontstaat een bestand van 8193 bytes; het voorafgaande ongeschreven gebied wordt als nullen gelezen. De logische grootte kan groter zijn dan de fysiek toegewezen ruimte.
Belangrijkste punten
fsyncmaakt bestandsgegevens en metadata duurzaam na geslaagde voltooiing.- Synchroniseer de directory om een nieuwe of vervangen naam duurzaam te maken.
- Schrijf, synchroniseer, hernoem en synchroniseer daarna de directory voor een duurzame vervanging.
- Een dunbezette tussenruimte wordt als nullen gelezen en hoeft geen gegevensblokken te bezetten.
1.3 Orden namen met directory's en koppelingen
Directory's scheiden de namen die mensen gebruiken van de objecten die het bestandssysteem opslaat. Elke directory heeft een eigen inode en gegevensblokken; de vermeldingen koppelen namen aan inodenummers.
Volg paden door de boom
Een absoluut pad begint bij /. Een relatief pad begint bij de huidige werkdirectory van het proces. De vermelding . duidt de directory zelf aan en .. de bovenliggende directory; de bovenliggende directory van de hoofddirectory is de hoofddirectory zelf. Vanuit /home/lee bereik je met het relatieve pad ../shared de directory /home/shared.
Een extensie zoals .txt maakt deel uit van een naam. Programma's kunnen die gebruiken om te kiezen hoe ze de bytes interpreteren, maar het bestandssysteem vereist niet dat een .txt-bestand tekst bevat.
mkdir maakt een directory aan met . en ... Om vermeldingen weer te geven, gebruikt een programma opendir, roept het readdir aan totdat er geen vermeldingen meer zijn en roept het closedir aan. Een resultaat van readdir bevat een naam en inodenummer. Programma's wijzigen directory-inhoud via aanroepen zoals link, unlink en rename, niet via gewone write-aanroepen. rmdir verwijdert een lege directory.
Geef één bestand twee gelijkwaardige namen
link(old, new) maakt een harde koppeling: een extra directoryvermelding die naar dezelfde inode verwijst. Geen van beide namen heeft een bevoorrechte positie als origineel. Het aantal harde koppelingen van de inode geeft aan hoeveel namen ernaar verwijzen.
Bekijk deze commando's wanneer geen proces het bestand open heeft:
echo hi > a
ln a b
rm a
cat b
rm b
Door b aan te maken stijgt het aantal harde koppelingen van 1 naar 2. Door a te verwijderen daalt het tot 1; via b zijn dezelfde bytes nog bereikbaar, dus drukt cat b “hi” af. Door b te verwijderen daalt het aantal tot 0, zodat de inode en de blokken ervan kunnen worden vrijgemaakt.
Een open descriptor voegt een tweede regel voor de levensduur toe. Als de laatste naam wordt verwijderd terwijl een proces het bestand nog open heeft, kan dat proces het blijven gebruiken. Vrijmaken wacht totdat zowel het aantal koppelingen nul is als er geen open verwijzingen meer zijn. Dit verklaart waarom het verwijderen van een groot geopend logboek de ruimte mogelijk niet onmiddellijk vrijgeeft.
Een harde koppeling kan niet over bestandssystemen heen verwijzen: het inodenummer van het doel zou geen betekenis hebben in de andere inodetabel. De meeste Unix-systemen verbieden ook harde koppelingen naar directory's om een boom zonder cycli te behouden. Bij de klassieke Unix-telling van directorykoppelingen heeft een lege directory twee koppelingen, vanuit de vermelding in de bovenliggende directory en vanuit de eigen .. Elke subdirectory voegt er via .. één toe; drie subdirectory's geven een aantal van 5.
Sla een pad op in een symbolische koppeling
Een symbolische koppeling is een afzonderlijk bestand waarvan de inhoud een doelpad is. ln -s /home/ana/report.txt r maakt r aan met het doelpad van 20 bytes als inhoud. Als je de koppeling volgt, wordt dat pad gevolgd. Symbolische koppelingen kunnen over bestandssystemen heen verwijzen en naar directory's wijzen.
| Soort koppeling | Wat de directoryvermelding bereikt | Effect van het verwijderen van de doelnaam |
|---|---|---|
| Harde koppeling | De gedeelde inode | Een andere harde koppeling bereikt het bestand nog steeds |
| Symbolische koppeling | Een afzonderlijk koppelingsobject met een pad | De koppeling is verbroken als het opgeslagen pad niet meer naar een doel leidt |
Een symbolische koppeling verhoogt het aantal harde koppelingen van het doel niet. Het koppelingsobject bewaren houdt het doel dus niet in stand.
Belangrijkste punten
- Directory's koppelen namen aan inodenummers; paden kiezen een reeks van die namen.
- Harde koppelingen zijn gelijkwaardige namen voor één inode.
- Een koppeling verwijderen verwijdert een naam; vrijmaken wacht ook tot open verwijzingen zijn beëindigd.
- Symbolische koppelingen slaan paden op en kunnen verbroken raken.
- Harde koppelingen blijven binnen één bestandssysteem.
1.4 Lees metadata, regel toegang en koppel bestandssystemen aan
De inhoud van een bestand is slechts een deel van de toestand ervan. Metadata legt vast wie het bestand mag gebruiken, wat de grootte en het type zijn en wanneer het is gewijzigd. Door aankoppeling worden objecten uit meerdere bestandssystemen bereikbaar via één namenboom.
Lees de metadata correct
stat(path, &buf) leest metadata via een pad; fstat(fd, &buf) leest die via een open descriptor. De resultaten omvatten het inodenummer, type, de toegangsrechten, ID's van eigenaar en groep, grootte, toegewezen blokken en het aantal harde koppelingen. De bestandsgrootte telt logische bytes; toegewezen blokken meten de werkelijk gebruikte opslagruimte, die bij een dunbezet bestand kleiner kan zijn dan de logische grootte.
Drie tijdstempels beschrijven verschillende gebeurtenissen:
| Veld | Betekenis | Voorbeeld van een gebeurtenis |
|---|---|---|
| atime | Laatste toegang | Inhoud lezen |
| mtime | Laatste wijziging van de inhoud | Bytes schrijven |
| ctime | Laatste statuswijziging van de inode | Schrijven, toegangsrechten wijzigen of een harde koppeling toevoegen |
ctime is niet de aanmaaktijd. Alleen atime bijwerken verandert ctime niet. De klassieke Unix-aanroep stat heeft geen veld voor de aanmaaktijd; Linux statx kan een geregistreerde geboortetijd tonen wanneer het bestandssysteem die ondersteunt.
Ontcijfer toegangsrechtenbits
Lees-, schrijf- en uitvoerrechten worden afzonderlijk vastgelegd voor eigenaar, groep en anderen. Elke klasse vormt één octaal cijfer: lezen is 4, schrijven 2 en uitvoeren 1. Bij rw-r----- krijgt de eigenaar 4 + 2 = 6, de groep 4 en de anderen 0. chmod 640 report.txt stelt die bits in.
Toegangsrechten voor een directory gelden voor namen en het doorlopen van paden. Leesrecht staat toe namen weer te geven. Uitvoerrecht staat doorzoeken toe, wat betekent dat je de directory in een pad mag gebruiken. Schrijfrecht samen met uitvoerrecht staat toe vermeldingen aan te maken, te verwijderen en te hernoemen. De naam kennen kan voldoende zijn om een bestand te openen in een directory met uitvoerrecht maar zonder leesrecht, mits de eigen toegangsrechten van het bestand toegang toestaan. De inhoud van die directory weergeven mislukt nog steeds.
Dit verschil is van belang bij verwijderen: een vermelding verwijderen wijzigt de bovenliggende directory. Het schrijfbit van een bestand bepaalt of je de bytes ervan mag wijzigen; het geeft niet het recht om de naam uit de directory te verwijderen. Root omzeilt de meeste gewone toegangscontroles. Toegangscontrolelijsten (ACL's) kunnen rechten geven aan bij naam genoemde gebruikers en groepen buiten de drie basisklassen.
Koppel een ander bestandssysteem aan
mkfs initialiseert een bestandssysteem op een partitie of ander apparaat, inclusief een eigen hoofddirectory en metadata. Het vernietigt de eerdere bestandssysteeminhoud van het apparaat, dus voer het alleen uit op een apparaat dat voor initialisatie is bedoeld.
mount koppelt die hoofddirectory aan een bestaande directory die het koppelpunt heet. Een schijf die op /media/usb is aangekoppeld, maakt de inhoud van de hoofddirectory daar bereikbaar. De eerdere inhoud van /media/usb is verborgen zolang de koppeling actief is; aankoppelen voegt die inhoud niet samen met de aangekoppelde boom. Als je mount zonder argumenten uitvoert, zie je de huidige koppelingen.
De laag van het virtuele bestandssysteem (VFS) in de kernel geeft ext4, XFS, FAT, geheugenbestandssystemen en netwerkbestandssystemen een gemeenschappelijke interface. Programma's kunnen via elk daarvan open en read aanroepen. De samengevoegde naamruimte voegt de inodetabellen niet samen: gelijke inodenummers op verschillende bestandssystemen kunnen niet-gerelateerde bestanden identificeren. Harde koppelingen en atomaire hernoemingen blijven daarom binnen hun eigen bestandssysteem.
Belangrijkste punten
statenfstatbeschrijven metadata; ctime registreert statuswijzigingen.- Rechtencijfers tellen lezen = 4, schrijven = 2 en uitvoeren = 1 per gebruikersklasse op.
- Uitvoerrecht op een directory staat het doorlopen van een pad toe; leesrecht staat toe de inhoud weer te geven.
- Aankoppelen verbindt de hoofddirectory van een bestandssysteem en verbergt de eerdere inhoud van het koppelpunt.
- Het VFS biedt bestandssysteemtypen een gemeenschappelijke interface, geen globale inodetabel.
- De logische bestandsgrootte en de toegewezen ruimte kunnen verschillen.
2Leg uit hoe een eenvoudig bestandssysteem gegevens opslaat en terugvindt
Achter een leesbaar pad gaat een reeks opzoekacties, toewijzingen en bloktoegangen schuil. Bouw een kleine schijfindeling, bereken een inodeadres en koppel byteposities via directe pointers, indirecte blokken of extents aan locaties. Volg daarna de I/O achter veelvoorkomende aanroepen. Door expliciet te maken wat in de cache staat, kun je uitleggen waarom hetzelfde programma de ene keer veel apparaatbewerkingen veroorzaakt en de volgende keer heel weinig.
2.1 Deel een schijf in met blokken, bitmaps, inodes en directory's
Een bestandssysteem moet zowel onthouden waar bytes staan als welke ruimte beschikbaar is. Een eenvoudige Unix-achtige indeling maakt deze taken zichtbaar door toewijzingsgegevens, inodes en inhoud te scheiden.
Verdeel de partitie in gebieden
Een blok is de basiseenheid voor toewijzing van het bestandssysteem. Een blok van 4 KiB bevat 4.096 bytes, oftewel acht traditionele sectoren van 512 bytes. Binaire groottes gebruiken KiB, MiB en GiB; overdrachtssnelheden zoals MB/s gebruiken decimale miljoenen bytes per seconde.
Het onderwijsontwerp vsfs, het zeer eenvoudige bestandssysteem, bevat deze structuren:
| Structuur | Opgeslagen informatie |
|---|---|
| Superblok | Bestandssysteemgrootte, locaties van gebieden, aantal inodes en identificerend speciaal getal |
| Inodebitmap | Eén toewijzingsbit per inode |
| Gegevensbitmap | Eén toewijzingsbit per gegevensblok |
| Inodetabel | Metadata en gegevenspointers voor elke inodeplaats |
| Gegevensgebied | Inhoud van gewone bestanden en directory's |
Een bitmapbit van 1 betekent toegewezen; 0 betekent vrij. Het superblok vertelt het besturingssysteem bij het aankoppelen hoe het de rest van de partitie moet interpreteren. De twee bitmaps beschrijven verschillende bronnen: een bestand kan een toegewezen inode hebben voordat het gegevensblokken heeft.
Zoek een inode op nummer
Neem een partitie van 64 blokken met blokken van 4 KiB. Plaats het superblok op blok 0, de inodebitmap op 1, de gegevensbitmap op 2 en de inodetabel in blokken 3–7. Gegevens bezetten blokken 8–63. Vijf inodetabelblokken met inodes van 256 bytes bevatten 80 inodes, omdat elk blok er 16 bevat. Er zijn 56 gegevensblokken. Eén bitmap van 4 KiB kan 32.768 objecten beschrijven, dus blijft in deze zeer kleine indeling een groot deel van elke bitmap ongebruikt.
Als je inodeplaatsen vanaf nul nummert, begint inode 37 op 37 × 256 = 9.472 bytes na het begin van de tabel. De tabel begint op byte 12.288, wat een absoluut byteadres van 21.760 geeft. Deling door 4.096 geeft schijfblok 5 met rest 1.280. Deling door 512 geeft sector 42 met rest 256. Lees het blok of de sector waarin de inode staat en selecteer daarbinnen de bytes van de inode.
De algemene methode is: het begin van de tabel in bytes plus het inodenummer maal de inodegrootte. Houd het beginadres van de tabel apart van de positie van de inode binnen de tabel. Als je dat basisadres weglaat, vind je het verkeerde schijfblok.
Scheid namen, metadata en inhoud
Een inode, of indexknoop, registreert type, toegangsrechten, eigenaar, grootte, tijdstempels, het aantal harde koppelingen, toegewezen blokken en gegevenslocaties. De inode bevat niet de bestandsnaam. De naam hoort in een directoryvermelding, waardoor meerdere namen één inode kunnen delen.
Een directory heeft een inode van het type directory en gegevensblokken met vermeldingen. Een eenvoudige vermelding bevat een inodenummer, recordlengte, naamlengte en naam. Dankzij de recordlengte kan het systeem bij het doorlopen de hele vermelding overslaan, inclusief herbruikbare ruimte die na verwijderen is achtergelaten. Grote directory's hebben baat bij indexen: XFS gebruikt B-bomen en ext4 gebruikt gehashte boomindexen.
Bij het aanmaken van een bestand zoekt het systeem een vrij bit in de inodebitmap en zet het dat bit. Bij het toewijzen van gegevens verandert op dezelfde manier de gegevensbitmap. Een allocator kan een reeks blokken reserveren zodat het bestand aaneengesloten kan groeien. De bitmap geeft aan of een blok vrij is; de inode geeft aan bij welk bestand het hoort. Deze structuren moeten overeenkomen.
Belangrijkste punten
- Het superblok beschrijft de indeling; bitmaps houden toewijzingen bij.
- Een inode bevat metadata en gegevenslocaties, terwijl directory's namen bevatten.
- Bereken een inodeadres uit de tabelbasis, het inodenummer en de inodegrootte.
- Inodetoewijzing en gegevenstoewijzing gebruiken afzonderlijke bitmaps.
2.2 Vind de gegevens van een bestand met pointers, indirecte blokken en extents
Een programma ziet opeenvolgende byteposities, maar de bijbehorende gegevensblokken kunnen over de schijf verspreid liggen. Het bestandssysteem heeft voor elk logisch bestandsblok een koppeling naar de fysieke locatie nodig.
Volg directe en indirecte pointers
Een directe pointer in een inode duidt één gegevensblok aan. Bij blokken van 4 KiB ligt bytepositie 10.000 in logisch blok 2, omdat twee volledige blokken 8.192 bytes gebruiken. De positie binnen dat blok is 1.808. Logische blokken beginnen bij 0, dus gebruikt blok 2 de derde directe pointer.
Een indirecte pointer duidt een blok aan dat gegevensblokadressen bevat. Een blok van 4.096 bytes met adressen van 4 bytes bevat 1.024 pointers. Een dubbelindirecte pointer duidt een blok aan waarvan de pointers naar 1.024 indirecte blokken leiden. Driedubbele indirectie voegt nog een niveau toe. Deze index met meerdere niveaus is bewust onevenwichtig: kleine bestanden gebruiken directe pointers zonder extra pointerblokken te lezen, terwijl grote bestanden de kosten van extra niveaus dragen.
Voor een inode met 12 directe pointers en één pointer voor elk indirect niveau:
| Hoogste gebruikte niveau | Gegevenscapaciteit met blokken van 4 KiB |
|---|---|
| Alleen direct | 12 blokken = 48 KiB |
| Enkelvoudig indirect | 12 + 1.024 blokken = 4.144 KiB |
| Dubbelindirect | 12 + 1.024 + 1.024² blokken = 4.299.210.752 bytes |
| Driedubbelindirect | Voegt 1.024³ blokken toe = nog eens 4 TiB |
Dit zijn capaciteiten van deze pointerindeling. Pointerblokken nemen ook opslagruimte in, maar hun bytes zijn geen bestandsinhoud.
Tel pointerblokken voor een bestand
Een bestand van 5 MiB bezet 1.280 gegevensblokken van elk 4 KiB. Wijs de eerste 12 toe aan directe pointers. Wijs de volgende 1.024 toe aan het enkelvoudig indirecte blok. Dan blijven 244 gegevensblokken over.
Die 244 hebben een dubbelindirect wortelblok en één indirect blok daaronder nodig. In totaal heeft het bestand drie pointerblokken nodig: het enkelvoudig indirecte blok, het dubbelindirecte wortelblok en het ene kindblok daarvan. Als je alleen het dubbelindirecte wortelblok telt, mis je het kindblok dat de gegevensadressen daadwerkelijk bevat. Alle 1.024 mogelijke kindblokken tellen verspilt ruimte: alleen het benodigde kindblok wordt toegewezen.
Vergelijk extents en ketens
Een extent legt een eerste schijfblok en een reekslengte vast. Een aaneengesloten reeks van 1.000 blokken kan één extent gebruiken in plaats van 1.000 afzonderlijke pointers. Ext4, XFS en NTFS gebruiken extents. Ext4 kan maximaal vier extents in de inode bevatten en gebruikt voor meer een boom. Fragmentatie splitst reeksen en vergroot het aantal benodigde extentrecords.
Gekoppelde toewijzing volgt een keten van blokken. De bestandstoewijzingstabel (FAT) bewaart de koppelingen naar volgende blokken in een afzonderlijke tabel, die meestal in het geheugen wordt gecachet. Een directoryvermelding identificeert het eerste blok en om een later blok te bereiken moet je de eerdere koppelingen volgen. FAT gebruikt geen Unix-inodes en ondersteunt geen twee harde koppelingen naar één bestand.
| Koppeling | Belangrijkste voordeel | Belangrijkste kosten |
|---|---|---|
| Directe en indirecte pointers | Directe toegang tot kleine bestanden; schaalbare indexering | Extra pointerblokken voor grote bestanden |
| Extents | Compacte beschrijvingen van aaneengesloten reeksen | Veel records bij fragmentatie |
| FAT-ketens | Eenvoudige gekoppelde toewijzing met gecachete koppelingen | Ketendoorlopen voor toegang dicht bij het einde |
Opeenvolgende posities bewijzen nooit dat blokken fysiek aaneengesloten zijn. De allocator kiest locaties en de koppeling legt die keuzes vast.
Belangrijkste punten
- Deel een bytepositie door de blokgrootte om het logische blok te vinden, geteld vanaf nul.
- Een indirect blok bevat blokadressen; elk extra niveau vergroot het bereik met een factor.
- Tel toegewezen pointerblokken afzonderlijk van gegevensblokken.
- Extents beschrijven aaneengesloten reeksen compact.
- FAT volgt koppelingen naar volgende blokken in plaats van een Unix-inode-index.
- Logische nabijheid garandeert geen fysieke nabijheid.
2.3 Volg de schijf-I/O van bestandsbewerkingen en onderzoek het effect van caching
Eén systeemaanroep kan meerdere schijfbewerkingen vereisen, of geen enkele. Om het werk te volgen, ga je na welke structuren het bestandssysteem moet raadplegen en geef je aan welke daarvan al in de cache staan.
Doorloop een pad voordat je de inhoud leest
In het eenvoudige model zonder cache leest het openen van /docs/plan.txt vijf blokken:
- De inode van de hoofddirectory, waarvan het nummer bekend is.
- De gegevens van de hoofddirectory, om
docste vinden. - De inode van
docs. - De directorygegevens van
docs, omplan.txtte vinden. - De inode van het bestand.
Elke directory past in één blok en geen benodigd blok staat vooraf in het geheugen. Het bestandssysteem controleert de toegangsrechten en maakt een vermelding voor het geopende bestand aan. Door het openen zijn de metadata van het bestand gevonden; de inhoud is nog niet gelezen. In ext2 en ext4 wordt inodenummer 2 voor de hoofddirectory gebruikt.
In een bewust cacheloos leesmodel leest elke blokleesbewerking daarna de inode van het bestand, leest de gegevens en schrijft de toegangstijd van de inode. Twee blokken voegen zes I/O-bewerkingen toe, dus elf inclusief het openen. Sluiten vereist in dit model geen schijf-I/O. Deze aantallen beschrijven de expliciete regels van het model voor opnieuw lezen en tijdstempels; een echte cache verandert ze.
Houd bij het aanmaken rekening met toewijzing
Het aanmaken van /docs/log.txt vereist meer dan een bestaande inode vinden. In hetzelfde eenvoudige model voert het systeem vier leesbewerkingen uit voor de inodes en directorygegevens van de hoofddirectory en docs. Het lezen en schrijven van de inodebitmap voegt twee I/O-bewerkingen toe. Het bijwerken van de gegevens van docs voegt één schrijfbewerking toe. Het lezen en schrijven van de nieuwe inode voegt er twee toe en het bijwerken van de inode van docs één. Totaal: tien.
Elk nieuw toegewezen gegevensblok voegt vijf I/O-bewerkingen toe: lees en schrijf de gegevensbitmap, lees en schrijf de inode van het bestand en schrijf het gegevensblok. Twee blokken geven dus twintig I/O-bewerkingen inclusief het aanmaken. Deze telling gebruikt de eenvoudige gegevensstructuren voordat journaalverkeer of echt cachegedrag wordt meegenomen.
Een overzicht bijhouden helpt: noteer de structuur, of die wordt gelezen of geschreven en waarom. Een gegevensschrijfbewerking heeft ook een toewijzingsregistratie en een pointerwijziging nodig. Een directorywijziging verandert ook de metadata van die directory.
Laat de cache het verloop veranderen
Een cachetreffer gebruikt een blok dat al in het geheugen staat. Linux gebruikt een gezamenlijke paginacache die met virtueel geheugen wordt gedeeld, geen blijvend afzonderlijke bestandscache met een vaste grootte. Bij opnieuw openen kunnen de directory- en inodeblokken van het eerdere doorlopen opnieuw worden gebruikt. Voor het lezen van gecachete inhoud is geen leesbewerking op het apparaat nodig. Het gebruikelijke relatime-beleid van Linux voorkomt ook dat atime bij elke leesbewerking wordt geschreven.
Schrijfbuffering stelt het versturen van gewijzigde blokken naar schijf uit. Twee kort na elkaar aangemaakte bestanden kunnen dezelfde inodebitmap in het geheugen bijwerken, waarna die later één keer wordt geschreven. Het bestandssysteem kan het werk anders ordenen voor een betere doorvoer. Een kort bestaand tijdelijk bestand kan worden aangemaakt en verwijderd voordat de inhoud ooit de opslag bereikt.
Buffering verbetert de prestaties, maar laat een periode waarin gegevens nog niet duurzaam zijn opgeslagen. fsync sluit die periode voor een bestand af door op de benodigde schrijfbewerkingen te wachten. Linux O_DIRECT laat geschikte programma's de paginacache omzeilen wanneer ze hun eigen buffers beheren; een cache omzeilen is op zichzelf niet dezelfde bewerking als synchroniseren naar duurzame opslag.
Belangrijkste punten
- Volg het doorlopen van een pad afzonderlijk van het lezen van bestandsgegevens.
- I/O-aantallen hangen af van de cache-inhoud en het beleid voor tijdstempels.
- Een bestand aanmaken werkt toewijzingsgegevens, directoryvermeldingen en inodes bij.
- Schrijfbuffering combineert wijzigingen en verbetert de planning, maar stelt duurzame opslag uit.
- Een systeemaanroep komt niet overeen met een vast aantal apparaatbewerkingen.
3Leg uit hoe het Fast File System lokaliteit benut voor hogere snelheid
Een snelle interface heeft een indeling nodig die bij het opslagapparaat past. Vroege Unix-bestandssystemen verspilden bandbreedte van harde schijven aan kleine overdrachten en ver verwijderde metadata. FFS groepeert verwante objecten en weegt die lokaliteit af tegen de behoeften van grote bestanden. De plaatsingsregels en berekening van de deelgrootte laten zien hoe een ontwerp prestaties kan verbeteren terwijl programma's vertrouwde bewerkingen blijven gebruiken.
3.1 Leg uit waarom vroege Unix-bestandssystemen traag waren en hoe groepen dat verhelpen
Een harde schijf kan een lange reeks bytes snel overdragen zodra de kop die heeft bereikt. Kleine verspreide verzoeken verspillen tijd aan zoeken en wachten op rotatie. Het Fast File System verandert de plaatsing zodat gewone bestandsbewerkingen meer van de overdrachtsbandbreedte van de schijf benutten.
Onderzoek de oude Unix-indeling
De vroege Unix-indeling plaatste alle inodes dicht bij het begin en alle bestandsgegevens erna. Het lezen van een bestand kon daardoor een lange zoekbeweging van metadata naar inhoud vereisen. Een vrijelijst verspreidde toewijzingen geleidelijk naarmate bestanden werden aangemaakt en verwijderd. Zelfs een sequentieel bestand kon veel niet-aangrenzende schijftoegangen opleveren.
Kleine blokken van 512 bytes maakten dit erger. Elke positioneringsvertraging leverde slechts een korte overdracht op voordat het volgende verzoek weer een zoekbeweging of rotatie nodig had. Historische metingen wezen uit dat het oude ontwerp soms maar 2% van de schijfbandbreedte haalde. Dat cijfer beschrijft het gemeten vroege ontwerp, geen vaste grens van Unix-interfaces.
Het Fast File System (FFS), begin jaren 1980 ontwikkeld in Berkeley, behield vertrouwde aanroepen zoals open, read en write, terwijl het de indeling en het toewijzingsbeleid veranderde. Grotere blokken, meestal 4 KiB, verhoogden het aantal overgedragen bytes per verzoek. Door metadata en inhoud dicht bij elkaar te houden, werd de afstand tussen verwante verzoeken kleiner.
Bouw groepen met eigen bronnen
Een cilinder is de verzameling sporen op dezelfde straal over de schijfoppervlakken. FFS vormt cilindergroepen uit naast elkaar gelegen cilinders. De inode en gegevens van een bestand kunnen in dezelfde groep staan, waardoor een zoekbeweging van metadata naar gegevens kort blijft.
Elke groep bevat een kopie van het superblok, eigen bitmaps voor inode- en gegevenstoewijzing, een deel van de inodetabel en gegevensblokken. De groep lijkt op een klein bestandssysteem, maar alle groepen horen bij één bestandssysteem. Een kopie van het superblok helpt ook bij herstel als één kopie beschadigd is. Ext4 bewaart kopieën in geselecteerde groepen in plaats van in elke groep.
Moderne schijven verbergen hun fysieke geometrie. Ext2, ext3 en ext4 gebruiken daarom blokgroepen, reeksen opeenvolgende logische blokadressen, om hetzelfde lokaliteitsdoel na te streven zonder van exacte cilinders afhankelijk te zijn.
Volg het aanmaken van een klein bestand
Het aanmaken van /docs/a.txt vereist een vrije inode, een gegevensblok, wijzigingen in toewijzingsbitmaps en een nieuwe directoryvermelding. FFS probeert het bestand in de groep van de bovenliggende directory te plaatsen. De nieuwe inode, bestandsgegevens, bitmaps en directorywijzigingen kunnen dan dicht bij elkaar liggen.
De bewerking vereist nog steeds meerdere afzonderlijke wijzigingen. Groeperen bespaart positioneringstijd; het brengt niet alle metadata en gegevens samen in één blok. Een indeling die rekening houdt met de schijf verlaagt de kosten om die structuren te bereiken zonder de bestandsbewerkingen van het programma te veranderen.
| Opslageigenschap | Gevolg voor plaatsing |
|---|---|
| Zoekbeweging en rotatie van een harde schijf | Nabije blokken voorkomen herhaalde lange positioneringsvertragingen |
| Hoge sequentiële overdrachtssnelheid | Grotere verzoeken verplaatsen meer bytes per vertraging |
| SSD zonder zoekbeweging of rotatie | Afstand is veel minder belangrijk, maar verzoekgrootte en schrijfgedrag blijven belangrijk |
Belangrijkste punten
- Lange zoekbewegingen, fragmentatie en kleine blokken beperkten de schijfdoorvoer van vroege Unix-systemen.
- FFS-groepen plaatsen inodes, toewijzingsbitmaps en gegevens dicht bij elkaar.
- Moderne blokgroepen behouden lokaliteit zonder de fysieke schijfgeometrie nodig te hebben.
- FFS verbetert de plaatsing met behoud van de bestaande bestandsinterface.
3.2 Pas de plaatsingsregels van FFS toe en bepaal de deelgroottes voor grote bestanden
FFS gebruikt namen als aanwijzing voor welke bestanden een programma samen zal gebruiken. Het begrenst ook hoeveel ruimte één groot bestand in een groep kan innemen en weegt zo lokaliteit af tegen ruimte voor toekomstige toewijzingen.
Plaats directory's en bestanden
Een nieuwe directory komt in een groep met relatief weinig directory's en veel vrije inodes. Dit spreidt verschillende directory's en laat tegelijk ruimte voor hun toekomstige bestanden. De inode van een gewoon bestand komt in de groep van de bovenliggende directory en de gegevens komen dicht bij de inode.
Voor /a/b, /a/c en /a/d worden de drie bestanden dicht bij directory /a geplaatst. Een bestand /b/f volgt de eigen bovenliggende directory /b, meestal naar een andere groep. Dit benut lokaliteit in de naamruimte: een compiler die aan één project werkt, opent vaak meerdere bestanden in dezelfde directory. De directoryrelatie voorspelt toegangspatronen; ze garandeert niets voor elk afzonderlijk programma.
Maak een uitzondering voor een groot bestand
Eén groot bestand zou de vrije blokken van de groep kunnen opgebruiken en alle latere naburige bestanden naar elders verdringen. FFS houdt het eerste deel, bereikbaar via 12 directe pointers, in de groep van de inode. Bij blokken van 4 KiB is dat 48 KiB. Latere delen, elk bereikbaar via een indirect blok met 1.024 pointers, beslaan 4 MiB aan gegevens en gaan naar andere weinig gebruikte groepen.
Dit offert enige lokaliteit binnen het grote bestand op om lokaliteit voor de andere bestanden van de directory te behouden. Het grote bestand krijgt tussen delen een positioneringsvertraging, dus moet elk deel groot genoeg zijn om die kosten de moeite waard te maken.
Leid de deelgrootte af
Stel dat positionering T seconden duurt en de overdrachtssnelheid R bytes per seconde is. De overdracht van een deel C duurt C/R seconden. De fractie van de totale tijd die aan overdracht wordt besteed, is:
Oplossen geeft:
Bij 100 MB/s met 10 ms positionering is R maal T gelijk aan 1 MB. Een deel van 1 MB vereist 10 ms overdracht plus 10 ms positionering, wat 50% van de maximale bandbreedte geeft. Voor 90% vermenigvuldig je 1 MB met 0,9/0,1 om 9 MB te krijgen. Voor 99% is de vermenigvuldigingsfactor 99, wat 99 MB geeft. Zet milliseconden om naar seconden voordat je met MB/s vermenigvuldigt. De noemer bevat zowel overdrachts- als positioneringstijd; alleen door de overdrachtstijd delen zou de overhead verbergen.
Overdrachtssnelheden zijn sneller verbeterd dan positioneringsvertragingen, dus zijn grotere delen nodig om dezelfde fractie van het maximum te bereiken naarmate het verschil groter wordt.
Laat kleine bestanden passen en behoud compatibiliteit
FFS gebruikte ook deelblokken van 512 bytes zodat kleine bestanden geen heel blok van 4 KiB verspilden. Groeiende bestanden werden naar volledige blokken gekopieerd; de C-bibliotheek bufferde schrijfbewerkingen in stukken van 4 KiB om herhaald verplaatsen te verminderen. Historische parameterisatie liet rotatietussenruimten tussen opeenvolgende blokken, zodat een opgevraagd volgend blok de kop nog niet was gepasseerd. Moderne spoorbuffers maken die techniek overbodig door intern een spoor op te halen.
Lange namen, symbolische koppelingen en atomaire rename waren extra mogelijkheden van FFS. Voor de snelheidswinst door de indeling zelf hoefden bestaande programma's niet te worden gewijzigd.
Belangrijkste punten
- FFS gebruikt een directory als aanwijzing dat de bestanden erin samen worden gebruikt.
- Directory's worden over groepen verspreid; hun gewone bestanden blijven in de buurt.
- Delen van grote bestanden worden verspreid om ruimte te laten voor naburige bestanden.
- Neem positionerings- en overdrachtstijd mee bij het berekenen van de effectieve bandbreedte.
- Deelblokken verminderen ruimteverspilling bij kleine bestanden; spoorbuffering vervangt het afstemmen van rotatietussenruimten.
- FFS voegde mogelijkheden toe en versnelde bestaande aanroepen.
4Zorg dat een bestandssysteem na crashes consistent kan worden hersteld
Een crash kan één logische bestandsbewerking tussen meerdere fysieke schrijfbewerkingen onderbreken. Vergelijk de toestanden die een onvoltooide toevoeging achterlaat en onderzoek daarna hoe een controleprogramma metadata herstelt en hoe een journaal herstel laat afhangen van geregistreerde transacties. De volgorde van gegevens en hergebruik van blokken laten zien waarom een geldige vastlegging meer nodig heeft dan een markering. Andere ontwerpen voor consistentie lossen hetzelfde probleem op met andere kosten.
4.1 Leg het probleem van consistentie na een crash uit
Voor een programma lijkt één toevoeging één handeling. Op schijf verandert die meerdere structuren en een crash kan ertoe leiden dat slechts enkele daarvan zijn bijgewerkt. Consistentie na een crash gaat over de vraag hoe die gedeeltelijke resultaten kunnen worden voorkomen of hersteld.
Volg drie onafhankelijke schrijfbewerkingen
Eén blok van 4 KiB aan een bestaand bestand toevoegen verandert:
- Db, het nieuwe gegevensblok met de toegevoegde bytes.
- I, de inode met een grotere grootte en een pointer naar dat blok.
- B, de gegevensbitmap die het blok als toegewezen markeert.
Als alle drie de opslag bereiken, ontstaat de bedoelde consistente wijziging. Als geen ervan de opslag bereikt, blijft de oude consistente toestand bestaan. Het gevaar zit in de zes gedeeltelijke combinaties. Het apparaat kan verzoeken anders ordenen, dus als je ze in een bepaalde volgorde uitgeeft zonder te wachten, bepaalt dat niet de volgorde waarin ze worden voltooid.
Classificeer elke gedeeltelijke uitkomst
| Schrijfbewerkingen die behouden blijven | Resultaat |
|---|---|
| Alleen Db | Nieuwe bytes bestaan, maar geen pointer bereikt ze; de oude bestandssysteemtoestand blijft consistent |
| Alleen I | De inode verwijst naar oude inhoud en de bitmap noemt het blok nog vrij |
| Alleen B | Een toegewezen blok heeft geen eigenaar: een lek in de opslagruimte |
| I en B | Metadata komen overeen, maar het nieuwe bestandsgebied bevat oude inhoud |
| I en Db | Het bestand verwijst naar geldige nieuwe gegevens die de bitmap nog vrij noemt |
| B en Db | Nieuwe bytes zijn toegewezen maar onbereikbaar: verloren gegevens en gelekte ruimte |
Een inconsistentie ontstaat wanneer metadata niet overeenkomen, bijvoorbeeld als een inode een blok claimt waarvan het toewijzingsbit vrij aangeeft. De allocator kan datzelfde blok dan aan een ander bestand geven. Een lek in de opslagruimte reserveert opslag die geen bestand kan bereiken. Ongeldige bestandsinhoud kan moeilijker te detecteren zijn: I en B komen volledig overeen, hoewel Db nooit is aangekomen.
Alleen Db laat geen toegewezen ruimte lekken, omdat de bitmap nog toestaat dat het blok opnieuw wordt gebruikt. Bytes naar een vrije locatie schrijven is niet hetzelfde als die toewijzen. Alleen B laat wel ruimte lekken, omdat de toewijzing behouden is gebleven zonder pointer van een eigenaar.
Scheid structuur van betekenis
Een controleprogramma kan pointers met bitmaps vergelijken. Het kan doorgaans niet vaststellen of aannemelijke bytes de bytes zijn die een programma wilde opslaan. De uitkomst met I en B laat deze grens zien: een structureel geldig bestand kan onjuiste inhoud hebben.
De gewenste overgang is atomair voor de hele wijziging: herstel naar de volledige oude toestand of de volledige nieuwe toestand. Een eenvoudig opslagmodel biedt alleen atomaire schrijfbewerkingen voor één sector, traditioneel 512 bytes. Meerdere bestandssysteemblokken overschrijden die eenheid, dus moet het bestandssysteem een sterker protocol opbouwen. De garanties voor atomaire schrijfbewerkingen van echte apparaten hangen af van het apparaat en de interface; het journaalprotocol moet zijn vastleggingsrecord binnen de ondersteunde atomaire eenheid laten passen.
Buffering vergroot het aantal wijzigingen dat verloren kan gaan, maar is niet de hoofdoorzaak. Zelfs als je elke schrijfbewerking onmiddellijk uitgeeft, kan een crash tussen afzonderlijke voltooiingen optreden. Een bestand aanmaken, hernoemen en verwijderen verandert ook meerdere structuren. Om de mogelijke fouttoestanden te begrijpen, begin je met dezelfde oefening: bepaal elk gewijzigd blok en vraag wat er gebeurt als slechts een deel behouden blijft.
Belangrijkste punten
- Eén logische bestandsbewerking kan meerdere onafhankelijk voltooide blokschrijfbewerkingen vereisen.
- Vergelijk gegevens, inodepointers en toewijzingsbits na elk mogelijk crashmoment.
- Consistente metadata kunnen nog steeds naar onjuiste bestandsinhoud verwijzen.
- Atomiciteit voor meerdere blokken vereist een bestandssysteemprotocol boven op één atomaire schrijfbewerking van het apparaat.
4.2 Controleer en herstel een bestandssysteem met fsck
Een bestandssysteemcontrole herstelt relaties tussen opgeslagen structuren nadat schade is ontstaan. De kracht is een breed overzicht van metadata; de zwakke punten zijn de kosten van het doorzoeken en het gebrek aan kennis over de bedoelde bestandsinhoud.
Reconstrueer het toewijzingsoverzicht
fsck, de bestandssysteemcontrole, onderzoekt een onzuiver afgesloten bestandssysteem voordat het normaal wordt aangekoppeld. Het controleert of de grootte en aantallen in het superblok redelijk zijn en kan een reservesuperblok gebruiken als de hoofdkopie beschadigd is.
Daarna doorzoekt het inodes en indirecte blokken om te bepalen naar welke gegevensblokken bestanden daadwerkelijk verwijzen. Uit die informatie over eigenaarschap bouwt het de toewijzingsbitmaps opnieuw op. Als een verder geldige inode naar blok 74 verwijst terwijl de bitmap 74 vrij noemt, moet de bitmap worden gewijzigd naar toegewezen. Als het systeem alleen op de bitmap zou vertrouwen, zou een latere toewijzing de bestandsgegevens kunnen overschrijven.
De omgekeerde afwijking is een bitmapbit dat als toegewezen is gemarkeerd zonder pointer vanuit een inode die eigenaar is. Door de bitmap te reconstrueren kan die ruimte weer beschikbaar komen. Herstel kiest een consistente relatie; het kan geen willekeurige ontbrekende toepassingsbytes reconstrueren.
Controleer objecten, namen en koppelingen
Elke toegewezen inode heeft een geldig type nodig, zoals gewoon bestand, directory of symbolische koppeling. Een inode die niet kan worden hersteld, wordt gewist en de toewijzingsgegevens worden aangepast.
Door vanaf de hoofddirectory te lopen kan fsck directoryverwijzingen naar elke inode tellen. Het vergelijkt deze waargenomen verwijzingen met de geregistreerde aantallen harde koppelingen en corrigeert fouten. Een toegewezen inode die geen directory bereikt, kan naar lost+found worden verplaatst. Zo krijgt herstelde inhoud een bereikbare naam zonder dat het oorspronkelijke pad bekend is.
Andere controles omvatten:
- Dubbel eigenaarschap: twee inodes claimen één gegevensblok. Een herstelactie kan één inode wissen of elk bestand een afzonderlijke kopie geven.
- Ongeldige adressen: pointers buiten het geldige bereik van het bestandssysteem moeten worden gewist.
- Directorystructuur:
.en..moeten geldig zijn en in de eenvoudige directoryindeling de eerste vermeldingen bezetten, vermeldingen moeten naar toegewezen inodes verwijzen en directory's mogen niet meerdere bovenliggende directory's hebben.
Deze controles beïnvloeden elkaar. Een ongeldige inode wissen verandert ook welke blokken toegewezen moeten zijn en welke directoryvermeldingen geldig blijven. Herstel vereist daarom een samenhangend beeld van de metadata, niet alleen een lijst verdachte afzonderlijke bits.
Begrijp wat een foutloze uitkomst vaststelt
Stel dat de inode en bitmap van een toevoeging de schijf hebben bereikt, maar de gegevens niet. De pointer ligt binnen het bereik, het toewijzingsbit is gezet en de koppelingsstructuur is geldig. fsck heeft geen afwijking in metadata om te herstellen. Het bestand kan de controle doorstaan terwijl het nieuw toegevoegde gebied oude bytes bevat.
De uitvoeringstijd hangt ook vooral af van de grootte van het bestandssysteem, niet van de hoeveelheid die vóór een crash is gewijzigd. Een crash tijdens één wijziging van drie blokken kan nog steeds vereisen dat alle metadata worden doorzocht. Op een groot bestandssysteem kan dit minuten tot uren duren, waarbij normale toegang tijdens de controle niet beschikbaar is.
Journaalregistratie vermindert het gebruikelijke herstelwerk na een crash door recente wijzigingen te registreren. Ze maakt een controleprogramma niet overbodig: softwarefouten of falende hardware kunnen structuren beschadigen op een manier die opnieuw toepassen uit het journaal niet kan herstellen. fsck blijft voor die gevallen een herstelhulpmiddel.
Belangrijkste punten
- fsck reconstrueert toewijzing uit inodepointers en corrigeert relaties tussen metadata.
- Het doorlopen van directory's controleert aantallen harde koppelingen en vindt onbereikbare toegewezen inodes.
- De controle kan dubbel eigenaarschap en ongeldige pointers herstellen.
- Een foutloze metadatacontrole kan niet vaststellen of toepassingsbytes correct zijn.
- Het volledig doorzoeken van metadata schaalt met de grootte van het bestandssysteem, ook na een kleine onderbroken wijziging.
4.3 Bescherm wijzigingen met gegevensregistratie in een journaal en pas de wijzigingen uit het logboek opnieuw toe
Een journaal registreert een wijziging voordat het bestandssysteem de gewone locaties overschrijft. Na een crash vertelt die registratie het herstelproces welke volledige wijzigingen opnieuw kunnen worden uitgevoerd. Dit is voorafgaande logregistratie. Ext3, ext4, XFS en NTFS gebruiken journaalregistratie, hoewel hun exacte logboekformaten verschillen.
Beschrijf een wijziging als een transactie
Voor een toevoeging registreert gegevensregistratie in een journaal kopieën van de nieuwe inode I, bitmap B en het gegevensblok Db. Een transactiebeginrecord, TxB, bevat een ID en de definitieve bestemmingen van de blokken. Een transactie-eindrecord, TxE, bevat de bijbehorende ID en markeert de vastlegging.
Volledige vervangende blokinhoud registreren is fysieke logregistratie. In plaats daarvan een bewerkingsbeschrijving registreren is logische logregistratie. Fysiek opnieuw uitvoeren heeft een nuttige eigenschap: dezelfde inhoud opnieuw naar hetzelfde adres schrijven heeft hetzelfde effect. Herstel kan daarom het overbrengen naar de definitieve locatie herhalen als dat vóór de crash gedeeltelijk was voltooid.
Leg vast na de inhoud
Het basisprotocol heeft vier fasen:
- Schrijven naar het journaal: schrijf TxB en I, B en Db naar het journaal en wacht tot ze duurzaam zijn opgeslagen.
- Vastleggen: schrijf TxE en wacht. De transactie is nu vastgelegd.
- Overbrengen: kopieer I, B en Db vanuit het journaal naar hun definitieve locaties.
- Vrijgeven: geef de journaalruimte van die transactie vrij voor later hergebruik.
TxE mag niet duurzaam worden opgeslagen vóór de inhoud van de transactie. Als alle vijf blokken zonder volgordegarantie zouden worden uitgegeven, zou een apparaat TxB en TxE kunnen voltooien terwijl Db ongeschreven blijft. Herstel zou een onvolledige transactie voor een geldige aanzien. In het basismodel past TxE binnen één atomaire sectorschrijfbewerking, zodat het als volledig vastleggingsrecord aanwezig of afwezig is.
Schrijfcaches van apparaten moeten de duurzaamheidsgrens ook respecteren. Cacheleegmaak- of geforceerde schrijfbewerkingen voorkomen dat een vluchtige apparaatcache het protocol laat geloven dat de inhoud veilig is terwijl stroomuitval die nog kan wissen.
Herstel van twee crashmomenten
Een crash na de inhoud maar vóór TxE laat een niet-vastgelegde transactie achter. Herstel negeert die en behoudt de oude bestandstoestand.
Een crash na TxE maar tijdens het overbrengen naar de definitieve locaties laat een vastgelegde transactie achter. Herstel schrijft alle blokinhoud op volgorde naar de definitieve locaties. Sommige schrijfbewerkingen herhalen mogelijk al uitgevoerd werk, wat voor deze blokinhoud geen kwaad kan. Dit is herstel door opnieuw uitvoeren. Journaalruimte kan pas opnieuw worden gebruikt als de vastgelegde blokinhoud de definitieve locaties heeft bereikt.
Het journaal is een circulair logboek. Het superblok houdt het actieve bereik bij, zodat vrijgekomen ruimte opnieuw kan worden gebruikt. Door meerdere wijzigingen in één transactie te bundelen kan één gedeeld directoryblok of één bitmap één keer worden geregistreerd. Het standaardinterval voor vastlegging in ext4 is 5 seconden, dus volgt vastlegging niet automatisch onmiddellijk op elke schrijfbewerking van een toepassing.
Scheid controlesommen van duurzaamheid
Een transactiecontrolesom kan ontbrekende of gedeeltelijk geschreven inhoudsblokken onthullen, ook wanneer een vastleggingsrecord aanwezig is. Een protocol op basis van controlesommen kan journaalschrijfbewerkingen samen uitgeven en alleen transacties accepteren waarvan de controle slaagt. Controlesommen detecteren onvolledige records; cacheleegmaakbewerkingen bepalen of bevestigde bytes werkelijk behouden blijven.
Een gebufferde, niet-vastgelegde schrijfbewerking van een toepassing kan nog steeds verdwijnen. Een programma dat duurzame voltooiing vereist, gebruikt fsync en controleert of dat lukt.
Belangrijkste punten
- Voorafgaande logregistratie registreert volledige wijzigingen voordat hun definitieve locaties worden gewijzigd.
- In het basisprotocol wordt de inhoud duurzaam opgeslagen vóór het vastleggingsrecord.
- Herstel voert vastgelegde transacties opnieuw uit en negeert niet-vastgelegde transacties.
- Identieke blokinhoud opnieuw schrijven is veilig na gedeeltelijke overbrenging naar de definitieve locatie.
- Het overbrengen naar de definitieve locatie moet zijn voltooid voordat journaalruimte opnieuw wordt gebruikt.
- Bundeling vermindert metadataverkeer, terwijl
fsyncde benodigde duurzaamheid vastlegt.
4.4 Verlaag de kosten van journaalregistratie en vergelijk andere benaderingen
Gegevensregistratie in een journaal schrijft bestandsinhoud naar het journaal en daarna naar de definitieve locaties. Alleen metadata in het journaal registreren vermindert dat verkeer, maar de volgorde van gegevens en metadata bepaalt nog steeds wat na herstel zichtbaar kan worden.
Zorg dat gegevens vóór vastgelegde pointers komen
Bij geordende metadataregistratie in een journaal gaat Db rechtstreeks naar de definitieve locatie. TxB, I en B gaan naar het journaal. Deze twee groepen schrijfbewerkingen kunnen parallel lopen, maar beide moeten voltooid zijn voordat TxE de metadata vastlegt. Na vastlegging kunnen I en B naar de definitieve locaties worden overgebracht en kan de journaalruimte worden vrijgegeven.
De afhankelijkheid is de kern: het blok dat een pointer aanduidt, moet gereed zijn voordat die pointer kan worden hersteld. Als I eerst wordt vastgelegd, kan herstel een geldige pointer installeren naar bytes die zijn achtergelaten door een eerdere gebruiker van het blok. De metadata zouden overeenkomen zonder dat de bedoelde gegevens aanwezig zijn.
| Ext4-modus | Wat in het journaal komt | Regel voor gegevens vóór vastlegging |
|---|---|---|
data=journal | Gegevens en metadata | Gegevens maken deel uit van de geregistreerde transactie |
data=ordered | Metadata | Gegevens waarnaar wordt verwezen bereiken vóór vastlegging hun definitieve plaats |
data=writeback | Metadata | Geen dergelijke garantie voor de volgorde van gegevens |
De geordende modus is de standaard. Alleen metadata in een journaal registreren betekent niet dat de geordende modus wordt gebruikt: de modus met ongeordend terugschrijven kan structureel correcte bestanden met verouderde inhoud herstellen. De modus met gegevensregistratie in een journaal laat het volledige protocol zien, maar kost een tweede schrijfbewerking voor de bestandsgegevens.
Voorkom dat opnieuw toepassen een hergebruikt blok beschadigt
Directory-inhoud telt als metadata. Stel dat een directoryblok op adres 1000 wordt geregistreerd, waarna de directory wordt verwijderd en hetzelfde adres gewone bestandsgegevens gaat bevatten. Die nieuwe gebruikersgegevens worden in de modus met alleen metadataregistratie niet geregistreerd. Als de oude directory-inhoud na een crash opnieuw wordt toegepast, overschrijft die de bytes van het nieuwe bestand.
Een vastgelegd intrekkingsrecord vertelt het herstelproces geregistreerde kopieën van dat blok uit transacties tot en met de intrekkende transactie over te slaan. Het verbiedt niet elk toekomstig gebruik van het adres. Als een latere transactie dat blok opnieuw registreert, kan de latere blokinhoud nog steeds opnieuw worden toegepast. Deze tijdsgrens onderscheidt intrekking van het permanent als onbruikbaar markeren van een blok.
Vergelijk alternatieven
Soft updates dwingen afhankelijkheden tussen gewone schrijfbewerkingen af zonder journaal. Door geïnitialiseerde gegevens vóór een pointer te schrijven, voorkom je bereikbare ongeldige inhoud, hoewel onderbroken bewerkingen ruimte kunnen laten lekken die een latere achtergrondcontrole weer beschikbaar maakt. FFS van FreeBSD gebruikt deze aanpak. Alle afhankelijkheden bijhouden maakt implementatie moeilijk.
Kopiëren bij schrijven schrijft gewijzigde blokken naar ongebruikte locaties en gebruikt een atomaire omschakeling van de wortelpointer om de nieuwe boom beschikbaar te maken. De oude boom blijft tot de omschakeling beschikbaar. ZFS, Btrfs en WAFL gebruiken verwante ontwerpen; oude blokken behouden maakt ook momentopnamen mogelijk.
Onderzoeksontwerpen op basis van terugverwijzingen registreren eigenaarschap van gegevens terug naar inodes, zodat onvolledige wijzigingen detecteerbare afwijkingen achterlaten. Optimistische consistentie na een crash vermindert het wachten en gebruikt controlesommen en andere controles om onvoltooid werk te detecteren. Elke aanpak weegt schrijfverkeer, herstelgaranties en implementatiecomplexiteit tegen elkaar af. Geordende metadataregistratie in een journaal houdt herstel kort en schrijft gewone bestandsgegevens één keer.
Belangrijkste punten
- Geordende journaalregistratie stuurt gegevens naar definitieve locaties voordat de metadatapointers worden vastgelegd.
- Alleen metadata in een journaal registreren en geordende journaalregistratie zijn geen synoniemen.
- Intrekkingsrecords voorkomen dat verouderde geregistreerde blokinhoud hergebruikte blokken overschrijft.
- Soft updates ordenen afhankelijkheden; kopiëren bij schrijven maakt een nieuwe boom beschikbaar.
- Minder schrijfverkeer kan zorgvuldiger ordening of controle vereisen.
5Leg uit hoe een loggestructureerd bestandssysteem schrijft en ruimte vrijmaakt
Sequentiële schrijfbewerkingen benutten een schijf goed, maar elk gewijzigd blok verplaatsen veroorzaakt nieuwe problemen bij het opzoeken en beheren van ruimte. Volg LFS van gebufferde segmenten via de inodevertaaltabel en het checkpointgebied en bekijk daarna hoe de segmentopruimer nog gebruikte blokken vindt en vrije segmenten terugwint. Herstel moet de nieuwste geldige koppeling terugvinden zonder een onderbroken checkpoint voor een volledig checkpoint aan te zien.
5.1 Schrijf sequentieel in segmenten en vind inodes via de inodevertaaltabel
Een loggestructureerd bestandssysteem zet verspreide kleine wijzigingen om in grote sequentiële schrijfbewerkingen. Dit helpt bij een schijf met een hoge overdrachtssnelheid waarvan zoek- en rotatievertragingen kostbaar blijven.
Verzamel wijzigingen in een segment
LFS van Berkeley, ontwikkeld door Rosenblum en Ousterhout en gepubliceerd in 1991, ging uit van veranderende werklasten. Grotere geheugens handelden meer leesbewerkingen af vanuit de cache, waardoor schrijfbewerkingen een groter aandeel van het schijfverkeer vormden. De sequentiële bandbreedte groeide sneller dan de positioneringssnelheid. FFS had voor het aanmaken van een klein bestand nog steeds meerdere korte schrijfopdrachten voor metadata en gegevens nodig, en kleine schrijfbewerkingen werkten ook slecht met RAID met pariteit.
LFS buffert gewijzigde gegevens, inodes en vertaaltabelinformatie samen in het geheugen. Het schrijft ze als één groot segment naar een ongebruikt schijfgebied. Een blok bijwerken maakt een nieuwe versie op een nieuw adres; de vorige versie blijft fysiek aanwezig totdat het opruimen het segment vrijmaakt.
Segmenten amortiseren positioneringskosten net als grote delen bij FFS. Bij snelheid R, positioneringstijd T en gewenste overdrachtstijdfractie F is de gebufferde grootte:
Bij 200 MB/s en 5 ms vereist 95% een grootte van 19 MB. De overdracht duurt 95 ms, de positionering 5 ms en de effectieve snelheid is 19 MB per 0,1 s = 190 MB/s. Een hoge doelfractie kan een segment vereisen dat groter is dan de gebruikelijke honderden kilobytes tot enkele megabytes. De vereiste grootte volgt uit het apparaat en het doel, niet uit het woord “segment”.
Zoek een inode die blijft verplaatsen
De formule met een vaste inodetabel werkt niet meer: elke inodewijziging wordt op een nieuw adres geschreven. LFS voegt een inodevertaaltabel, of imap, toe die elk inodenummer aan het nieuwste schijfadres koppelt. Bijgewerkte imap-delen worden in het logboek geschreven naast de inodes die ze beschrijven.
Een vast checkpointgebied (CR) legt vast waar de nieuwste imap-delen staan. Het wordt periodiek bijgewerkt, bijvoorbeeld om de 30 seconden, zodat de incidentele schrijfbewerking op een vaste locatie het verkeer niet overheerst.
De opzoekketen is:
- Lees bij het aankoppelen de CR om de huidige imap-delen te vinden.
- Laad de imap in het geheugen.
- Zoek het gevraagde inodenummer op in de imap.
- Lees die nieuwste inode en volg de gegevenspointers.
Zodra de imap in de cache staat, gebruiken gewone bestandsleesbewerkingen vrijwel hetzelfde pad van inode naar gegevens als in FFS. De extra vertaalslag maakt verplaatsing betaalbaar zonder de stabiele identiteit van het bestand te veranderen.
Houd directoryvermeldingen stabiel
Een directory bewaart namen en inodenummers. Als /docs/report.txt wordt gewijzigd, verplaatst de inode maar behoudt die het nummer. De imap verandert; de directoryvermelding hoeft niet alleen door die verplaatsing te veranderen.
Zonder deze indirecte verwijzing zou een directory met fysieke inodeadressen telkens opnieuw moeten worden geschreven wanneer een onderliggende inode verplaatst. De eigen inode zou dan verplaatsen, wat een wijziging in de bovenliggende directory afdwingt, enzovoort tot aan de hoofddirectory. De imap doorbreekt dit recursieve wijzigingsprobleem.
LFS maakt schrijfbewerkingen sequentieel, niet alle leesbewerkingen. De ongewijzigde blokken van een bestand kunnen in oudere segmenten blijven terwijl latere versies van andere blokken naar elders verplaatsen. Voor het lezen van dat bestand kunnen nog steeds zoekbewegingen tussen segmenten nodig zijn; grote geheugencaches maken deel uit van de motivatie voor het ontwerp.
Belangrijkste punten
- LFS schrijft gebufferde gegevens en metadata samen in grote segmenten naar ongebruikte ruimte.
- De imap koppelt stabiele inodenummers aan veranderende inodeadressen.
- Het vaste checkpointgebied geeft aan waar de nieuwste imap-delen staan.
- Directoryvermeldingen behouden inodenummers en voorkomen zo dat bovenliggende directory's recursief worden herschreven.
- De segmentgrootte moet positioneringskosten amortiseren; leesbewerkingen kunnen nog steeds verspreid zijn.
5.2 Maak ruimte vrij met de segmentopruimer en herstel na een crash
Door nieuwe versies naar ongebruikte locaties te schrijven blijven oude bytes fysiek aanwezig. LFS moet oude onbereikbare versies onderscheiden van nog gebruikte blokken, grote vrije gebieden terugwinnen en na een crash een bruikbare koppeling herstellen.
Ruim hele segmenten op
De segmentopruimer leest gedeeltelijk bezette segmenten, kopieert hun nog gebruikte blokken naar een kleiner aantal nieuwe segmenten en geeft de oude segmenten vrij. Als vier even grote segmenten elk voor een kwart nog gebruikte gegevens bevatten, vullen die gegevens samen één nieuw segment. Door de vier oude segmenten na het kopiëren vrij te geven win je drie segmenten aan bruikbare capaciteit.
Door hele segmenten op te ruimen blijven grote aaneengesloten gebieden behouden voor toekomstige sequentiële schrijfbewerkingen. Kopiëren heeft kosten: nog gebruikte blokken worden opnieuw gelezen en geschreven, ook als geen toepassing ze heeft gewijzigd. Bij een bijna volle schijf met voornamelijk nog gebruikte segmenten kan veel kopiëren nodig zijn om weinig vrije ruimte terug te winnen.
Bepaal of een blok nog wordt gebruikt
Een segmentoverzicht identificeert voor elk blok de inode van de eigenaar en de positie van het logische bestandsblok. Om een blok op adres A te testen, gebruik je de imap om de nieuwste inode van die eigenaar te vinden. Volg de pointer voor het vastgelegde logische blok. Als de pointer nog gelijk is aan A, is dit de gebruikte versie. Als die naar elders verwijst, is A verouderd.
Een overzicht koppelt bijvoorbeeld adres 600 aan inode 14, logisch blok 2. De huidige inode 14 laat logisch blok 2 naar adres 920 wijzen. Blok 600 is ongebruikt, ook als de bytes op geldige gegevens lijken. Of een blok nog wordt gebruikt, hangt af van de huidige bereikbaarheid, niet van hoe recent het is geschreven of of de inhoud nuttig lijkt.
Versienummers versnellen het uitsluiten. Een bestand verwijderen of tot nul inkorten verhoogt het versienummer van dat bestand in de imap. Een segmentblok met een oudere versie kan als ongebruikt worden aangemerkt zonder de inode te lezen.
Het opruimbeleid houdt ook rekening met verwachte wijzigingen. Hete segmenten bevatten vaak overschreven blokken; door te wachten kunnen meer van hun blokken ongebruikt raken zonder te kopiëren. Koude segmenten veranderen weinig, dus ruimt het oorspronkelijke LFS-beleid ze eerder op. Het beleid moet de gebruikte fractie, de leeftijd en de beschikbare ruimte tegen elkaar afwegen; alleen de temperatuur van een segment meet niet de directe kopieerkosten.
Herstel de koppeling en recent werk
LFS bewaart twee checkpointgebieden aan tegenoverliggende uiteinden van de schijf en werkt ze afwisselend bij. Elke wijziging schrijft een header met een tijdstempel, de inhoud en een afsluitend overeenkomstig tijdstempel. Herstel kiest het nieuwste gebied waarvan begin en einde overeenkomen. Een onderbroken nieuwere wijziging verdringt een ouder volledig checkpoint niet.
Het checkpoint bevat mogelijk niet de recentst voltooide segmenten. Daarom voert herstel voorwaarts herstel uit vanaf het daarin vastgelegde logboekeinde: het zoekt geldige latere wijzigingen en past die toe om de huidige koppeling opnieuw op te bouwen. Gegevens die nooit een geldige herstelbare wijziging vormden, kunnen na stroomuitval niet uit het geheugen worden teruggehaald.
Verwante systemen met kopiëren bij schrijven bewaren oude blokken om momentopnamen te ondersteunen; ZFS, Btrfs en WAFL delen dat algemene idee. SSD-controllers gebruiken vaak loggestructureerde flashvertaallagen, terwijl F2FS loggestructureerde ideeën op bestandssysteemniveau toepast voor flashopslag. Elk heeft nog steeds een manier nodig om ruimte van verouderde versies vrij te maken.
Belangrijkste punten
- De segmentopruimer kopieert nog gebruikte blokken naar minder segmenten en geeft de oude segmenten vrij.
- Of een blok nog wordt gebruikt, volgt uit de nieuwste inodetoewijzing, niet uit de schijnbare inhoud van het blok.
- Verschillende versienummers kunnen ongebruikte blokken snel identificeren.
- Door te wachten met het opruimen van hete segmenten kun je voorkomen dat blokken worden gekopieerd die snel verouderen.
- Herstel kiest een volledig checkpoint en voert geldig later werk voorwaarts uit.
- Opruimen voegt I/O toe en kan duur worden wanneer weinig vrije ruimte overblijft.
6Vergelijk hoe gedistribueerde bestandssystemen bestanden via een netwerk delen
Bestanden delen tussen machines brengt onzekere antwoorden en gecachete kopieën mee die kunnen verschillen. NFS laat zien hoe zelfstandige verzoeken en veilige herhalingen een soort herstel na storingen vereenvoudigen. AFS laat zien hoe het cachen van volledige bestanden en wijzigingsmeldingsbeloften serverwerk verminderen. Vergelijk hun grenzen voor het delen en de toestand bij storingen om te voorspellen wanneer een andere client een wijziging ziet en wanneer gelijktijdige wijzigingen verloren kunnen gaan.
6.1 Leg uit hoe NFS met toestandsloze verzoeken van storingen herstelt
Een gedistribueerd bestandssysteem bewaart bestanden op een server terwijl programma's op clientmachines vertrouwde bestandsaanroepen gebruiken. De client vertaalt die aanroepen naar netwerkverzoeken. Vertragingen en storingen roepen een vraag op die lokale aanroepen meestal verbergen: wat moet een client doen als die niet kan bepalen of een verzoek is voltooid?
Houd de toestand van geopende bestanden op de client
Het Network File System (NFS) van Sun begon in de jaren 1980. NFSv2 maakte de server toestandsloos voor geopende bestanden. De server slaat bestanden op, maar onthoudt niet de descriptoren of huidige bestandsposities van elke client. Elk verzoek bevat voldoende informatie om zonder een eerder openingsverzoek te worden uitgevoerd.
Een bestandshandle identificeert het servervolume, het inodenummer en de inodegeneratie. De generatie verandert wanneer een inodenummer opnieuw wordt gebruikt. Zo voorkomt die dat een oude handle per ongeluk een ander bestand op die opnieuw gebruikte plaats aanduidt.
Om /home/ana/notes.txt te openen begint de client met een handle voor de hoofddirectory en stuurt die LOOKUP voor home, ana en notes.txt. De client bewaart de resulterende handle in de eigen toestand voor geopende bestanden. De eerste 4 KiB lezen wordt een READ-verzoek met die handle, positie 0 en aantal 4096. De lokale descriptor sluiten vereist geen NFSv2-CLOSE-verzoek, omdat de server geen vermelding voor een geopend bestand heeft om vrij te geven.
Herhaal zonder een effect te herhalen
Als geen antwoord aankomt, kan de client geen onderscheid maken tussen een verloren verzoek, een onbereikbare server of een verloren antwoord. Na een time-out verstuurt de client het verzoek opnieuw.
Een bewerking is idempotent wanneer herhalen hetzelfde effect heeft als één keer uitvoeren. READ, LOOKUP en GETATTR wijzigen de opgeslagen inhoud niet. Een WRITE met een expliciete positie herhaalt in dit model ook veilig dezelfde bytes op dezelfde locatie. Een verzoek herhalen dat zegt “voeg deze bytes aan het huidige einde toe” zou daarentegen een tweede kopie toevoegen; de positie in een NFS-WRITE voorkomt die dubbelzinnigheid.
Sommige verzoeken vereisen extra zorg. Een geslaagde MKDIR opnieuw proberen nadat het antwoord verloren is gegaan, kan “bestaat al” teruggeven. De directory is aanwezig, maar het herhaalde antwoord verschilt van de oorspronkelijke bevestiging. Toestandsloos herstel maakt niet van elke bewerking een eenvoudig herhaalbaar verzoek.
Maak bevestigingen betrouwbaar
NFSv2 moet een WRITE duurzaam opslaan voordat het succes bevestigt. Anders zou de server een blok kunnen bevestigen, het tijdens een crash uit het geheugen verliezen en daarna latere blokken accepteren. De client zou denken dat alle schrijfbewerkingen zijn geslaagd terwijl in het bestand een wijziging in het midden ontbreekt.
Duurzame antwoorden voorkomen die fout ten koste van prestaties. NFSv3 voegde instabiele schrijfbewerkingen toe, gevolgd door COMMIT, waardoor meerdere schrijfbewerkingen samen duurzaam kunnen worden gemaakt. De client moet een instabiele bevestiging onderscheiden van duurzame voltooiing.
Onderscheid versies van het protocol
Een protocol met toestand heeft mechanismen nodig om de toestand van geopende bestanden en vergrendelingen na een serverherstart te herstellen en toestand van gecrashte clients op te ruimen. NFSv4 accepteert die complexiteit bewust: het heeft OPEN, CLOSE, vergrendelingen en in tijd beperkte tijdelijke gebruiksrechten die clients verlengen. De Linux-client probeert normaal eerst versie 4.2 en valt zo nodig terug. NFSv2 toestandsloos noemen beschrijft dus niet elke NFS-versie.
Belangrijkste punten
- NFSv2 bewaart descriptoren en bestandsposities op clients; elk verzoek is zelfstandig.
- Bestandshandles bevatten een generatie om verouderde identiteiten na hergebruik van een inode af te wijzen.
- Expliciete posities maken het herhalen van dezelfde WRITE veilig in het model met herhaalde verzoeken.
- NFSv2 bevestigt schrijfbewerkingen pas na stabiele opslag; NFSv3 kan duurzaamheid uitstellen tot COMMIT.
- NFSv4 houdt toestand bij en gebruikt herstelmechanismen en tijdelijke gebruiksrechten.
6.2 Vergelijk caching en consistentie bij NFS en AFS
Caching op clients bespaart netwerkverkeer, maar creëert meerdere kopieën van gedeelde bestanden. De consistentieregel bepaalt wanneer een andere machine moet stoppen met het gebruiken van een oude kopie en de wijzigingen van de schrijver moet ophalen.
Controleer NFS-caches bij overdracht tussen gebruikers
Bij consistentie tussen sluiten en opnieuw openen van NFS stuurt het sluiten van een gewijzigd bestand gebufferde schrijfbewerkingen naar de server. Een latere opening op een andere client controleert of de kopie actueel is en ziet die wijzigingen. GETATTR of een vergelijkbare controle vergelijkt serverattributen met gecachete attributen en verwijdert verouderde gecachete gegevens wanneer een wijziging wordt gedetecteerd.
Bij elke toegang controleren zou de server belasten. Linux bewaart attributen van gewone bestanden standaard tussen 3 en 60 seconden in de cache. Een proces dat een bestand openhoudt, kan daardoor tussen controles verouderde gecachete gegevens lezen. Openen is een sterker overdrachtsmoment dan een willekeurige leesbewerking via een al open descriptor. Consistentie tussen sluiten en opnieuw openen belooft niet dat elke afzonderlijke schrijfbewerking onmiddellijk zichtbaar is.
Hergebruik volledige bestanden met AFS-wijzigingsmeldingsbeloften
Het Andrew File System (AFS) is in de jaren 1980 bij Carnegie Mellon ontworpen om veel clients per server te ondersteunen. Als er geen geldige lokale kopie bestaat, haalt openen het hele bestand naar de lokale schijf. Lees- en schrijfbewerkingen gebruiken daarna die kopie en het sluiten van een gewijzigd bestand stuurt de hele nieuwe versie naar de server. Een geldige gecachete kopie kan opnieuw worden geopend zonder die opnieuw te downloaden.
AFSv1 controleerde bij elke opening de geldigheid en liet het doorlopen van paden aan de server over. AFSv2 verschoof het doorlopen naar clients, die directory's cachen, en introduceerde wijzigingsmeldingsbeloften. De server belooft een client te melden wanneer een gecachet object verandert. Tot die belofte wordt ingetrokken, gebruikt de client de kopie opnieuw zonder herhaalde controles. De bestandsidentificatie omvat een volume, een bestandsidentificatie en een uniekmaker.
Volg twee overlappende sessies
Stel dat clients A en B beide een bestand openen. A wijzigt de lokale kopie en sluit het bestand, waardoor de nieuwe versie naar de server gaat. De server trekt de wijzigingsmeldingsbeloften van andere clients in. Een latere opening op B haalt de nieuwe versie op, maar de al open sessie van B behoudt de bestaande kopie tot sluiten en opnieuw openen.
Als beide machines hun kopieën wijzigen, vervangt de machine die het laatst sluit het hele bestand op de server. Blokken uit de twee kopieën worden niet samengevoegd. Ook bij twee wijzigingen op verschillende posities kunnen de wijzigingen van één client verloren gaan, omdat de laatst sluitende client wint één volledige versie kiest. Processen op één clientmachine zien elkaars schrijfbewerkingen onmiddellijk.
Wijzigingsmeldingsbeloften zijn toestand op de server. Na een herstart van een client zijn gecachete bestanden verdacht omdat meldingen gemist kunnen zijn. Na een herstart van de server moeten clients de verloren beloften detecteren, via hartslagberichten of een melding van de server, en opnieuw controleren.
Stem caching af op de werklast
| Werklast of vraagstuk | NFS | AFS |
|---|---|---|
| Klein deel van een groot bestand | Draagt opgevraagde blokken over | Overdracht van het hele bestand kan werk verspillen |
| Herhaald lezen van een groot bestand dat niet in het geheugen past | Hangt af van beschikbare gecachete blokken | Lokale schijfkopie voorkomt meer downloads via het netwerk |
| Bijhouden of gegevens actueel zijn | Attribuutcontroles | Wijzigingsmeldingsbeloften van de server |
| Gelijktijdig delen | Vereist coördinatie | Vereist coördinatie; de laatst sluitende client kan een andere versie overschrijven |
AFS bood ook een globale naamruimte, toegangscontrolelijsten en door beheerders beheerde volumes. AFSv2 verhoogde historisch de schaal van een server tot ongeveer 50 clients, tegenover ongeveer 20 voor AFSv1. Geen van beide cacheregels vervangt expliciete coördinatie, zoals bestandsvergrendeling, wanneer programma's veilige gedeelde wijzigingen nodig hebben.
Belangrijkste punten
- NFS controleert bij opnieuw openen na sluiten, terwijl attributencaching open lezers verouderde gegevens kan laten zien.
- AFS hergebruikt een volledig bestand in de schijfcache zolang een wijzigingsmeldingsbelofte geldig blijft.
- AFS maakt wijzigingen bij sluiten beschikbaar; een al open sessie op afstand behoudt de oude kopie.
- Gelijktijdige AFS-schrijvers vervangen volledige versies, dus wint de laatst sluitende client.
- Toestand voor wijzigingsmeldingsbeloften vereist na storingen een nieuwe controle.
- De overdrachtsgranulariteit bepaalt welke werklasten baat hebben bij elk cacheontwerp.
Bestandssystemen: voorbeelden
1Volg een bestand van openen tot duurzame vervanging
19 stappen
- 1IntroductieVolg vier soorten toestand
Een bestandsbewerking kan bytes, een bestandspositie van een geopend bestand, een directorynaam of toegangsrechten veranderen. Volg een klein programma door deze lagen en bouw daarna een duurzame vervanging. De lagen gescheiden houden verklaart twee aanvankelijk verrassende resultaten: een bestand kan bruikbaar blijven nadat de laatste naam is verwijderd en een bestand sluiten maakt een opslagactie op zichzelf niet duurzaam.
- 2VoorbeeldOpen en lees een reeks bytes
Een bestand van 260 bytes wordt geopend om te lezen. Stel dat
opendescriptor 3 teruggeeft en de eersteread(3, buf, 80)80 teruggeeft. De descriptor identificeert de open verwijzing van dit proces; de bestandspositie is nu 80. Het teruggegeven aantal vertelt je hoeveel je moet opschuiven. Het gevraagde aantal is alleen een bovengrens, dus moet het programma de retourwaarde controleren. - 3UitdagingBepaal de volgende bestandspositie
Het volgende verzoek vraagt 100 bytes maar geeft 60 terug. Op welke positie begint de daaropvolgende gewone leesbewerking?
---reveal---
Die begint bij byte 140: de vorige positie 80 schuift op met de 60 werkelijk gelezen bytes. Opschuiven met de gevraagde 100 zou ten onrechte bytes overslaan. Een leesbewerking die aan het bestandseinde 0 teruggeeft, zou de positie ongewijzigd laten.
- 4AnalogieDeel een boekenlegger
Een vermelding voor een geopend bestand is als een gedeelde boekenlegger in één exemplaar van een boek.
dupgeeft een andere manier om dezelfde boekenlegger te bereiken; twee afzonderlijkeopen-aanroepen maken twee boekenleggers. De vergelijking gaat alleen over de positie: beide openingen bereiken nog steeds hetzelfde onderliggende bestand. De bytes wijzigen kan beide lezers beïnvloeden, ook al zijn hun bestandsposities onafhankelijk. - 5VoorbeeldVolg een gedupliceerde descriptor
Het programma roept
other = dup(3)aan en daarnalseek(other, 20, SEEK_SET). Descriptor 3 gebruikt nu ook positie 20, omdat beide descriptoren één vermelding voor een geopend bestand bereiken. Een leesbewerking van 15 bytes via descriptor 3 laat hun gedeelde positie op 35 staan. De positiewijziging zelf verandert de toestand in het geheugen; ze leest geen blok en verplaatst geen fysieke schijfkop. - 6TipKies de juiste positiebewerking
Gebruik
preadwanneer een leesbewerking een expliciete bytepositie moet aangeven zonder de positie van de vermelding voor het geopende bestand te veranderen. Dit is van belang wanneer descriptoren die vermelding nadupofforkdelen. Een gewonereadschuift de gedeelde positie op;preaddoet dat niet. Controleer bij beide aanroepen het teruggegeven aantal en eventuele fouten voordat je aanneemt dat de gevraagde bytes zijn opgehaald. - 7UitlegMaak geaccepteerde bytes duurzaam
Een geslaagde
writeplaatst nieuwe bytes meestal in geheugenbuffers. Een latere crash kan ze wissen voordat ze de opslag bereiken.fsyncwacht totdat de gewijzigde gegevens en metadata van het bestand volgens het apparaat de opslag hebben bereikt. Een descriptor sluiten geeft een open verwijzing vrij; het voert niet dezelfde duurzaamheidsbewerking uit. - 8VoorbeeldBereid een volledige vervanging voor
Een editor wil
settings.jsonvervangen. Die schrijft eerst alle vervangende inhoud naarsettings.json.tmpin dezelfde directory en controleert de geschreven aantallen en fouten. Het oude doel blijft tijdens dit werk intact. Daarna synchroniseert de editor het tijdelijke bestand met succes, zodat de volledige vervangende bytes duurzaam zijn opgeslagen voordat de doelnaam verandert. - 9VoorbeeldMaak de nieuwe naam beschikbaar en duurzaam
Vervolgens hernoemt de editor het tijdelijke bestand over
settings.json. De vervanging binnen hetzelfde bestandssysteem is atomair: de naam bereikt het oude of het nieuwe bestand, zonder periode waarin de naam ontbreekt. Ten slotte synchroniseert de editor de bovenliggende directory. Die laatste stap maakt de naamswijziging duurzaam, omdat de directoryvermelding bij de directory hoort en niet bij het bestand. - 10UitdagingVind de ontbrekende stap voor duurzaamheid
Een programma schrijft en synchroniseert een nieuw bestand, hernoemt het over het doel en meldt direct dat het duurzaam is opgeslagen. Welke bewerking is nog nodig?
---reveal---
Synchroniseer de bovenliggende directory en controleer of dat lukt. Bestandssynchronisatie beschermt de inhoud van de vervanging, terwijl directorysynchronisatie de gewijzigde naam beschermt. Alleen atomair hernoemen zorgt er niet voor dat de hernoeming een crash overleeft.
- 11VoorbeeldVoeg een tweede naam toe
Het commando
ln draft savedmaakt een harde koppeling. Beide namen verwijzen naar één inode en het aantal harde koppelingen van het gewone bestand wordt 2. Na het verwijderen vandraftblijftsavedbruikbaar met aantal 1. De inhoud is niet gekopieerd: de bewerking voegde een directoryvermelding toe. Een symbolische koppeling zou daarentegen een eigen object zijn dat een te volgen pad opslaat. - 12UitdagingVerwijder alle namen van een geopend bestand
Een proces heeft
savedopen. Een ander proces verwijdert de laatste harde koppeling. Kan het eerste proces het bestand nog lezen en wanneer kan de opslagruimte worden vrijgemaakt?---reveal---
De open descriptor blijft bruikbaar. Vrijmaken wacht totdat er geen namen en geen open verwijzingen meer zijn. Het aantal harde koppelingen registreert namen, dus beëindigt een aantal van nul op zichzelf een bestaande open verwijzing niet.
- 13KernpuntEen pad is geen objectverwijzing
Een symbolische koppeling bewaart een doelpad, dus kan het verwijderen of hernoemen van het doel de koppeling verbreken. Een harde koppeling duidt rechtstreeks de inode aan en blijft bestaan als de andere namen worden verwijderd. Symbolische koppelingen kunnen over bestandssystemen heen verwijzen omdat paden over koppelpunten heen kunnen lopen; harde koppelingen kunnen dat niet, omdat inodenummers binnen één bestandssysteem betekenis hebben.
- 14VoorbeeldOntcijfer toegangsrechten
De rechtenreeks
rw-r-----bestaat uit eigenaarrw-, groepr--en anderen---. Met lezen = 4, schrijven = 2 en uitvoeren = 1 zijn de cijfers 6, 4 en 0. Dus steltchmod 640 reportlezen en schrijven voor de eigenaar, lezen voor de groep en geen rechten voor anderen in. De drie cijfers beschrijven afzonderlijke gebruikersklassen, niet één gedeelde som. - 15UitdagingBereik een bekende bestandsnaam
Een gebruiker heeft uitvoerrecht maar geen leesrecht op
/srv/dataen de toegangsrechten van het bestand staan lezen van/srv/data/plantoe. Kan de gebruiker het bekende pad openen en de inhoud van de directory weergeven?---reveal---
De gebruiker kan het bekende pad openen omdat uitvoerrecht het doorzoeken van de directory toestaat. Voor het weergeven van de inhoud is leesrecht op de directory nodig, dus dat mislukt. De bestandsrechten worden ook gecontroleerd; alleen de directory mogen doorzoeken geeft geen toegang tot elk bestand erin.
- 16TipLees ctime correct
Na
chmodverandert ctime omdat de status van de inode is gewijzigd. Het is geen aanmaaktijdstempel. mtime registreert wijzigingen van de bestandsinhoud; atime registreert toegang, vaak met uitgestelde updates. Door deze betekenissen te onderscheiden kun je de uitvoer vanstatinterpreteren zonder te concluderen dat een wijziging van toegangsrechten een nieuw bestand heeft aangemaakt of de bytes heeft herschreven. - 17VerbandVoeg bomen samen zonder identiteiten samen te voegen
Aankoppelen verbindt de hoofddirectory van een ander bestandssysteem aan een directory zoals
/media/usb, waarbij de eerdere inhoud van die directory verborgen is zolang de koppeling actief is. De laag van het virtuele bestandssysteem geeft beide bomen gemeenschappelijke aanroepen. Die voegt hun inodetabellen niet samen: inode 25 op het ene bestandssysteem kan niets te maken hebben met inode 25 op het andere. - 18UitdagingVervang een bestand via een tweede naam
Een programma houdt het oude bestand open via de harde koppeling
backup. Een editor maakt een volledig nieuw bestand beschikbaar door een tijdelijk bestand overcurrentte hernoemen en synchroniseert daarna de directory. Welke inhoud bereikt de oude descriptor en welke bereikt een nieuwe opening vancurrent?---reveal---
De descriptor en
backupbereiken nog steeds de oude inode. Een nieuwe opening vancurrentbereikt de vervangende inode. Hernoemen verandert een directoryvermelding zonder bestaande open verwijzingen naar een ander doel te laten wijzen; synchronisatie maakt die naamswisseling duurzaam. - 19SamenvattingGebruik het juiste toestandsmodel
Volg gewone leesposities via vermeldingen voor geopende bestanden en namen via directory's en inodes. Rond voor duurzame vervanging het tijdelijke bestand af, synchroniseer het, hernoem het en synchroniseer daarna de directory. Onderzoek bij problemen met toegang of verwijderen zowel de relevante directoryrechten en open verwijzingen als de eigen metadata van het bestand.
2Vind bytes op schijf en tel het werk
17 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieVertaal namen naar blokken
- 2VoorbeeldBouw de partitie-indeling
- 3UitdagingTel inodeplaatsen
- 4VoorbeeldBereken een absoluut inodeadres
- 5VoorbeeldSelecteer bytes binnen het omvattende blok
- 6KernpuntHoud de bestandsnaam buiten de inode
- 7VoorbeeldZoek een logisch gegevensblok
- 8UitlegBreid de pointerboom uit
- 9VoorbeeldWijs het eerste deel van een groot bestand toe
- 10UitdagingVoltooi de telling van pointerblokken
- 11VerbandBeschrijf een reeks in plaats van elk adres
- 12VoorbeeldDoorloop een pad zonder cache
- 13UitdagingPas het leesmodel toe
- 14TipTel elke gewijzigde structuur
- 15KernpuntLaat geheugen apparaatwerk wegnemen
- 16UitdagingHerhaal een opzoekactie nadat de gegevens zijn gecachet
- 17SamenvattingOnderscheid drie vertalingen
3Plaats verwante bestanden en bepaal hun overdrachtsgrootte
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieBesteed tijd aan het overdragen van bruikbare bytes
- 2UitlegOnderzoek ver verwijderde metadata en kleine overdrachten
- 3AnalogieHoud een werkverzameling bij elkaar
- 4VoorbeeldPlaats lokale bronnen in elke groep
- 5UitdagingLeg uit wat groeperen verandert
- 6VoorbeeldPlaats de bestanden van een directory
- 7KernpuntLaat ruimte voor naburige bestanden
- 8VoorbeeldMeet de overhead
- 9VoorbeeldBereken de grootte voor een doel van 90%
- 10UitdagingVoorspel de deelgrootte voor een snellere schijf
- 11TipStem toewijzing ook op kleine bestanden af
- 12UitdagingHoud ruimte voor bestanden die samen worden aangemaakt
- 13SamenvattingWeeg lokaliteit, ruimte en overdrachtsgrootte af
4Volg een toevoeging door een crash en herstel
18 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieHerstel één volledige wijziging
- 2VoorbeeldBenoem de drie gewijzigde blokken
- 3UitdagingClassificeer een toewijzing zonder pointer
- 4VoorbeeldVind verborgen ongeldige inhoud
- 5KernpuntOnderscheid drie soorten fouten
- 6UitlegReconstrueer eigenaarschap met fsck
- 7UitdagingBeoordeel een foutloze controle
- 8VerbandHerstel namen zonder ze te verzinnen
- 9VoorbeeldSchrijf eerst de inhoud voor opnieuw uitvoeren
- 10VoorbeeldLeg de volledige transactie vast
- 11UitdagingHerstel na gedeeltelijke overbrenging
- 12TipControleer vastlegging en duurzaamheid afzonderlijk
- 13VoorbeeldVoorkom dat gegevens twee keer worden geschreven
- 14UitdagingHerken de ontbrekende volgorderegel
- 15VoorbeeldBescherm een hergebruikt blok tegen oude herhaling
- 16VerbandMaak in plaats daarvan een nieuwe boom beschikbaar
- 17UitdagingHerstel structuur zonder de bedoeling te herstellen
- 18SamenvattingVraag wat herstel kan bewijzen
5Schrijf, vind en ruim een verplaatsend logboek op
15 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieHoud identiteit stabiel terwijl locaties veranderen
- 2VerbandMaak van veel korte wijzigingen één overdracht
- 3VoorbeeldSchrijf een nieuwe versie
- 4UitlegWerk de inodevertaaltabel bij
- 5UitdagingControleer de bovenliggende directory
- 6VoorbeeldVind de vertaaltabel na het aankoppelen
- 7VoorbeeldBepaal de grootte van een sequentieel segment
- 8KernpuntGa niet uit van sequentieel lezen
- 9VoorbeeldControleer of het oude blok nog wordt gebruikt
- 10UitdagingBereken de teruggewonnen ruimte
- 11TipVoorkom het kopiëren van gegevens die snel ongebruikt raken
- 12VoorbeeldKies een volledig checkpoint
- 13UitdagingHerstel werk van na het checkpoint
- 14UitdagingHerstel de vertaaltabel voordat je controleert of blokken nog worden gebruikt
- 15SamenvattingBetaal voor sequentiële wijzigingen met vertaling en opruimen
6Herhaal verzoeken en voorspel de zichtbaarheid van gedeelde bestanden
16 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieGa om met onzekerheid tussen machines
- 2VoorbeeldStel een zelfstandig leesverzoek samen
- 3KernpuntToestandsloos betekent niet zonder opslag
- 4UitdagingHerhaal een WRITE na een verloren antwoord
- 5TipHerken een herhaling die het antwoord verandert
- 6VoorbeeldMaak de bevestiging duurzaam
- 7VerbandHoud protocolversies apart
- 8VoorbeeldDeel gegevens bij opnieuw openen in NFS
- 9UitdagingVerklaar een leesbewerking uit een oude cache
- 10AnalogieVervang herhaalde controles door een belofte
- 11VoorbeeldBehoud de kopie van een bestaande AFS-sessie
- 12UitdagingVoorspel het resultaat van twee schrijvers
- 13KernpuntHoud na een crash rekening met wijzigingsmeldingsbeloften
- 14VerbandKies de overdrachtsgranulariteit voor de werklast
- 15UitdagingOnderscheid veilig herhalen van veilig samen wijzigen
- 16SamenvattingStel twee afzonderlijke netwerkvragen
Bestandssystemen: oefenvragen
Set 1: Descriptoren, namen en duurzaam opslaan10 Oefenvragen
Vraag 1 van 10
Toon antwoordVerberg antwoord
Vraag 2 van 10
a en b en leest daarna 24 bytes via a. Wat is de positie van b vóór de eerste leesbewerking via die descriptor?Toon antwoordVerberg antwoord
a verplaatst alleen de positie van a; met dup gemaakte descriptoren zouden daarentegen een positie delen.Vraag 3 van 10
a, maakt b = dup(a) en opent het afzonderlijk als c. Na fork verplaatst het kindproces b naar 70. Het ouderproces leest 12 bytes via a en roept daarna pread(c, buf, 9, 100) aan. Wat zijn de uiteindelijke posities van a, b en c?Toon antwoordVerberg antwoord
a en b delen ook na de fork een vermelding, dus stelt de positiewijziging van het kindproces hun positie in op 70 en schuift de leesbewerking van het ouderproces die op naar 82. De afzonderlijke opening c begint op nul en pread laat die positie daar staan. c naar 109 opschuiven zou I/O met een expliciete positie verwarren met een gewone read.Vraag 4 van 10
Toon antwoordVerberg antwoord
fsync wacht tot de gewijzigde gegevens en metadata van het bestand volgens het apparaat de opslag bereiken. close geeft de descriptor vrij en kan schrijfbewerkingen gebufferd achterlaten. Metadata lezen of de positie veranderen vraagt niet om deze duurzaamheidsgrens.Vraag 5 van 10
Toon antwoordVerberg antwoord
Vraag 6 van 10
Toon antwoordVerberg antwoord
Vraag 7 van 10
red en blue, zijn harde koppelingen naar één gesloten gewoon bestand. Wat gebeurt er met blue nadat red is verwijderd?Toon antwoordVerberg antwoord
red en verlaagt het aantal harde koppelingen van de gedeelde inode van 2 naar 1. blue blijft een gelijkwaardige naam voor die inode en bereikt nog steeds de inhoud. De naam als verbroken beschouwen zou het padgedrag van een symbolische koppeling op een harde koppeling toepassen.Vraag 8 van 10
Toon antwoordVerberg antwoord
Vraag 9 van 10
/srv/team doorzoeken maar de namen erin niet weergeven. De gebruiker kent /srv/team/brief en de toegangsrechten van dat bestand staan lezen toe. Welke toegang is mogelijk?Toon antwoordVerberg antwoord
Vraag 10 van 10
Toon antwoordVerberg antwoord
Set 2: Breng inodes, gegevensblokken en apparaatwerk in kaart10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
/lab/raw/data te vinden voordat de inhoud wordt gelezen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
/lab/raw/data leest het programma drie gegevensblokken; bij elke bloktoegang leest het de inode opnieuw en schrijft het atime. Sluiten heeft geen I/O. Wat is het totaal?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Lokaliteit, doorvoer en gedeeltelijke wijzigingen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Controleer, leg vast en pas veilig opnieuw toe10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 5: Verplaatsende logboeken en netwerkcaches10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 6: Onderzoek ontwerpen van bestandssystemen10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
one en two zijn harde koppelingen naar een bestand en shortcut is een symbolische koppeling met het pad one. Een proces opent two, waarna alle drie de namen worden verwijderd. Wat blijft er over voordat dat proces de descriptor sluit?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
aantal harde koppelingen
absoluut pad
/srv/reports/today begint bij de hoofddirectory, ook wanneer de huidige directory van het proces /home/lee is.amortisatie
Andrew File System
atime
relatime-beleid van Linux voorkomt dat dit na elke toegang wordt geschreven.atomaire schrijfeenheid
atomaire vervanging
rename binnen hetzelfde bestandssysteem vervangt config, terwijl lezers óf het oude óf het nieuwe volledige bestand bereiken.attributencache
B
bestandsdescriptor
open 4 teruggeeft, geeft het programma 4 door aan read, write en close voor die open verwijzing.bestandshandle
bestandspositie
bestandstoewijzingstabel
blokgroep
C
cachen van volledige bestanden
cachetreffer
checkpointgebied
cilindergroep
circulair logboek
consistentie na een crash
consistentie tussen sluiten en opnieuw openen
consistentiemodel waarin de laatst sluitende client wint
ctime
chmod verandert ctime, hoewel de bytes en dus de wijzigingstijd van de inhoud ongewijzigd blijven.D
deelblok
directe pointer
directoryvermelding
doorlopen van een pad
/team/result wordt eerst team in de hoofddirectory gevonden en daarna result in de directory team.dubbele blokverwijzing
dubbelindirecte pointer
dunbezet bestand
duurzaamheid
fsync voordat die meldt dat de nieuwe inhoud van een document duurzaam is opgeslagen.E
extent
F
fragmentatie
fsck
fysieke logregistratie
G
gedistribueerd bestandssysteem
read van een programma naar een verzoek dat een serverbestand en het gewenste bytebereik identificeert.gegevensblok
generatienummer
geordende journaalregistratie
gewijzigde buffer
H
harde koppeling
ln draft copy laat het verwijderen van draft de naam copy naar hetzelfde bestand en de bestaande bytes verwijzen.I
idempotentie
indirect blok
inode
inodetabel
inodevertaaltabel
intrekkingsrecord
J
journaal
journaalmodus met ongeordend terugschrijven
data=writeback kunnen metadata consistent zijn, ook wanneer een recent geschreven bestand verouderde bytes bevat.K
kopiëren bij schrijven
koppelpunt
/media/usb verbergt de eerdere inhoud van die directory zolang de koppeling actief blijft.L
lek in de opslagruimte
loggestructureerd bestandssysteem
logisch bestandsblok
logische logregistratie
lokaliteit in de naamruimte
M
metadata
fstat leest metadata via een descriptor zonder de bestandsinhoud als een metadatarecord te behandelen.metadataregistratie in een journaal
momentopname
mtime
N
Network File System
nog gebruikt blok
O
onbereikbare inode
lost+found plaatsen voor inspectie.ongeldige bestandsinhoud
ongeldige blokverwijzing
overbrengen van vastgelegde journaalblokken naar hun definitieve locatie
P
paginacache
positioneringskosten
R
recursief wijzigingsprobleem
relatief pad
/srv/reports bereikt het pad ../logs de directory /srv/logs door eerst de vermelding naar de bovenliggende directory te volgen.S
schrijfbewerking met minder geschreven bytes dan aangevraagd
write 200 teruggeeft bij een verzoek om 500 bytes, moet het programma de resterende 300 bytes nog afhandelen.schrijfbuffering
segment
segment met vaak gewijzigde blokken
segmentopruimer
segmentoverzicht
soft updates
spoorbuffer
superblok
symbolische koppeling
/media/archive kan een ander bestandssysteem bereiken, maar werkt niet als het doelpad verdwijnt.T
tijdelijk gebruiksrecht
toegangscontrolelijst
toegangsrechtenbits
750 geeft de eigenaar alle drie de rechten, de groep lees- en uitvoerrecht en anderen geen rechten.toestandsloze server
toevoegmodus
O_APPEND wordt gekozen.O_APPEND zodat elk nieuw bericht na de bestaande bestandsinhoud wordt geplaatst.toewijzingsbitmap
transactie
transactiecontrolesom
U
uitzonderingsregel voor grote bestanden
umask
0022 een aanvraag voor 0666 in de rechten 0644.V
vastleggingsrecord
vermelding in de tabel met geopende bestanden
dup zijn gemaakt, wijzen naar één vermelding, zodat een positiewijziging via een van beide hun gedeelde positie verandert.verouderde cache
virtueel bestandssysteem
read gebruiken op een ext4-bestand en een NFS-bestand, terwijl hun implementaties verschillende opslag afhandelen.voorwaarts herstel
W
wijzigen van de bestandslengte
O_TRUNC maakt het leeg voordat het programma vervangende inhoud schrijft.wijzigingsmeldingsbelofte
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.