15 Stimmen

Wie berechnet der stat-Befehl die Blöcke einer Datei?

Ich frage mich, wie das stat-Kommando die Anzahl der Blöcke für eine Datei berechnet. Ich habe diesen Artikel gelesen, der besagt:

Der Wert st_blocks gibt die Größe der Datei in 512-Byte-Blöcken an. (Dies kann kleiner sein als st_size/512 z.B. wenn die Datei Löcher hat.) Der Wert st_blksize gibt die "bevorzugte" Blockgröße für effizientes Dateisystem-I/O an. (Schreiben in eine Datei in kleineren Stückchen kann ein ineffizientes Lese-Ändern-Neuschreiben verursachen.)

Doch ich kann dies nicht mit meinen eigenen Tests verifizieren.

Mein Dateisystem ist ext3.

Der Befehl dumpe2fs -h /dev/sda3 zeigt:

...
Erster Block: 0
Blockgröße: 4096
Fragmentgröße: 4096
...

Dann führe ich aus

kent@KentT60:~/Desktop$ stat Email
Datei: `Email'
Größe: 965 Blöcke: 8 IO-Block: 4096 reguläre Datei
Gerät: 80ah/2058d Inode: 746095 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Zugriff: 2009-08-11 21:36:36.000000000 +0200
Ändern: 2009-08-11 21:36:35.000000000 +0200
Änderung: 2009-08-11 21:36:35.000000000 +0200

Wenn "Blöcke" hier bedeutet: "wie viele 512-Byte-Blöcke", sollte die Zahl 2 und nicht 8 sein. Ich dachte, dass die Blockgröße des Dateisystems (IO-Block) 4k ist.

Wenn das Dateisystem die Datei Email erhält, werden mindestens 4k von der Festplatte abgerufen (8 x 512-Byte-Blöcke), was bedeutet 965/512 + 6 = 8. Ich bin mir nicht sicher, ob diese Vermutung korrekt ist.

Noch ein Test:

kent@KentT60:~/Desktop$ stat wxPython-demo-2.8.10.1.tar.bz2
Datei: `wxPython-demo-2.8.10.1.tar.bz2'
Größe: 3605257 Blöcke: 7056 IO-Block: 4096 reguläre Datei
Gerät: 80ah/2058d Inode: 746210 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 1000/ kent) Gid: ( 1000/ kent)
Zugriff: 2009-08-12 21:45:45.000000000 +0200
Ändern: 2009-08-12 21:43:46.000000000 +0200
Änderung: 2009-08-12 21:43:46.000000000 +0200

3605257/512=7041.xx = 7042

Nach meiner obigen Vermutung würde dies 7042 + 6 = 7048 sein. Aber das stat-Ergebnis zeigt 7056.

Und ein weiteres Beispiel aus dem Internet unter https://www.computerhope.com/unix/stat.htm. Ich habe das Beispiel unten auf der Seite eingefügt:

Datei: `index.htm'
Größe: 17137 Blöcke: 40 IO-Block: 8192 reguläre Datei
Gerät: 8h/8d Inode: 23161443 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: (17433/comphope) Gid: ( 32/ www)
Zugriff: 2007-04-03 09:20:18.000000000 -0600
Ändern: 2007-04-01 23:13:05.000000000 -0600
Änderung: 2007-04-02 16:36:21.000000000 -0600

In diesem Beispiel beträgt die Blockgröße des Dateisystems 8k. Ich vermute, dass der Wert "Blöcke" 16xN sein sollte, aber es sind 40. Ich verliere den Überblick...

Kann mir jemand erklären, wie stat den Wert "Blöcke" berechnet?

Danke!

0 Stimmen

stat Die Ausgabe ist ein bisschen tückisch: Die Blockgröße von "Blocks" beträgt 512 Bytes, während die Blockgröße von "IO Block" üblicherweise 4096 Bytes beträgt (für ext4). Ich habe versucht, diesem in dieser Antwort auf den Grund zu gehen.

23voto

Barry Kelly Punkte 40566

Das Befehlszeilentool stat verwendet die Funktionen stat / fstat usw., die Daten in der Struktur stat zurückgeben. Das Element st_blocks der Struktur stat gibt zurück:

Die Gesamtzahl der physischen Blöcke der Größe 512 Bytes, die tatsächlich auf der Festplatte allokiert sind. Dieses Feld ist für Blockspezialdateien oder Zeichenspezialdateien nicht definiert.

Also für Ihr Beispiel "E-Mail" mit einer Größe von 965 und einer Blockanzahl von 8 zeigt es an, dass 8*512=4096 Bytes physikalisch auf der Festplatte allokiert sind. Der Grund, warum es nicht 2 ist, liegt darin, dass das Dateisystem auf der Festplatte keinen Speicherplatz in Einheiten von 512 zuweist, sondern offensichtlich in Einheiten von 4096. (Und die Zuordnungseinheit kann je nach Dateigröße und Dateisystemkomplexität variieren. Z.B. unterstützt ZFS verschiedene Zuordnungseinheiten.)

Ebenso zeigt das wxPython-Beispiel an, dass 7056*512 Bytes oder 3612672 Bytes physikalisch auf der Festplatte allokiert sind. Sie verstehen die Idee.

Die IO-Blockgröße ist "ein Hinweis auf die 'beste' Einheitsgröße für I/O-Operationen" - normalerweise ist es die Zuordnungseinheit auf der physischen Festplatte. Verwechseln Sie nicht den IO-Block mit dem Block, den stat zur Angabe der physischen Größe verwendet; die Blöcke für die physische Größe sind immer 512 Bytes.

Update basierend auf Kommentar:

Wie gesagt, st_blocks ist die Art und Weise, wie das Betriebssystem angibt, wie viel Speicherplatz von der Datei auf der Festplatte verwendet wird. Die tatsächlichen Zuordnungseinheiten auf der Festplatte sind die Wahl des Dateisystems. Zum Beispiel kann ZFS Zuordnungsblöcke variabler Größe haben, sogar in derselben Datei, aufgrund der Art und Weise, wie es Blöcke zuweist: Dateien haben anfangs eine kleine Blockgröße, und die Blockgröße erhöht sich weiter, bis sie einen bestimmten Punkt erreicht. Wenn die Datei später gekürzt wird, behält sie wahrscheinlich die alte Blockgröße bei. Basierend auf der Historie der Datei kann sie also mehrere mögliche Blockgrößen haben. Daher ist es anhand einer Dateigröße nicht immer offensichtlich, warum sie eine bestimmte physische Größe hat.

Konkretes Beispiel: Auf meinem Solaris-Rechner mit einem ZFS-Dateisystem kann ich eine sehr kurze Datei erstellen:

$ echo foo > test
$ stat test
  Größe: 4               Blöcke: 2          IO-Block: 512    reguläre Datei
(unerhebliche Details weggelassen)

OK, kleine Datei, 2 Blöcke, physische Festplattennutzung beträgt 1024 für diese Datei.

$ dd if=/dev/zero of=test2 bs=8192 count=4
$ stat test2
  Größe: 32768           Blöcke: 65         IO-Block: 32768  reguläre Datei

OK, jetzt sehen wir eine physische Festplattennutzung von 32,5K und eine IO-Blockgröße von 32K. Ich habe es dann nach test3 kopiert und diese test3-Datei in einem Editor gekürzt:

$ cp test2 test3
$ joe -hex test3
$ stat test3
  Größe: 4               Blöcke: 65         IO-Block: 32768  reguläre Datei

Nun, hier ist eine Datei mit 4 Bytes - genau wie test - aber sie verwendet 32,5K physikalisch auf der Festplatte, aufgrund der Art und Weise, wie das ZFS-Dateisystem Speicherplatz zuweist. Die Blockgrößen nehmen mit zunehmender Dateigröße zu, aber sie nehmen nicht ab, wenn die Datei kleiner wird. (Und ja, dies kann zu erheblichem Platzverschwendung führen, abhängig von den Arten von Dateien und Dateioperationen, die Sie auf ZFS durchführen, weshalb es Ihnen ermöglicht, die maximale Blockgröße pro Dateisystem festzulegen und dynamisch zu ändern.)

Hoffentlich können Sie jetzt schätzen, dass es nicht zwangsläufig eine einfache Beziehung zwischen Dateigröße und physischer Festplattennutzung gibt. Auch oben ist nicht klar, warum 32,5K Bytes benötigt werden, um eine Datei zu speichern, die genau 32K groß ist - es scheint, dass ZFS im Allgemeinen zusätzliche 512 Bytes für zusätzlichen Speicherplatz verwendet. Vielleicht verwendet es diesen Speicher für Prüfsummen, Referenzzähler, Transaktionsstatus - Dateisystem-Buchhaltung. Indem es diese Extras in der angezeigten physischen Dateigröße einschließt, scheint ZFS zu versuchen, den Benutzer nicht über die physischen Kosten der Datei zu täuschen. Das bedeutet jedoch nicht, dass es trivial ist, die Berechnung ohne genaue Kenntnisse über die zugrunde liegende Dateisystemimplementierung rückgängig zu machen.

0 Stimmen

Zustimmung. st_blocks wird nur aus historischen Gründen so genannt. Denken Sie nicht an Blöcke, sondern an die Menge an Festplattenspeicher, die von der Datei verwendet wird, in Einheiten von 512 Byte. 512 Byte ist eine praktische Einheit, da es praktisch die kleinste Zuordnungseinheit ist, die jemand verwendet.

0 Stimmen

Vielen Dank für die Erklärung. Fast klar. Aber ich habe immer noch Fragen. Ich bin mir nicht sicher, ob das richtig verstanden wurde: st_blocks = (IO-Blockgröße / 512) * (wie viele IO-Blöcke die Datei verwendet hat). Das E-Mail-Beispiel kann so erklärt werden: (4096/512) * 1 = 8 wxPython nicht. Denn die Datei hat 881 IO-Blöcke verwendet, und (4096/512)*881 = 7048, nicht 7056. Und das letzte Beispiel auch nicht: 40 kann nicht genau durch 16 (8192/512) geteilt werden. Sind die "512 Bytes" für alle Systeme gleich? Vielen Dank.

0voto

Alex Punkte 723

Ich spreche nicht über komplexe Dateisysteme wie ZFS
aber was einfache Dateisysteme wie ext2 betrifft:
- Das Ausgabefeld "IO-Block" in "stat" zeigt "Blockgröße des ext2-Dateisystems" an
- Das Ausgabefeld "Blocks" zeigt die Anzahl der nicht vorhandenen virtuellen Blöcke (jeweils 512 Byte) an. Das bedeutet, dass "stat" die Dateigröße aus dem Feld "Größe" nimmt, durch 512 teilt und in die Antwort einfügt.

Ein Beispiel. Eine Datei hat die Größe von 2 Byte.

# od -t x1 ./1
0000000 31 0a
0000002

Ein Dateisystem ist mit einer Blockgröße von 4K formatiert Schauen wir uns "stat" an

# stat 1
  Datei: 1
  Größe: 2           Blöcke: 8          IO-Block: 4096   normale Datei
Gerät: 811h/2065d  Inode: 12          Links: 1

IO-Block zeigt 4096, das sind 4K, das ist die Blockgröße des ext2-Dateisystems. Da eine Datei nicht weniger Platz als die Blockgröße des Dateisystems belegen kann, befinden sich 2 Byte in einem 4K-Block = 4096 Byte. Wir teilen 4096 durch 512 und erhalten 8. Dies ist die Zahl im Feld "Blöcke".

Nehmen wir ein anderes ext2-Dateisystem mit einer Blockgröße von 1K.

# stat 1
  Datei: 1
  Größe: 2           Blöcke: 2          IO-Block: 1024   normale Datei

IO-Block = 1024, das ist genau die Blockgröße des Dateisystems (1K)

Die Datei kann nicht weniger als 1K Speicherplatz belegen. Daher belegen 2 Bytes 1K Speicherplatz.

Wir teilen 1024 durch 512 und erhalten 2. Das ist genau das, was wir in

Blöcke: 2

-1voto

santhosh Punkte 1

Hier müssen wir beachten, dass die Datenblockzuweisung auf die unten angegebene Weise erfolgt:

1) standardmäßig werden 8 Datenblöcke für eine Datei zugewiesen, auch wenn wir Daten von einem Byte in die Datei schreiben. 2) Wenn wir fertig sind, Daten von 8*4096 Bytes in die Datei hinzuzufügen, und danach ein zusätzliches Byte hinzufügen, werden erneut neue 8 Datenblöcke zugewiesen. Insgesamt also 16 Datenblöcke.

WENN SIE DIE OBIGEN AUSSAGEN VERSTEHEN, dann --------(in der Frage)----------------- also für 965 werden standardmäßig 8 Datenblöcke zugewiesen und wenn es genau 4*4096=32768 ist und wenn wir all diese füllen und dann ein weiteres Byte hinzufügen, werden 8 Datenblöcke zugewiesen und für die Größe von 32769 insgesamt 16 Datenblöcke zugewiesen.

1 Stimmen

"... das Hinzufügen von Daten von 8*4096 Byte in die Datei ...". Wenn stat Blocks: 8 schreibt, bedeutet das, dass acht Blöcke von 512 Byte für die Datei allokiert wurden, nicht acht Blöcke von 4096 Byte. IO Block: 4096 bezieht sich auf die bevorzugte Dateisystem-Blockgröße, diese Blockgröße beträgt nie 512 Byte auf ext4. Siehe diese Antwort von mir für mehr Informationen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X