ext4, por que o arquivo 70k leva 88 blocos

3
[root@xx]# cat -n create_extents.sh 
     1  #!/bin/bash
     2
     3  if [ $# -ne 2 ]
     4  then
     5          echo "$0 [filename] [size in kb]"
     6          exit 1
     7  fi
     8
     9  filename=$1
    10  size=$2
    11  i=0
    12
    13  while [ $i -lt $size ]
    14  do
    15          i='expr $i + 7'
    16          echo -n "$i" | dd of=$1 bs=1024 seek=$i
    17  done

então eu fiz

sudo ./create_extents.sh  /device3/test70 70

Então, eu uso o comando debugfs "stat" para verificar,

Inode: 13 Tipo: regular Modo: 0644 Sinalizadores: 0x80000

Generation: 2638566511    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 71682
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 88
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x53292990:042e685c -- Wed Mar 19 01:22:24 2014
 atime: 0x5329298f:edd4dc60 -- Wed Mar 19 01:22:23 2014
 mtime: 0x53292990:042e685c -- Wed Mar 19 01:22:24 2014
crtime: 0x5329298f:edd4dc60 -- Wed Mar 19 01:22:23 2014
Size of extra inode fields: 28
EXTENTS:
(ETB0):33803, (1):33825, (3):33827, (5):33829, (7-8):33831-33832, (10):33834, (12):33836, (14-15):33838-33839, (17):33841
(END)

Por que são necessários tantos blocos? e o lugar é tão disperso ..? Meu tamanho de bloco é 4k. Eu sei que o ext4 tenta manter a localidade para um arquivo.

obrigado

    
por BufBills 19.03.2014 / 06:37

1 resposta

3

O valor "Contagem de bloqueios" é o campo i_blocks do struct ext2_inode . Este é o valor que é retornado para o stat syscall no campo st_blocks . Por razões históricas, a unidade desse campo é de 512 bytes - esse era o tamanho do bloco do sistema de arquivos nos primeiros sistemas de arquivos Unix, mas agora é apenas uma unidade arbitrária. Você pode ver o valor incrementado e decremented dependendo apenas do tamanho do arquivo mais abaixo em fs/stat.c .

Você pode ver esse mesmo valor executando stat /device3/test70 ("Blocos: 88").

O arquivo na verdade contém 18 blocos, o que é o esperado com um tamanho de bloco de 4kB (o arquivo tem 71682 bytes de comprimento, não escasso, e 17 × 4096 \ < 71682 ≤ 18 × 4096).

Provavelmente, é surpreendente que o número de blocos de 512 bytes seja 88 e não 141 (porque 140 × 512 \ < 71682 ≤ 141 × 512) ou 144 (que é 18 × 4096/512). O motivo tem a ver com o cálculo em fs/stat.c que eu vinculei acima. Seu script cria esse arquivo procurando repetidamente após o final e, para o cálculo do campo i_blocks , o arquivo é esparso - há blocos inteiros de 512 bytes que nunca são gravados e, portanto, não são contados em i_blocks . (No entanto, não há nenhum bloco de armazenamento totalmente procurado, portanto, o arquivo não é realmente esparso.)

Se você copiar o arquivo, verá que a cópia tem 144 blocos como esperado (observe que você precisa executar cp --sparse=never , porque o GNU cp tenta ser inteligente e procura quando vê expansões de zeros ).

Quanto ao número de extensões, a criação de um arquivo da maneira que você faz por buscas sucessivas após o final não é uma situação para a qual os sistemas de arquivos tendem a ser otimizados. Eu acho que as heurísticas no driver do sistema de arquivos primeiro decidem que você está criando um arquivo pequeno, então comece reservando espaço um bloco de cada vez; mais tarde, quando o arquivo cresce, as heurísticas começam a reservar vários blocos por vez. Se você criar um arquivo maior, deverá ver o aumento de grandes extensões. Mas eu não sei ext4 em detalhes suficientes para ter certeza.

    
por 20.03.2014 / 02:40