Se eu tiver o seguinte conteúdo em um diretório:
empty_dir
: diretório vazio.empty_file
: Arquivo vazio.one_char
: Arquivo que consiste em um caractere.several_blocks
: Arquivo composto por vários blocos (mas não "muito" grande ou "esparso").
Em seguida, ls
exibirá o seguinte †:
$ ls -Gghs
total 152K
8,0K drwxr-xr-x 2 4,0K dec 21 23:34 empty_dir
4,0K -rw-r--r-- 1 0 dec 21 23:21 empty_file
8,0K -rw-r--r-- 1 1 dec 21 23:22 one_char
132K -rw-r--r-- 1 127K dec 22 00:14 several_blocks
Em segundo lugar, stat
exibe o seguinte:
$ stat empty_dir/
File: empty_dir/
Size: 4096 Blocks: 16 IO Block: 4096 directory
...
$ stat empty_file
File: empty_file
Size: 0 Blocks: 8 IO Block: 4096 regular empty file
...
$ stat one_char
File: one_char
Size: 1 Blocks: 16 IO Block: 4096 regular file
...
$ stat several_blocks
File: several_blocks
Size: 129760 Blocks: 264 IO Block: 4096 regular file
...
Em terceiro lugar, du
exibe o seguinte:
$ du -h empty_dir/
8,0K empty_dir/
$ du -h empty_file
4,0K empty_file
$ du -h one_char
8,0K one_char
$ du -h several_blocks
132K several_blocks
Por último:
$ tune2fs /dev/nvme0n1p2 -l
...
Block size: 4096
...
Inode size: 256
...
O tamanho dos blocos relatados por stat
é 512 B, o que significa que a saída entre stat
, ls
e du
é consistente:
empty_dir
: 16 * 512 / 1024 = 4096 + 4096 = 8 KiB.empty_file
: 8 * 512 / 1024 = 0 + 4096 = 4 KiB.one_char
: 16 * 512 / 1024 = 4096 + 4096 = 8 KiB.several_blocks
: 264 * 512 / 1024 = 129760 + 5408 = 129760 + 1312 + 4096 = 131072 + 4096 = 32 * 4096 + 4096 = 132 KiB.
Perguntas
- Why is the allocated size for
empty_dir
andone_char
two blocks (of size 4096 B) and not one? - Why is the allocated size for
empty_file
one block and not zero? - Why is the allocated size for
several_blocks
(and larger files in general) more than one block larger than the apparent size ((264 * 512) - 129760 = 5408 > 4096)?
Eu suspeito que o bloco adicional é aquele que contém o inode
, como este questionador pergunta (mas não é respondido). Da mesma forma, este questionador observou o tamanho duplo, mas é formulado incorretamente na pergunta e recebe uma resposta para a outra parte da pergunta. No entanto, esta resposta a uma pergunta diferente sugere que não deve haver bloqueios adicionais (que foi minha intuição).
- Nossos sistemas estão configurados incorretamente?
- Supondo que o bloco que contém o
inode
seja contado: Ao usardu
em vários arquivos, compensa contar oinode
bloco várias vezes, deveinodes
ser múltiplo no mesmo bloco (já que um bloco pode conter 16inodes
(4096 / 256 = 16))?
Apêndice
@WumpusQ.Wumbley especulou que poderiam ser atributos estendidos e esse acabou sendo o caso!
getfattr
retorna user.com.dropbox.attributes
. Acontece que o diretório de testes era um subdiretório no fundo de um diretório que estava simbolicamente vinculado à minha pasta do Dropbox . Veja a resposta aceita abaixo.
† Isso usa GNU Core Utilities 8.30 em GNU/Linux com kernel 4.19.1 (Manjaro) em ext4 em um SSD NVME.
@WumpusQ.Wumbley apontou a causa em um comentário: atributos estendidos .
Por uma questão de completude, as respostas são apresentadas abaixo.
Atributos estendidos , neste caso aplicados pelo Dropbox (
getfattr
returnuser.com.dropbox.attributes
), usam blocos adicionais para armazenamento. Sem esses atributos estendidosls
(e os outros comandos) retorna:Como esperado.
Além disso,
stat
para o único caso interessante deseveral_blocks
devoluções:O que também é o esperado, pois 256 * 512 - 129760 = 1312 < 4096, ou seja, nenhum bloco extra usado.
Os "blocos adicionais" não se devem a alguma inconsistência na configuração. (Hipoteticamente, sempre pode estar errado por algum outro motivo. Como raios cósmicos que corromperam o código do seu kernel :-)).
Digo isso porque não há opção de ajustar manualmente os detalhes do cálculo do uso do disco para esses comandos. Os comandos apenas convertem o uso do disco para unidades diferentes, multiplicando ou dividindo. O uso do disco é obtido chamando a chamada de sistema stat(). O kernel retorna um número de "blocos" sintéticos, que são sempre 512 bytes. Também não há nenhuma opção de kernel que afete como stat() calcula o número de blocos.
Posso dizer que o bloco que contém o inode não deve ser contado no seu sistema de arquivos ext4. Em geral, Giles diz que não conta com nenhum sistema de arquivos que ele conheça. Talvez em parte devido ao ponto que você levanta :-). Os inodes tendem a ser menores do que os blocos de 512 bytes relatados pelo
stat
. ext4 padroniza para inodes de 256 bytes; ext3 padronizado para 128 bytes.Se examinarmos as questões relacionadas (barra lateral direita), notamos um caso em que pode haver bloqueios adicionais. A árvore de extensão (ou blocos indiretos, se as extensões estiverem desabilitadas) é contada no ext4. ( Por que a diferença no tamanho do arquivo e no tamanho do disco é maior que 4 KiB? )
Uma segunda resposta à pergunta vinculada sugere outro caso. Alguns usos de fallocate() podem permitir a criação de arquivos com uma diferença arbitrariamente grande entre seu tamanho e o número de blocos alocados a eles.
Dito isto, suspeito que o acima não seja suficiente para explicar nenhum de seus exemplos.