Detaillierte Erläuterung der Dateisystemformate der EXT-Serie in Linux

Detaillierte Erläuterung der Dateisystemformate der EXT-Serie in Linux

Linux-Dateisystem

In der Abbildung oben sind herkömmliche Festplatten dargestellt. Jede Festplatte ist in mehrere Spuren unterteilt, jede Spur ist in mehrere Sektoren unterteilt und jeder Sektor ist 512 Byte groß, was die kleinste Speichereinheit der Festplatte darstellt. Auf Betriebssystemebene werden jedoch mehrere Sektoren zu Blöcken zusammengefasst, was die kleinste Einheit für die Datenspeicherung des Betriebssystems darstellt. Normalerweise bilden 8 Sektoren einen 4-KB-Block.
Bei Linux-Dateisystemen müssen einige Dinge beachtet werden:

  • Das Dateisystem muss eine strenge Organisationsform haben, damit Dateien in Blöcken gespeichert werden können.
  • Das Dateisystem benötigt einen Indexbereich, um die Position der einzelnen Blöcke einer Datei leichter ermitteln zu können.
  • Wenn es Dateien gibt, die in letzter Zeit häufig gelesen und geschrieben werden, ist eine Cache-Schicht erforderlich
  • Dateien sollten zur einfachen Verwaltung und Abfrage in Ordnern organisiert werden
  • Der Linux-Kernel verwaltet eine Reihe von Datenstrukturen in seinem eigenen Speicher, um zu verfolgen, welche Dateien von welchen Prozessen geöffnet und verwendet werden.

In Linux ist alles eine Datei, und es gibt die folgenden Dateitypen (wie aus der ersten Kennung des Ergebnisses von ls -l ersichtlich):

  • - kennzeichnet eine normale Datei
  • d steht für Ordner
  • c stellt eine Zeichengerätedatei dar
  • b gibt eine Blockgerätedatei an
  • s gibt die Socket-Datei an
  • l zeigt einen Softlink an

Inode- und Blockspeicher

Nehmen wir das EXT-Serienformat als Beispiel, um zu sehen, wie die Datei auf der Festplatte existiert. Zunächst wird die Datei in Blöcke aufgeteilt und auf der Festplatte verteilt. Um diese Blöcke zu finden und einige Metadaten der Datei aufzuzeichnen, ist eine Indexstruktur erforderlich. Dies ist der Inode, wobei i für Index steht. Die Inode-Datenstruktur ist wie folgt:

Struktur ext4_inode {
 __le16 i_mode; /* Dateimodus */
 __le16 i_uid; /* Untere 16 Bits der Eigentümer-UID */
 __le32 i_size_lo; /* Größe in Bytes */
 __le32 i_atime; /* Zugriffszeit */
 __le32 i_ctime; /* Inode-Änderungszeit */
 __le32 i_mtime; /* Änderungszeit */
 __le32 i_dtime; /* Löschzeitpunkt */
 __le16 i_gid; /* Untere 16 Bits der Gruppen-ID */
 __le16 i_links_count; /* Anzahl der Links */
 __le32 i_blocks_lo; /* Anzahl der Blöcke */
 __le32 i_flags; /* Dateiflags */
 Vereinigung {
  Struktur {
   __le32 l_i_version;
  }linux1;
  Struktur {
   __u32 h_i_übersetzer;
  } hurd1;
  Struktur {
   __u32 m_i_reserved1;
  } masix1;
 } osd1; /* Betriebssystemabhängig 1 */
 __le32 i_block[EXT4_N_BLOCKS];/* Zeiger auf Blöcke */
 __le32 i_generation; /* Dateiversion (für NFS) */
 __le32 i_file_acl_lo; /* Datei-ACL */
 __le32 i_Größe_hoch;
 __le32 i_obso_faddr; /* Veraltete Fragmentadresse */
 Vereinigung {
  Struktur {
   __le16 l_i_blocks_high; /* waren l_i_reserved1 */
   __le16 l_i_file_acl_high;
   __le16 l_i_uid_high; /* diese 2 Felder */
   __le16 l_i_gid_high; /* waren reserviert2[0] */
   __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
   __le16 l_i_reserviert;
  }linux2;
  Struktur {
   __le16 h_i_reserved1; /* Veraltete Fragmentnummer/-größe, die in ext4 entfernt wurden */
   __u16 h_i_mode_high;
   __u16 h_i_uid_hoch;
   __u16 h_i_gid_hoch;
   __u32 h_i_author;
  } hurd2;
  Struktur {
   __le16 h_i_reserved1; /* Veraltete Fragmentnummer/-größe, die in ext4 entfernt wurden */
   __le16 m_i_file_acl_high;
   __u32 m_i_reserved2[2];
  } masix2;
 } osd2; /* Betriebssystemabhängig 2 */
 __le16 i_extra_isize;
 __le16 i_checksum_hi; /* crc32c(uuid+inum+inode) BE */
 __le32 i_ctime_extra; /* zusätzliche Änderungszeit (nsec << 2 | Epoche) */
 __le32 i_mtime_extra; /* zusätzliche Änderungszeit (nsec << 2 | Epoche) */
 __le32 i_atime_extra; /* zusätzliche Zugriffszeit (nsec << 2 | Epoche) */
 __le32 i_crtime; /* Dateierstellungszeit */
 __le32 i_crtime_extra; /* zusätzliche FileCreationtime (nsec << 2 | Epoche) */
 __le32 i_version_hi; /* hohe 32 Bit für 64-Bit-Version */
 __le32 i_projid; /* Projekt-ID */
};

Unter ihnen speichert __le32 i_block[EXT4_N_BLOCKS] den Verweis auf den Datenblock. EXT4_N_BLOCKS ist wie folgt definiert:

#define EXT4_NDIR_BLOCKS 12
#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#define EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1)
#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1)

In ext2 und ext3 speichern die ersten 12 Elemente von i_block direkte Verweise auf Datenblöcke, das 13. Element speichert Verweise auf indirekte Blöcke und der Speicherort der Datenblöcke wird in den indirekten Blöcken gespeichert. In ähnlicher Weise speichert das 14. Element den Speicherort sekundärer indirekter Blöcke und das 15. Element den Speicherort tertiärer indirekter Blöcke, wie in der folgenden Abbildung dargestellt:

Es ist nicht schwer zu erkennen, dass bei großen Dateien die Festplatte mehrere Male gelesen werden muss, um die entsprechenden Blöcke zu finden. Extents Tree wird in ext4 vorgeschlagen, um dieses Problem zu lösen. Die Kernidee besteht darin, fortlaufende Blöcke durch die Startposition plus die Anzahl der Blöcke darzustellen, anstatt die Position jedes Blocks einzeln aufzuzeichnen und so Speicherplatz zu sparen. Zunächst werden die ursprünglichen 415=60 Byte Speicherplatz in i_block durch einen Extent-Header (ext4_extent_header) plus 4 Extent-Einträge (ext4_extent) ersetzt, da sowohl ext4_extent_header als auch ext4_extent 12 Byte belegen. Das erste Bit in ee_len wird verwendet, um zu bestimmen, ob es initialisiert ist, sodass es auch maximal 32K Zahlen speichern kann. Daher kann ein Extent-Eintrag maximal 32K4K=128M Daten speichern. Wenn eine Datei größer als 4128M=512M ist oder die Datei in mehr als 4 nicht zusammenhängenden Blöcken gespeichert ist, müssen wir die i_block-Struktur im Inode erweitern. Sein Extent-Eintrag muss von ext4_extent in die Struktur ext4_extent_idx geändert werden, die auf einen Block mit 4 KBytes zeigt. Mit Ausnahme der 12 Bytes, die der Header belegt, können 340 ext4_extents gespeichert werden, und die maximale Datenmenge, die gespeichert werden kann, beträgt 340128M=42,5G. Es ist ersichtlich, dass diese Indexstruktur sehr effizient ist, wenn Dateien in fortlaufenden Blöcken gespeichert werden.

Struktur ext4_extent_header {
 __le16 eh_magic; /* ext4-Extents-Bezeichner: 0xF30A */
 __le16 eh_entries; /* Anzahl gültiger Knoten in der aktuellen Ebene*/
 __le16 eh_max; /* Maximale Anzahl von Knoten in der aktuellen Ebene*/
 __le16 eh_depth; /* Die Tiefe der aktuellen Ebene im Baum, 0 ist ein Blattknoten, also ein Datenknoten, >0 stellt einen Indexknoten dar*/
 __le32 eh_generation; 
}
Struktur ext4_extent {
 __le32 ee_block; /* logische Startblocknummer des Bereichs*/
 __le16 ee_len; /* Anzahl der im Extent enthaltenen Blöcke*/
 __le16 ee_start_hi; /*Höchste 16 Bits der physischen Adresse des Extent-Startblocks*/
 __le32 ee_start_lo; /*untere 32 Bits der physischen Adresse des Extent-Startblocks*/
}; //extent_body-Format im Datenknoten struct ext4_extent_idx {
 __le32 ei_block; /* Die logische Sequenznummer des Startblocks des vom Index abgedeckten Dateibereichs*/
 __le32 ei_leaf_lo; /* Speichert die unteren 32 Bits der physischen Adresse des Blocks der nächsten Ebene*/ 
 __le16 ei_leaf_hi; /* Die oberen 16 Bits der physischen Adresse des Blocks, der die Extents der nächsten Ebene speichert*/
 __u16 ei_unbenutzt;

}; //extent_body-Format im Indexknoten

Unten sehen Sie ein Beispiel für eine /var/log/messages-Datei:

Inode-Bitmap und Block-Bitmap

Es gibt Bereiche auf der Festplatte, die für die Speicherung von Blockdaten und Inodes vorgesehen sind. Wenn wir jedoch eine neue Datei erstellen möchten, müssen wir wissen, welcher Inode-Bereich und welcher Block leer sind. Dazu müssen wir einen Block zum Speichern der Inode-Bitmap und einen Block zum Speichern der Block-Bitmap verwenden. Jedes Bit ist 1 für belegt und 0 für unbelegt. Ein Block hat jedoch höchstens 4K*8=32K Bits, was bedeutet, dass er den Status von bis zu 32K Blöcken darstellen kann. Daher müssen diese Blöcke in einer Blockgruppe organisiert werden, um ein größeres System aufzubauen.

Hardlinks und Softlinks

Ein Hardlink teilt sich denselben Inode mit der Originaldatei und Inodes können nicht Dateisysteme überschreiten. Hardlinks können also auch keine Dateisysteme überschreiten.

Ein Softlink verfügt über einen eigenen Inode, zeigt beim Öffnen der Datei jedoch auf eine andere Datei. Er kann also Dateisysteme überschreiten und weiterhin vorhanden sein, wenn die Originaldatei gelöscht wird.

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Verwenden des Ext3-Dateisystems in einer Linux-Umgebung
  • Tutorial zum Anpassen der Größe der logischen LVM-Volume-Partition in Linux (für verschiedene Dateisysteme wie xfs und ext4)
  • Linux-Dateisysteme erklärt: ext4 und darüber hinaus
  • Verwenden Sie mysqladmin extended-status mit Linux-Befehlen, um den MySQL-Laufstatus unter Linux anzuzeigen

<<:  So kapseln Sie Axios in ein Vue-Projekt (einheitliche Verwaltung von HTTP-Anfragen)

>>:  Detaillierte Erläuterung gängiger MySQL-Befehle im Linux-Terminal

Artikel empfehlen

Zusammenfassung von 6 Methoden zur Anzeige von Linux-Protokollen

Als Backend-Programmierer haben Sie an vielen Ste...

So lösen Sie das Problem des verstümmelten MySQL-Inserts

Problembeschreibung: Beim Einfügen chinesischer Z...

Der praktische Prozess des Login-Status-Managements im vuex-Projekt

Inhaltsverzeichnis Werkzeug: Anmeldeszenario: übe...

Implementierung der Nginx-Flusskontrolle und Zugriffskontrolle

Nginx-Verkehrskontrolle Die Ratenbegrenzung ist e...

jQuery erzielt den Shutter-Effekt (mithilfe der Li-Positionierung)

In diesem Artikel wird der spezifische Code von j...

Eine kurze Diskussion zur Logikextraktion und Feldanzeige von Vue3 in Projekten

Inhaltsverzeichnis Logische Schichtung Trennen Si...

Lösung zum Verhindern des Caching in Seiten

Lösung: Fügen Sie in <head> den folgenden Co...

Detaillierte Erklärung zur Formatierung von Zahlen in MySQL

Aus beruflichen Gründen musste ich kürzlich Zahle...

Vue implementiert Funktionen zum Hoch- und Herunterladen von Dateien

In diesem Artikelbeispiel wird der spezifische Co...

Installieren Sie JDK1.8 in einer Linux-Umgebung

Inhaltsverzeichnis 1. Installationsumgebung 2. In...

CSS3-Randeffekte

Was ist CSS? CSS (Abkürzung für Cascading Style S...