Arquivos esparsos / furos de arquivo e tamanho de bloco inesperado

4

Para meu próprio aprendizado, tenho brincado com a criação de arquivos com falhas de arquivos. Eu criei um util que simplesmente lê de stdin e grava em um arquivo, mas antes de gravar no arquivo, ele usa lseek para ir além do final do arquivo por um número de bytes.

fh -b 20000 testfile
hello
there

Após iniciar este processo, a entrada pode ser digitada ("hello") e gravada no testfile, mas antes disso, ela procura o final do arquivo em 20000 bytes. Então, antes de escrever, ele busca novamente no final do arquivo outros 20000 bytes antes de "lá" ser escrito.

O que não estou claro é o número de blocos alocados para o arquivo recém-criado. Se eu fizer

ls -ls testfile

mostra 8 blocos alocados e o tamanho do arquivo é 40013 (o que é esperado).

Um novo arquivo com 13 bytes (mas sem furos de arquivo) aloca 4 blocos de acordo com ls -ls . Descobri que isso realmente significa 1 bloco (2048 bytes para um bloco), mas os blocos relatados são divisíveis por 512 bytes. Então, supondo que isso seja verdade, a matemática não calcula o arquivo com falhas de arquivos. Por que 8 blocos são alocados, não deveria ser apenas 4, já que o tamanho físico do arquivo é de apenas 13 bytes (em oposição ao tamanho lógico de 40013)?

Não tenho certeza se estou lendo o tamanho do bloco corretamente e, em segundo lugar, não entendo por que o tamanho do bloco é 8, considerando que um arquivo de tamanho semelhante sem furos de arquivo tem apenas 4.

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

    
por stantona 09.01.2012 / 02:48

1 resposta

5

O Ext4 pode usar 1kB, 2kB ou 4kB como o tamanho do bloco; Tanto quanto eu sei o padrão no Ubuntu é de 4kB. Note que aqui, um bloco é o tamanho de um pedaço de arquivo, que é constante para um determinado sistema de arquivos. O arquivo que você descreve tem dois blocos que não são zeros: o que contém hello (cercado por um monte de zeros - 3616 antes e 474 depois) eo contendo here (precedido por um monte de zeros e contendo apenas 3148 bytes, após o qual o final do arquivo é atingido). O total é de dois blocos de 4kB.

Na saída ls , os blocos são uma unidade arbitrária escolhida pelo comando ls e cujo padrão é 1kB. Existem 2 blocos de 4kB alocados para conter os dados do arquivo, portanto, o tamanho alocado para o arquivo é 8kB.

Sua confusão pode ser devida a duas coisas. Primeiro, a figura de 2048 bytes para um bloco é possível, mas não é o valor padrão no Ubuntu (ou distribuições mais modernas), e aparentemente não é o valor em seu sistema. Você pode verificar o tamanho do bloco executando tune2fs -l /dev/sdz42 (use o caminho real para o seu dispositivo de sistema de arquivos).

Em segundo lugar, os arquivos esparsos consistem em não armazenar blocos feitos inteiramente de zeros. Se um bloco (que é necessariamente alinhado em um limite de tamanho de bloco, pelo menos para a maioria dos sistemas de arquivos incluindo ext4) contém zeros e outras coisas, então o bloco completo é armazenado no disco. Assim, nesse arquivo de 40012 bytes (como você chegou a 40013, a propósito), existem 4 blocos não armazenados todos os zero, então um bloco armazenado contendo hello rodeado por zeros, então mais 4 todos os zeros blocos não armazenados e um bloco parcial final contendo zeros e there .

Observe que seu utilitário pode ser escrito em termos de comandos padrão do shell:

n=20000
while IFS= read -r line; do
  dd bs=1 seek=$n </dev/null
  echo "$line"
done >testfile
    
por 09.01.2012 / 03:59