Alt hvad du nogensinde har ønsket at vide om inoder på Linux

Linux-filsystemet er afhængigt af inoder. Disse vitale dele af filsystemets indre funktion misforstås ofte. Lad os se nøjagtigt på, hvad de er, og hvad de gør.

Elementerne i et filsystem

Per definition skal et filsystem gemme filer, og de indeholder også mapper. Filerne er gemt i telefonbøgerne, og disse mapper kan have underkataloger. Noget, et eller andet sted, skal registrere, hvor alle filerne er placeret i filsystemet, hvad de hedder, hvilke konti de tilhører, hvilke tilladelser de har og meget mere. Disse oplysninger kaldes metadata, fordi det er data, der beskriver andre data.

I Linux ext4-filsystemet arbejder inode- og bibliotekstrukturer sammen for at give en understøttende ramme, der gemmer alle metadata for hver fil og bibliotek. De gør metadata til rådighed for enhver, der kræver det, uanset om det er kernen, bruger applikationer, eller Linux hjælpeprogrammer, såsom ls, stat, og df.

Inoder og filsystemstørrelse

Selvom det er sandt, er der et par strukturer, men et filsystem kræver meget mere end det. Der er tusinder og tusinder af hver struktur. Hver fil og mappe kræver en inode, og fordi hver fil er i en mappe, kræver hver fil også en mappestruktur. Directory-strukturer kaldes også katalogindgange eller "tandlæger".

Hver inode har et inode nummer, som er unikt inden for et filsystem. Det samme inodenummer vises muligvis i mere end et filsystem. Imidlertid kombineres filsystemets id og inode nummer for at skabe en unik identifikator, uanset hvor mange filsystemer der er monteret på dit Linux-system.

Husk, i Linux monterer du ikke en harddisk eller partition. Du monterer det filsystem, der er på partitionen, så det er nemt at have flere filsystemer uden at indse det. Hvis du har flere harddiske eller partitioner på et enkelt drev, har du mere end et filsystem. De kan være af samme type - f.eks. Alt ext4 - men de vil stadig være forskellige filsystemer.

Alle inoder holdes i en tabel. Ved hjælp af et inode nummer beregner filsystemet let offset i den inodetabel, hvor inoden er placeret. Du kan se, hvorfor "i" i inode står for indeks.

Variablen, der indeholder inode-nummeret, erklæres i kildekoden som et 32-bit, usigneret langt heltal. Dette betyder, at inodetallet er et heltal med en maksimal størrelse på 2 ^ 32, der beregner ud til 4.294.967.295 — langt over 4 milliarder inoder.

Det er det teoretiske maksimum. I praksis bestemmes antallet af inoder i et ext4-filsystem, når filsystemet oprettes med et standardforhold på en inode pr. 16 KB filsystemkapacitet. Katalogstrukturer oprettes på farten, når filsystemet er i brug, da filer og mapper oprettes i filsystemet.

Der er en kommando, du kan bruge til at se, hvor mange inoder der er i et filsystem på din computer. Indstillingen -i(inoder) for dfkommandoen instruerer den i at vise dens output i antal inoder.

Vi skal se på filsystemet på den første partition på den første harddisk, så vi skriver følgende:

df -i / dev / sda1

Resultatet giver os:

  • Filsystem : Filsystemet der rapporteres om.
  • Inoder : Det samlede antal inoder i dette filsystem.
  • IUsed : Antallet af inoder, der er i brug.
  • IFree : Antallet af resterende inoder, der er tilgængelige til brug.
  • IUse% : Procentdelen af ​​brugte inoder.
  • Monteret på : Monteringspunktet for dette filsystem.

Vi har brugt 10 procent af inoderne i dette filsystem. Filer gemmes på harddisken i diskblokke. Hver inode peger på diskblokke, der gemmer indholdet af den fil, de repræsenterer. Hvis du har millioner af små filer, kan du løbe tør for inoder, før du løber tør for plads på harddisken. Det er dog et meget vanskeligt problem at løbe ind i.

Tidligere havde nogle mailservere, der lagrede e-mail-meddelelser som diskrete filer (hvilket hurtigt førte til store samlinger af små filer) dette problem. Da disse applikationer ændrede deres bagende til databaser, løste dette dog problemet. Det gennemsnitlige hjemmesystem løber ikke tør for inoder, hvilket er lige så godt, fordi du med ext4-filsystemet ikke kan tilføje flere inoder uden at geninstallere filsystemet.

For at se størrelsen på diskblokkene på dit filsystem kan du bruge blockdevkommandoen med indstillingen --getbsz(get block size):

sudo blockdev --getbsz / dev / sda

Blokstørrelsen er 4096 bytes.

Lad os bruge indstillingen -B(blokstørrelse) til at specificere en blokstørrelse på 4096 byte og kontrollere den almindelige diskbrug:

df -B 4096 / dev / sda1

Denne output viser os:

  • Filsystem : Filsystemet, som vi rapporterer om.
  • 4K-blokke : Det samlede antal på 4 KB blokke i dette filsystem.
  • Brugt : Hvor mange 4K-blokke er der i brug.
  • Tilgængelig : Antallet af resterende 4 KB-blokke, der er tilgængelige til brug.
  • Brug% : Procentdelen af ​​4 KB-blokke, der er blevet brugt.
  • Monteret på : Monteringspunktet for dette filsystem.

I vores eksempel har filopbevaring (og opbevaring af inoder og bibliotekstrukturer) brugt 28 procent af pladsen på dette filsystem til prisen for 10 procent af inoderne, så vi er i god form.

Inode-metadata

For at se inode nummeret på en fil kan vi bruge lsmed -i(inode) indstillingen:

ls -i geek.txt

Inode-nummeret for denne fil er 1441801, så denne inode indeholder metadataene for denne fil og traditionelt pegerne til diskblokkene, hvor filen ligger på harddisken. Hvis filen er fragmenteret, meget stor eller begge dele, kan nogle af de blokke, som inoden peger på, muligvis indeholde yderligere henvisninger til andre diskblokke. Og nogle af disse andre diskblokke kan også indeholde markører til et andet sæt diskblokke. Dette overvinder problemet med, at inoden er en fast størrelse og i stand til at holde et endeligt antal markører til diskblokke.

Denne metode blev erstattet af en ny ordning, der gør brug af "omfang". Disse registrerer start- og slutblokken for hvert sæt sammenhængende blokke, der bruges til at gemme filen. Hvis filen ikke er fragmenteret, skal du kun gemme den første blok og fillængde. Hvis filen er fragmenteret, skal du gemme den første og sidste blok i hver del af filen. Denne metode er (åbenbart) mere effektiv.

Hvis du vil se, om dit filsystem bruger diskblokmarkører eller -udvidelser, kan du se inde i en inode. For at gøre dette bruger vi debugfskommandoen med -R(anmodning) mulighed og sender den inoden til den interessefil. Dette beder om  debugfs at bruge sin interne "stat" -kommando til at vise indholdet af inoden. Da inode numre kun er unikke inden for et filsystem, skal vi også fortælle debugfs det filsystem, som inoden ligger på.

Her er hvordan denne eksempelkommando vil se ud:

sudo debugfs -R "stat" / dev / sda1

Som vist nedenfor debugfsudtrækker kommandoen informationen fra inoden og præsenterer den for os i less:

Vi får vist følgende oplysninger:

  • Inode : Antallet af inode, vi ser på.
  • Type : Dette er en almindelig fil, ikke et bibliotek eller et symbolsk link.
  • Tilstand : Filtilladelserne i oktal.
  • Flag : Indikatorer, der repræsenterer forskellige funktioner eller funktioner. 0x80000 er “extents” -flagget (mere om dette nedenfor).
  • Generation : Et netværksfilsystem (NFS) bruger dette, når nogen får adgang til eksterne filsystemer via en netværksforbindelse, som om de var monteret på den lokale maskine. Inode- og generationsnumrene bruges som en form for filhåndtag.
  • Version : Inode-versionen.
  • Bruger : Ejeren af ​​filen.
  • Gruppe : Gruppeejeren af filen.
  • Projekt : Skal altid være nul.
  • Størrelse : Filens størrelse.
  • File ACL : File access control list. Disse blev designet til at give dig mulighed for at give kontrolleret adgang til personer, der ikke er i ejergruppen.
  • Links : Antallet af hårde links til filen.
  • Blockcount : Mængden af ​​harddiskplads, der er allokeret til denne fil, givet i 512-byte-stykker. Vores fil er tildelt otte af disse, hvilket er 4.096 bytes. Så vores 98-byte-fil sidder i en enkelt 4.096-byte diskblok.
  • Fragment : Denne fil er ikke fragmenteret. (Dette er et forældet flag.)
  • Ctime : Det tidspunkt, hvor filen blev oprettet.
  • Atime : Det tidspunkt, hvor filen sidst blev åbnet.
  • Mtime : Det tidspunkt, hvor filen sidst blev ændret.
  • Crtime : Det tidspunkt, hvor filen blev oprettet.
  • Størrelse på ekstra inode-felter : Ext4-filsystemet introducerede muligheden for at allokere en større inode på disken på formatet. Denne værdi er antallet af ekstra byte, som inoden bruger. Denne ekstra plads kan også bruges til at imødekomme fremtidige krav til nye kerner eller til at gemme udvidede attributter.
  • Inode-kontrolsum : En kontrolsum for denne inode, som gør det muligt at opdage, om inoden er beskadiget.
  • Områder : Hvis der anvendes udvidelser (på udvid4 er de som standard), har metadata vedrørende diskblokering af filer to tal, der angiver start- og slutblokkene for hver del af en fragmenteret fil. Dette er mere effektivt end lagring af hver diskblok, der optages af hver del af en fil. Vi har en udstrækning, fordi vores lille fil sidder i en diskblok ved denne blokforskydning.

Hvor er filnavnet?

Vi har nu en masse information om filen, men som du måske har bemærket, fik vi ikke filnavnet. Det er her katalogstrukturen kommer i spil. I Linux, ligesom en fil, har en mappe en inode. I stedet for at pege på diskblokke, der indeholder fildata, peger en biblioteksinode dog på diskblokke, der indeholder katalogstrukturer.

Sammenlignet med en inode indeholder en katalogstruktur en begrænset mængde information om en fil. Det indeholder kun filens inode nummer, navn og længden af ​​navnet.

Inoden og katalogstrukturen indeholder alt, hvad du (eller et program) har brug for at vide om en fil eller mappe. Katalogstrukturen er i en biblioteksdiskblok, så vi ved, hvilken mappe filen er i. Katalogstrukturen giver os filnavnet og inodenummeret. Inoden fortæller os alt andet om filen, inklusive tidsstempler, tilladelser og hvor fildataene findes i filsystemet.

Directory-inoder

Du kan se inode nummeret på en mappe lige så let som du kan se dem for filer.

I det følgende eksempel bruger vi ls indstillingerne -l(langt format), -i(inode) og -d(bibliotek) og ser på workbiblioteket:

ls -lågsarbejde /

Fordi vi brugte indstillingen -d(bibliotek)  lsrapporterer om selve biblioteket, ikke dets indhold. Inoden til denne mappe er 1443016.

For at gentage det for homebiblioteket skriver vi følgende:

ls -låg ~

homeInoden til biblioteket er 1447510, og workmappen er i hjemmekataloget. Lad os nu se på indholdet af workbiblioteket. I stedet for indstillingen  -d(bibliotek) bruger vi indstillingen -a(alle). Dette viser os de katalogposter, der normalt er skjult.

Vi skriver følgende:

ls -lia arbejde /

Fordi vi brugte indstillingen -a(alle), vises posterne single (.) Og dobbelt-punkt (..). Disse poster repræsenterer selve biblioteket (enkelt prik) og dets overordnede bibliotek (dobbelt prik).

Hvis du ser på inode-nummeret for single-dot-posten, skal du se, at det er1443016 - det samme inode-nummer, vi fik, da vi opdagede inode-nummeret til workkataloget. Inode-nummeret for dobbeltpunktsindgangen er også det samme som inode-nummeret for homebiblioteket.

Derfor kan du bruge cd ..kommandoen til at flytte et niveau op i katalogtræet. Når du går forud for et program eller scriptnavn med   ./, fortæller du shell, hvorfra applikationen eller scriptet skal startes.

Inoder og links

Som vi har dækket, kræves der tre komponenter for at have en velformet og tilgængelig fil i filsystemet: filen, katalogstrukturen og inoden. Filen er de data, der er gemt på harddisken, biblioteksstrukturen indeholder navnet på filen og dens inode nummer, og inoden indeholder alle metadata for filen.

Symbolske links er filsystemposter, der ligner filer, men de er virkelig genveje, der peger på en eksisterende fil eller mappe. Lad os se, hvordan de styrer dette, og hvordan de tre elementer bruges til at opnå dette.

Lad os sige, at vi har en mappe med to filer i den ene: den ene er et script, og den anden er en applikation, som vist nedenfor.

Vi kan bruge kommandoen ln og indstillingen -s(symbolsk) til at oprette et blødt link til scriptfilen som sådan:

ls -s my_script geek.sh

Vi har oprettet et link til my_script.shkaldet geek.sh. Vi kan skrive følgende og bruge  ls til at se på de to scriptfiler:

ls -li * .sh

Posten for geek.sh vises i blåt. Det første tegn i tilladelsesflagene er et "l" for link, og  ->peger på my_script.sh. Alt dette indikerer, at det geek.sher et link.

Som du sandsynligvis forventer, har de to scriptfiler forskellige inodetal. Hvad der måske er mere overraskende, er dog det bløde link geek.sh, har ikke de samme brugertilladelser som den originale scriptfil. Faktisk er tilladelserne til  geek.shmeget mere liberale - alle brugere har fulde tilladelser.

Katalogstrukturen for geek.shindeholder navnet på linket og dets inode. Når du prøver at bruge linket, henvises der til dets inode, ligesom en almindelig fil. Linkinoden peger på en diskblok, men i stedet for at indeholde filindholdsdata indeholder diskblokken navnet på den originale fil. Filsystemet omdirigerer til den originale fil.

Vi sletter den originale fil og ser hvad der sker, når vi skriver følgende for at se indholdet af  geek.sh:

rm my_script.sh
kat nørd. sh

Det symbolske link er brudt, og omdirigering mislykkes.

Vi skriver nu følgende for at oprette et hårdt link til applikationsfilen:

I en specialapp-nørd-app

For at se på inoderne til disse to filer, skriver vi følgende:

ls -li

Begge ligner almindelige filer. Intet om geek-appangiver, at det er et link på den måde, som lslisten for geek.shgjorde. Plus  geek-app har de samme brugertilladelser som den originale fil. Hvad der måske kan være overraskende er, at begge applikationer har det samme inodenummer: 1441797.

Directory-posten for geek-appindeholder navnet “geek-app” og et inode-nummer, men det er det samme som inode-nummeret på den originale fil. Så vi har to filsystemposter med forskellige navne, der begge peger på den samme inode. Faktisk kan et vilkårligt antal varer pege på den samme inode.

Vi skriver følgende og bruger statprogrammet til at se på målfilen:

stat special-app

Vi ser, at to hårde links peger på denne fil. Dette lagres i inoden.

I det følgende eksempel sletter vi den originale fil og prøver at bruge linket med en hemmelig, sikker adgangskode:

rm special-app
./geek-app correcthorsebatterystaple

Overraskende nok kører applikationen som forventet, men hvordan? Det fungerer, fordi inoden er fri til at blive genbrugt, når du sletter en fil. Katalogstrukturen er markeret med et inode-nummer på nul, og diskblokkene er derefter tilgængelige for en anden fil, der skal gemmes i det rum.

Hvis antallet af hårde links til inoden er større end en, reduceres antallet af hardlink dog med en, og inode-nummeret på bibliotekstrukturen for den slettede fil er sat til nul. Filindholdet på harddisken og inoden er stadig tilgængelig for de eksisterende hardlinks.

Vi skriver følgende og bruger stat igen - denne gang den geek-app:

stat geek-app

Disse detaljer trækkes fra den samme inode (1441797) som den forrige statkommando. Linkantalet blev reduceret med en.

Fordi vi er nede på et hårdt link til denne inode, hvis vi sletter  geek-app, ville det virkelig slette filen. Filsystemet frigør inoden og markerer katalogstrukturen med en inode på nul. En ny fil kan derefter overskrive datalagring på harddisken.

RELATERET: Sådan bruges stat-kommandoen på Linux

Inode overhead

det er et pænt system, men der er omkostninger. For at læse en fil skal filsystemet gøre følgende:

  • Find den rigtige katalogstruktur
  • Læs inode nummeret
  • Find den rigtige inode
  • Læs information om inode
  • Følg enten inode-linkene eller udvidelserne til de relevante diskblokke
  • Læs fildataene

Lidt mere at hoppe rundt er nødvendigt, hvis dataene ikke er sammenhængende.

Forestil dig det arbejde, der skal udføres for  ls at udføre en langformat filoversigt over mange filer. Der er meget frem og tilbage bare for lsat få de oplysninger, det har brug for for at generere dets output.

Selvfølgelig er det hurtigere at få adgang til filsystemet, hvorfor Linux forsøger at gøre så meget forebyggende caching af filer som muligt. Dette hjælper meget, men nogle gange - som med ethvert filsystem - kan omkostningerne blive tydelige.

Nu ved du hvorfor.