tamanho do bloco de arquivo - diferença entre stat e ls

8

Eu notei que quando faço:

ls -ls file

Ele fornece contagem de blocos, digamos 8 blocos.

Quando faço:

stat file

Noto que a contagem de blocos é 16, o dobro do número dado por ls.

O tamanho do bloco no meu sistema de arquivos é 4096. Aprendi que a unidade arbitrária para blocos usada por ls é 1024. É correto dizer que stat usa uma unidade arbitrária de 512 bytes ao reportar blocos?

Em caso afirmativo, há uma razão para a inconsistência?

Estou executando o Ubuntu 11.10 em um sistema de arquivos ext4.

    
por stantona 10.01.2012 / 17:20

3 respostas

8

Muitos discos têm um tamanho de setor de 512 bytes, o que significa que qualquer leitura ou gravação no disco transfere um setor inteiro de 512 bytes de cada vez. É bastante natural projetar sistemas de arquivos em que um setor não é dividido entre arquivos (o que complicaria o design e prejudicaria o desempenho); portanto, sistemas de arquivos tendem a usar pedaços de 512 bytes para arquivos. Portanto, os utilitários tradicionais, como ls e du , indicam tamanhos em unidades de blocos de 512 bytes.

Para humanos, unidades de 512 bytes não são muito significativas. 1kB é a mesma ordem de magnitude e muito mais significativa. Um bloco de sistema de arquivos (a menor unidade na qual um arquivo é dividido) geralmente consiste em vários setores: 1kB, 2kB e 4kB são tamanhos de bloco de sistema de arquivos comuns; então a unidade de 512 bytes não é strongmente justificada pelo design do sistema de arquivos, e não há nenhuma boa razão além da tradição para usar uma unidade de 512 bytes fora de um driver de disco.

Então você tem uma tradição que não tem muito a ver e uma convenção mais legível que está sendo aceita. Um pouco como octal e hexadecimal: não há um que esteja certo e um que esteja errado, são formas diferentes de escrever os mesmos números.

Muitas ferramentas têm a opção de selecionar unidades de exibição: ls --block-size=512 para GNU ls , definindo POSIXLY_CORRECT=1 no ambiente para GNU df e GNU du para obter unidades de 512 bytes (ou passando -k para forçar unidades de 1kB). O que o comando stat em GNU coreutils expõe como o “tamanho do bloco” (o valor %B ) é um valor dependente do sistema operacional de uma interface interna; Dependendo do sistema operacional, ele pode ou não estar relacionado a um tamanho usado pelo sistema de arquivos ou código de disco (geralmente não é - veja Diferença entre o tamanho do bloco e o tamanho do cluster ). No Linux, o valor é 512, independentemente do que qualquer driver subjacente esteja fazendo. O valor de %B nunca importa, é apenas uma peculiaridade que existe.

    
por 11.01.2012 / 02:20
4

Depois de investigar o código-fonte e o padrão POSIX, eu diria que a resposta de @ antje-m e @Gilles está correta na maioria das vezes.

Vale a pena citar o comentário de POSIX.1-2008 , em resumo:

The use of 512-byte units is historical practice and maintains compatibility with ls and other utilities in this volume of POSIX.1-2008. This does not mandate that the file system itself be based on 512-byte blocks. The -k option was added as a compromise measure. It was agreed by the standard developers that 512 bytes was the best default unit because of its complete historical consistency on System V (versus the mixed 512/1024-byte usage on BSD systems), and that a -k option to switch to 1024-byte units was a good compromise. Users who prefer the more logical 1024-byte quantity can easily alias df to df -k without breaking many historical scripts relying on the 512-byte units.

Para o tamanho do bloco em ls -s :

O POSIX diz que o tamanho padrão do bloco é definido pela implementação, a menos que -k opção é dada.

O tamanho de bloco padrão implementado em GNU coreutils ls está definido em 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

que vem de um commit antigo:

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

A própria mensagem de commit não diz nada sobre o número 1024.

E observe que o tamanho do bloco usado em du e df também é 1024, ls apenas escolheu consistir com eles. Embora para du e df seja um conflito com o padrão POSIX (então aqui a variável de ambiente POSIXLY_CORRECT vem). Isso parece ser uma decisão da equipe GNU, consulte a página da Wikipedia POSIX sobre essa controvérsia.

Para o comando stat .

Não faz parte do padrão POSIX, mas o stat chamada de sistema é. No entanto, a unidade para tamanho de bloco não é padronizada ( sys_stat.h ):

The unit for the st_blocks member of the stat structure is not defined within POSIX.1-2008.

O comando stat simplesmente exibe as informações fornecidas por stat system call e usa o tamanho do bloco 512 com poucas exceções (são não-Linux, por exemplo, HP-UX, IBM AIX, etc., veja as macros definidas em gnulib/lib/stat-size.h ).

Assim, o número 512 é mais uma escolha histórica e uma convenção do Linux.

O GNU coreutils (daí o comando ls ) não faz parte do kernel do Linux (daí a stat call), eles estão direcionando diferentes aspectos do sistema, GNU coreutils é mais para humanos (mais fácil de ler) e o kernel do Linux para resumo de hardware (portanto, mais próximo do hardware).

Editar: o tamanho do bloco 4096 é o tamanho do "bloco IO", o tamanho real do bloco físico provavelmente ainda é 512 Byte como explicado nesta questão .

    
por 23.08.2017 / 15:40
1

O comando stat usa o tamanho físico do disco rígido. Basicamente, todo o disco rígido desde a sua criação em 1956 usou blocos de 512 bytes. No entanto, isso começou recentemente a mudar com o próximo formato avançado.

Eu suspeito que ls '1024byte-blocksize também tenha uma razão histórica. Talvez tenha sido comum o sistema de arquivos ter um tamanho de blocos de 1024 ou ter sido usado para fornecer o tamanho em kilobyte. Mas (pelo menos com GNU coreutils ) você pode especificar o tamanho do bloco com a opção --block-size= .

    
por 10.01.2012 / 21:28