dimensione del blocco file - differenza tra stat e ls


9

Ho notato che quando faccio un:

ls -ls file

Fornisce il conteggio dei blocchi, diciamo 8 blocchi.

Quando io faccio:

stat file

Vedo che il conteggio dei blocchi è 16, il doppio del numero dato da ls.

La dimensione del blocco sul mio file system è 4096. Ho appreso che l'unità arbitraria per i blocchi utilizzati da ls è 1024. È corretto dire che stat utilizza un'unità arbitraria di 512 byte quando segnala i blocchi?

In tal caso, c'è un motivo per l'incoerenza?

Sto eseguendo Ubuntu 11.10 su un file system ext4.

Risposte:


9

Molti dischi hanno una dimensione del settore di 512 byte, il che significa che qualsiasi lettura o scrittura sul disco trasferisce un intero settore di 512 byte alla volta. È del tutto naturale progettare filesystem in cui un settore non è suddiviso tra file (il che complicherebbe la progettazione e danneggerebbe le prestazioni); pertanto i filesystem tendono ad usare blocchi da 512 byte per i file. Quindi utility tradizionali come lse duindicano dimensioni in unità di blocchi da 512 byte.

Per l'uomo, le unità da 512 byte non sono molto significative. 1kB è lo stesso ordine di grandezza e molto più significativo. Un blocco di filesystem (la più piccola unità in cui è diviso un file) in realtà è spesso composto da diversi settori: 1kB, 2kB e 4kB sono dimensioni comuni dei blocchi di filesystem; quindi l'unità da 512 byte non è fortemente giustificata dalla progettazione del filesystem, e non vi è alcuna buona ragione se non quella tradizionale di utilizzare un'unità da 512 byte al di fuori di un driver del disco.

Quindi hai una tradizione che non ha molto da fare e una convenzione più leggibile che sta prendendo piede. Un po 'come ottale ed esadecimale: non ce n'è uno giusto e uno sbagliato, sono modi diversi di scrivere gli stessi numeri.

Molti strumenti hanno un'opzione per selezionare le unità di visualizzazione: ls --block-size=512per GNU ls, impostazione POSIXLY_CORRECT=1nell'ambiente per GNU dfe GNU duper ottenere unità da 512 byte (o passaggio -kper forzare unità da 1kB). Ciò che il statcomando in GNU coreutils espone come "dimensione del blocco" (il %Bvalore) è un valore dipendente dal sistema operativo di un'interfaccia interna; a seconda del sistema operativo, potrebbe essere o meno correlato a una dimensione utilizzata dal filesystem o dal codice del disco (di solito non lo è - vedere Differenza tra dimensione del blocco e dimensione del cluster ). Su Linux, il valore è 512, indipendentemente da ciò che sta facendo qualsiasi driver sottostante. Il valore di %Bnon importa mai, è solo una stranezza che esiste affatto.


4

Dopo aver scavato nel codice sorgente e nello standard POSIX, direi che la risposta di @ antje-m e @Gilles è per lo più corretta.

Vale la pena citare il commento di POSIX.1-2008 , come riassunto:

L'uso di unità da 512 byte è una pratica storica e mantiene la compatibilità con ls e altre utilità in questo volume di POSIX.1-2008. Ciò non impone che il file system stesso sia basato su blocchi da 512 byte. L'opzione -k è stata aggiunta come misura di compromesso. Gli sviluppatori standard hanno concordato che 512 byte era la migliore unità predefinita a causa della sua completa coerenza storica sul Sistema V (rispetto all'utilizzo misto da 512/1024 byte sui sistemi BSD) e che l'opzione -k per passare a 1024- le unità byte erano un buon compromesso. Gli utenti che preferiscono la quantità più logica di 1024 byte possono facilmente alias df a df -k senza rompere molti script storici basandosi sulle unità da 512 byte.

Per la dimensione del blocco in ls -s:

POSIX afferma che la dimensione del blocco predefinita è definita dall'implementazione, a meno che non -kvenga fornita l'opzione.

La dimensione del blocco predefinita implementata in GNU coreutils lsè definita 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

che proviene da un vecchio commit:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <jim@meyering.net>
Date:   Mon Jun 29 15:23:04 1998 +0000

Il messaggio stesso di commit non ha detto nulla sul numero 1024.

E nota che la dimensione del blocco usata in dued dfè anche 1024, ha lsappena scelto di consistere con loro. Anche se per dued dfè una conflitto con lo standard POSIX (quindi qui POSIXLY_CORRECTarriva la variabile d'ambiente ). Questa è una decisione del team GNU, vedere la pagina POSIX di Wikipedia su questa controversia.

Per il comando stat.

Non fa parte dello standard POSIX, ma lo è la chiamata di sistema . Tuttavia, l'unità per la dimensione del blocco non è standardizzata ( sys_stat.h ):stat

L'unità per il membro st_blocks della struttura stat non è definita in POSIX.1-2008.

Il statcomando visualizza semplicemente le informazioni fornite dalla statchiamata di sistema e utilizzando 512 blocchi di dimensioni con poche eccezioni (sono non Linux, ad esempio HP-UX, IBM AIX ecc. Vedere le macro definite in gnulib/lib/stat-size.h).

Quindi il numero 512 è più una scelta storica e una convenzione di Linux.

Il GNU coreutils(da qui il lscomando) non fa parte del kernel Linux (da qui la statchiamata), stanno prendendo di mira aspetti di sistema diversi, GNU coreutilsè più per umani (più facile da leggere), e kernel Linux per abstract hardware (quindi più vicino all'hardware).

Modifica: la dimensione del blocco 4096 è la dimensione del "blocco IO", la dimensione del blocco fisico reale è probabilmente ancora 512 byte, come spiegato in questa domanda .


1

I statcomandi utilizzano la dimensione fisica del blocco del disco rigido. Fondamentalmente tutti i dischi rigidi sin dal loro inizio nel 1956 hanno usato blocchi di 512 byte. Tuttavia, questo ha recentemente iniziato a cambiare con l'imminente formato avanzato.

Sospetto che ls'1024byte-blocksize abbia anche una ragione storica. Forse una volta era comune che il filesystem avesse una dimensione di blocco di 1024 o era usato per darti la dimensione in kilobyte. Ma (almeno con GNU coreutils) puoi specificare la dimensione del blocco con l' --block-size=opzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.