Dateiblockgröße - Unterschied zwischen stat und ls

9

Ich habe das bemerkt, wenn ich mache:

ls -ls file

Es bietet eine Blockanzahl von beispielsweise 8 Blöcken.

Wenn ich es tue:

stat file

Ich stelle fest, dass die Blockanzahl 16 ist, doppelt so hoch wie die von ls.

Die Blockgröße in meinem Dateisystem beträgt 4096. Ich habe erfahren, dass die willkürliche Einheit für von ls verwendete Blöcke 1024 ist. Ist es richtig zu sagen, dass stat beim Melden von Blöcken eine willkürliche Einheit von 512 Bytes verwendet?

Wenn ja, gibt es einen Grund für die Inkonsistenz?

Ich verwende Ubuntu 11.10 auf einem ext4-Dateisystem.

Stantona
quelle

Antworten:

9

Viele Festplatten haben eine Sektorgröße von 512 Bytes, was bedeutet, dass jedes Lesen oder Schreiben auf der Festplatte jeweils einen ganzen 512-Byte-Sektor überträgt. Es ist ganz natürlich, Dateisysteme zu entwerfen, bei denen ein Sektor nicht zwischen Dateien aufgeteilt ist (was das Design erschweren und die Leistung beeinträchtigen würde). Daher verwenden Dateisysteme in der Regel 512-Byte-Blöcke für Dateien. Daher geben herkömmliche Dienstprogramme wie lsund duGrößen in Einheiten von 512-Byte-Blöcken an.

Für den Menschen sind 512-Byte-Einheiten nicht sehr aussagekräftig. 1 kB ist die gleiche Größenordnung und viel aussagekräftiger. Ein Dateisystemblock (die kleinste Einheit, in die eine Datei unterteilt ist) besteht tatsächlich häufig aus mehreren Sektoren: 1 KB, 2 KB und 4 KB sind übliche Dateisystemblockgrößen; Daher ist die 512-Byte-Einheit durch das Dateisystemdesign nicht stark gerechtfertigt, und es gibt keinen anderen guten Grund als die Tradition, eine 512-Byte-Einheit überhaupt außerhalb eines Festplattentreibers zu verwenden.

Sie haben also eine Tradition, die nicht viel zu bieten hat, und eine besser lesbare Konvention, die sich durchsetzt. Ein bisschen wie oktal und hexadezimal: Es gibt keine, die richtig und eine falsch ist, sie sind verschiedene Arten, die gleichen Zahlen zu schreiben.

Viele Tools haben die Option, Anzeigeeinheiten auszuwählen: ls --block-size=512für GNU ls, Einstellung POSIXLY_CORRECT=1in der Umgebung für GNU dfund GNU du, um 512-Byte-Einheiten zu erhalten (oder Übergabe -k, um 1-kB-Einheiten zu erzwingen). Was der statBefehl in GNU coreutils als "Blockgröße" (der %BWert) verfügbar macht, ist ein betriebssystemabhängiger Wert einer internen Schnittstelle. Abhängig vom Betriebssystem kann es mit einer Größe zusammenhängen, die vom Dateisystem oder vom Festplattencode verwendet wird (normalerweise nicht - siehe Unterschied zwischen Blockgröße und Clustergröße ). Unter Linux beträgt der Wert 512, unabhängig davon, was ein zugrunde liegender Treiber tut. Der Wert von spielt %Bnie eine Rolle, es ist nur eine Eigenart, dass es überhaupt existiert.

Gilles 'SO - hör auf böse zu sein'
quelle
4

Nachdem ich mich mit dem Quellcode und dem POSIX-Standard befasst habe, würde ich sagen, dass die Antwort von @ antje-m und @Gilles größtenteils richtig ist.

Es lohnt sich, den Kommentar von POSIX.1-2008 als Zusammenfassung zu zitieren :

Die Verwendung von 512-Byte-Einheiten ist eine historische Praxis und gewährleistet die Kompatibilität mit ls und anderen Dienstprogrammen in diesem Band von POSIX.1-2008. Dies erfordert nicht, dass das Dateisystem selbst auf 512-Byte-Blöcken basiert. Die Option -k wurde als Kompromissmaßnahme hinzugefügt. Die Standardentwickler waren sich einig, dass 512 Bytes aufgrund ihrer vollständigen historischen Konsistenz auf System V (im Vergleich zur gemischten Verwendung von 512/1024 Bytes auf BSD-Systemen) die beste Standardeinheit sind und dass eine -k-Option zum Umschalten auf 1024 Byte besteht. Byte-Einheiten waren ein guter Kompromiss. Benutzer, die die logischere Menge von 1024 Byte bevorzugen, können problemlos df zu df -k aliasen, ohne viele historische Skripte zu beschädigen, die auf den 512-Byte-Einheiten basieren.

Für die Blockgröße in ls -s:

Der POSIX gibt an, dass die Standardblockgröße implementierungsdefiniert ist, sofern keine -kOption angegeben ist.

Die in implementierte Standardblockgröße GNU coreutils lsist definiert in GNU gnulib: gnulib/lib/human.c

/* The default block size used for output.  This number may change in
   the future as disks get larger.  */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif

das kommt von einem alten Commit:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <[email protected]>
Date:   Mon Jun 29 15:23:04 1998 +0000

Die Festschreibungsnachricht selbst sagte nichts über die Nummer 1024 aus.

Und beachten Sie, dass die Blockgröße, die in duund dfauch 1024 verwendet wird, lsnur gewählt wurde, um mit ihnen zu bestehen. Obwohl für duund dfes ein Konflikt zum POSIX-Standard ist (hier POSIXLY_CORRECTkommt also die Umgebungsvariable ). Dies scheint eine Entscheidung des GNU-Teams zu sein, siehe die Wikipedia-Seite POSIX zu dieser Kontroverse.

Für den Befehl stat.

Es ist kein Teil des POSIX-Standards, aber der Systemaufruf ist. Die Einheit für die Blockgröße ist jedoch nicht standardisiert ( sys_stat.h ):stat

Die Einheit für das st_blocks-Mitglied der stat-Struktur ist in POSIX.1-2008 nicht definiert.

Der statBefehl zeigt einfach die durch den statSystemaufruf bereitgestellten Informationen an und verwendet mit wenigen Ausnahmen die Blockgröße 512 (es handelt sich um Nicht-Linux- Informationen , z. B. HP-UX, IBM AIX usw., siehe die in definierten Makros gnulib/lib/stat-size.h).

Die Nummer 512 ist also eher eine historische Wahl und eine Linux-Konvention.

Der GNU coreutils(daher der lsBefehl) ist kein Teil des Linux-Kernels (daher der statAufruf), er zielt auf verschiedene Systemaspekte ab, GNU coreutilsist eher für Menschen (einfacher zu lesen) und der Linux-Kernel für Hardware-Abstracts (daher näher an Hardware).

Bearbeiten: Die Blockgröße 4096 ist die Größe des "E / A-Blocks". Die tatsächliche physische Blockgröße beträgt wahrscheinlich immer noch 512 Byte, wie in dieser Frage erläutert .

Eddy Xiao
quelle
1

Die statBefehle verwenden die physische Blockgröße der Festplatte. Grundsätzlich haben alle Festplatten seit ihrer Gründung im Jahr 1956 512-Byte-Blöcke verwendet. Dies hat sich jedoch seit kurzem mit der Einführung des erweiterten Formats geändert.

Ich vermute, dass lsdie Blockgröße von 1024 Byte auch einen historischen Grund hat. Vielleicht war es einmal üblich, dass das Dateisystem eine Blockgröße von 1024 hatte, oder es wurde verwendet, um die Größe in Kilobyte anzugeben. Aber (zumindest mit GNU coreutils) können Sie die Blockgröße mit der --block-size=Option angeben .

antje-m
quelle