Sobre o tamanho do arquivo e uso de disco no ext3

3

Eu tenho várias cópias de um arquivo. Os arquivos levam 2390170 KiB cada, de acordo com ls -lk e du --apparent-size -k .

O problema é que du -k informa tamanhos diferentes para cada cópia: 2389824, 2392512, 2392512 e 2390336.

Eu esperava que o uso do disco fosse o 2390172KiB (o tamanho do número mínimo de blocos (597543) onde o arquivo se encaixa.

Então, por que cada arquivo tem um uso de disco diferente?

Eu também vi que uma das cópias usa 2389824KiB, mas o tamanho do arquivo é 346KiB maior: 2390170. Como isso faz sentido?

PD: Todos os arquivos estão no mesmo sistema de arquivos ext3. O tamanho do bloco do sistema de arquivos é 4096. Todos os arquivos têm o mesmo hash.

Atualização: dos comentários:

although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like

arquivos esparsos podem ser o motivo, porque o uso do disco é menor. Mas não consigo ver como a fragmentação interna ou os blocos indiretos podem reduzir o uso do disco em relação ao arquivo original. Como o arquivo é o mesmo, o uso do disco da fragmentação interna e dos blocos indiretos deve ser constante.

Eu observei que cp --sparse=always pode fazer um arquivo esparso de um não-esparso. cp --sparse=always resulta em um arquivo que usa 2390336KiB cp --sparse=never resulta em um arquivo que usa 2392512KiB

Então, eu suponho que o uso de 2389824KiB de uma das cópias é causado por uma implementação diferente do algoritmo esparso ...

O arquivo original foi copiado de uma máquina windows através de sftp ou samba, e eu acho que o arquivo 2389824KiB é uma cópia dele, mas não me lembro como eu fiz isso (eu acho que com cp, mas eu não tenho certeza).

    
por naw 04.12.2010 / 18:20

2 respostas

3

De man du :

--apparent-size
print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like

De info du :

'--apparent-size'
Print apparent sizes, rather than disk usage. The apparent size of a file is the number of bytes reported by wc -c on regular files, or more generally, ls -l --block-size=1 or stat --format=%s. For example, a file containing the word 'zoo' with no newline would, of course, have an apparent size of 3. Such a small file may require anywhere from 0 to 16 KiB or more of disk space, depending on the type and configuration of the file system on which the file resides. However, a sparse file created with this command:

      dd bs=1 seek=2GiB if=/dev/null of=big

has an apparent size of 2 GiB, yet on most modern systems, it actually uses almost no disk space.

[ênfase minha]

    
por 05.12.2010 / 02:55
1

Há duas coisas acontecendo aqui - os arquivos maiores do que o esperado são devidos a metadados dos armazenamentos de sistema de arquivos que estão sendo contados em relação ao tamanho do arquivo. Os arquivos menores do que o esperado são devidos a um recurso do UNIX chamado "arquivos esparsos".

Arquivos maiores

Para ext2 / ext3, o uso em disco do arquivo inclui o espaço usado pelas estruturas do sistema de arquivos que controlam onde os blocos de dados estão no disco. Dê uma olhada em a estrutura de inode Ext2 - um inode é a estrutura de dados que controla as permissões de um arquivo, tamanho, etc, bem como onde seus blocos de dados estão no disco. O próprio inode não é contado para o uso (é pré-alocado na criação do sistema de arquivos), mas os blocos indiretos são.

Cálculo

Assim, o seu arquivo com tamanho 2390172kB recebe 597543 blocos de dados, como você disse. Os locais de 12 desses blocos são armazenados no próprio inode, então eles são gratuitos. O 13º local armazenado no inode é para um bloco indireto - um bloco recém-alocado que armazena os locais de 1024 blocos de dados. Então, isso adiciona 1 bloco ao seu tamanho de arquivo e nos deixa com 596507 blocos.

O 14º ponteiro de localização no inode é para um bloco duplamente indireto - um bloco alocado que contém espaço para os locais de 1024 blocos indiretos. 596507/1024 ~ = 582.52, então precisaremos de 583 blocos indiretos para conter o resto dos blocos de dados, além do bloco duplamente indireto.

Então:

    1 (indirect from inode)
+   1 (doubly-indirect from inode)
+ 583 (indirect from doubly-indirect)
-----
= 585
= 598128 - 597543

E isso representa o tamanho 2392512 (= 598128 * 4).

Arquivos menores

Eu suspeito que os arquivos menores (2389824kB) sejam arquivos esparsos, o que significa que alguns dos blocos nunca foram gravados e, portanto, não foram alocados - blocos não alocados são definidos como preenchidos com zeros. Veja a resposta de Dennis Williamson para referências. Arquivos esparsos podem ocorrer se a gravação do programa mover o ponteiro do arquivo e gravar em posições diferentes no arquivo, em vez de gravar o arquivo do início ao fim. Para um exemplo extremo de um arquivo esparso, tente o seguinte:

du if=/dev/zero of=my_sparse_file bs=1000 count=1 seek=1000000

Se você ls do arquivo resultante, o tamanho aparente será 1000001000. No entanto, como apenas 1000 bytes foram gravados, apenas um bloco de dados é usado, portanto, apenas um bloco de dados é alocado. du relatará 12kB usado - um bloco de 4k para os dados, um para o bloco duplamente indireto e um para um único bloco indireto ao qual o bloco duplamente indireto aponta com seu 976º ponteiro. Nenhum dos blocos restantes do arquivo foi alocado, seja dados ou metadados.

Quando o bloco duplamente indireto acabar, o sistema de arquivos começa a usar um bloco triplo indireto. Seu arquivo atingirá o tamanho máximo possível do sistema de arquivos ext3 antes de preenchê-lo.

    
por 05.12.2010 / 08:46