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

9

Percebi que quando faço um:

ls -ls file

Ele fornece contagem de blocos, digamos 8 blocos.

Quando eu faço:

stat file

Percebo 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 dos blocos usados ​​por ls é 1024. É correto dizer que o stat usa uma unidade arbitrária de 512 bytes ao reportar blocos?

Em caso afirmativo, existe um motivo para a inconsistência?

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

Stantona
fonte

Respostas:

9

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 por vez. É bastante natural projetar sistemas de arquivos onde um setor não é dividido entre arquivos (isso complicaria o design e prejudicaria o desempenho); portanto, os sistemas de arquivos tendem a usar blocos de 512 bytes para arquivos. Portanto, utilitários tradicionais como lse duindicam 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 em que um arquivo é dividido) geralmente consiste em vários setores: 1kB, 2kB e 4kB são tamanhos comuns de blocos de sistema de arquivos; portanto, a unidade de 512 bytes não é fortemente justificada pelo design do sistema de arquivos e não há outra razão além da tradição para usar uma unidade de 512 bytes fora de um driver de disco.

Portanto, você tem uma tradição que não tem muito a oferecer e uma convenção mais legível que está em andamento. Um pouco como octal e hexadecimal: não há um que esteja certo e outro que esteja errado, são maneiras diferentes de escrever os mesmos números.

Muitas ferramentas têm uma opção para selecionar unidades de exibição: ls --block-size=512para GNU ls, configurando POSIXLY_CORRECT=1no ambiente para GNU dfe GNU duobter unidades de 512 bytes (ou passando -kpara forçar unidades de 1kB). O que o statcomando no GNU coreutils expõe como o "tamanho do bloco" (o %Bvalor) é um valor dependente do SO de uma interface interna; dependendo do sistema operacional, ele pode ou não estar relacionado a um tamanho usado pelo sistema de arquivos ou pelo código do disco (geralmente não é - consulte 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 %Bnunca importa, é apenas uma peculiaridade de que existe.

Gilles 'SO- parar de ser mau'
fonte
4

Depois de pesquisar o código fonte e o padrão POSIX, eu diria que a resposta de @ antje-me @Gilles está correta.

Vale citar o comentário do POSIX.1-2008 , como um resumo:

O uso de unidades de 512 bytes é prática histórica e mantém a compatibilidade com sl e outros utilitários neste volume do POSIX.1-2008. Isso não exige que o próprio sistema de arquivos seja baseado em blocos de 512 bytes. A opção -k foi adicionada como uma medida de compromisso. Foi acordado pelos desenvolvedores padrão que 512 bytes era a melhor unidade padrão por causa de sua completa consistência histórica no Sistema V (versus o uso misto de 512/1024 bytes em sistemas BSD) e a opção -k para mudar para 1024- unidades de bytes foi um bom compromisso. Os usuários que preferem a quantidade mais lógica de 1024 bytes podem facilmente alias df a df -k sem quebrar muitos scripts históricos que dependem das unidades de 512 bytes.

Para o tamanho do bloco em ls -s:

O POSIX diz que o tamanho do bloco padrão é definido pela implementação, a menos que a -kopção seja fornecida.

O tamanho do bloco padrão implementado em GNU coreutils lsé 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 confirmação não disse nada sobre o número 1024.

E observe que o tamanho do bloco usado due dftambém é 1024, lsapenas escolheu consistir com eles. Embora para due dfseja um conflito com o padrão POSIX (então aqui a variável de ambiente POSIXLY_CORRECTvem). Parece ser uma decisão da equipe GNU, veja a página da Wikipédia POSIX sobre essa controvérsia.

Para o comando stat.

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

A unidade para o membro st_blocks da estrutura stat não está definida no POSIX.1-2008.

O statcomando simplesmente exibe as informações fornecidas pela statchamada do sistema e, usando o tamanho de 512 blocos, com poucas exceções (elas não são Linux, por exemplo, HP-UX, IBM AIX etc., consulte as macros definidas em gnulib/lib/stat-size.h).

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

O GNU coreutils(daí o lscomando) não faz parte do kernel do Linux (daí a statchamada), eles têm como alvo aspectos diferentes do sistema, GNU coreutilssão mais para humanos (mais fáceis de ler) e o kernel do Linux para abstratos de hardware (portanto, mais próximos do hardware).

Edit: o tamanho do bloco 4096 é o tamanho "IO block", o tamanho real do bloco físico provavelmente ainda é de 512 bytes, conforme explicado nesta pergunta .

Eddy Xiao
fonte
1

Os statcomandos usam o tamanho físico do bloco do disco rígido. Basicamente, todos os discos rígidos desde a sua criação em 1956 usaram blocos de 512 bytes. No entanto, isso começou recentemente a mudar com a chegada do formato avançado.

Suspeito que lso tamanho do bloco de 1024 bytes também tenha uma razão histórica. Talvez tenha sido comum o sistema de arquivos ter um tamanho de bloco 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 --block-size=opção

antje-m
fonte