Crescimento monotônico do tamanho do diretório Linux / contagem de blocos

8

No Linux, (talvez em função do tamanho do bloco do sistema de arquivos), quando eu crio um diretório e statele retorna um tamanho de 4096. Eu posso criar arquivos nesse diretório, até certo ponto, sem aumentar o tamanho percebido do diretório (conforme relatado por stat).

Em algum momento, conforme o diretório se enche de muitos arquivos, o tamanho do diretório aumenta (não estou falando do conteúdo do diretório, estou falando dos blocos consumidos para representar o próprio diretório). Se os arquivos forem excluídos, o tamanho do diretório permanecerá o mesmo.

Aqui está um exemplo rápido:

[root@uxlabtest:/]$ mkdir test
[root@uxlabtest:/]$ stat test
  File: `test'
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 1396685     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2011-07-26 14:06:04.000000000 -0400
Modify: 2011-07-26 14:06:04.000000000 -0400
Change: 2011-07-26 14:06:04.000000000 -0400

Em seguida, toque em vários arquivos:

[root@uxlabtest:/]$ for i in `seq 1 10000`; do touch /test/$i; done
[root@uxlabtest:/]$ stat test
  File: `test'
  Size: 155648          Blocks: 312        IO Block: 4096   directory
Device: fd00h/64768d    Inode: 1396685     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2011-07-26 14:06:04.000000000 -0400
Modify: 2011-07-26 14:06:56.000000000 -0400
Change: 2011-07-26 14:06:56.000000000 -0400

Em seguida, exclua os arquivos:

[root@uxlabtest:/]$ rm -rf /test/*
[root@uxlabtest:/]$ stat test
  File: `test'
  Size: 155648          Blocks: 312        IO Block: 4096   directory
Device: fd00h/64768d    Inode: 1396685     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2011-07-26 14:07:11.000000000 -0400
Modify: 2011-07-26 14:07:12.000000000 -0400
Change: 2011-07-26 14:07:12.000000000 -0400

Minhas perguntas são:

  • Por que a contagem de tamanho / bloco de um diretório aumenta monotonicamente?
  • Isso é uma função do sistema de arquivos subjacente ou do VFS Linux?
  • O tamanho do diretório pode ser reduzido sem excluir e recriar o diretório?
  • Pontos de bônus: Aponte-me para o código-fonte do kernel em que esse comportamento é implementado.
loopforever
fonte
Não sei ao certo por que isso é votado para baixo. Essas são perguntas legítimas e claramente expressas, com comandos dados para replicar o cenário. As respostas a essas perguntas satisfariam o conhecimento da comunidade e seria útil ter documentado em algum lugar.
27311 loopforever

Respostas:

9

Aqui estão as respostas verdadeiras para ext2 / ext3 / ext4. Se eles são verdadeiros para outros sistemas de arquivos, depende de sua implementação.

  1. user48838 respondeu a esta corretamente. Mais arquivos consomem mais metadados. Eles são alocados em 4k chunks ou em qualquer outro tamanho definido no momento da criação do sistema de arquivos
  2. Sim, é um recurso / problema do sistema de arquivos real
  3. Em um sistema de arquivos ext3, isso não é possível. Somente recriando o diretório (vazio)
  4. O código fonte está por aqui e nos arquivos relacionados

Mas você tem sorte. Quando você recriar a mesma quantidade de arquivos que você já excluiu, o tamanho do diretório permanecerá o mesmo. Somente quando você adicionar mais arquivos, ele aumentará.

mailq
fonte
1
Uma coisa: "e2fsck -fD" deve compactar todos os diretórios em um sistema de arquivos ext2 / 3. Isso pode fazer o que o OP deseja, embora eu suspeite que seja lento e o sistema de arquivos esteja offline. Isso provavelmente leva mais tempo do que vincular todos os arquivos em um novo diretório e excluir os antigos.
akramer
4

Os incrementos de bloco que você está vendo devem-se à forma como o sistema de arquivos gerencia seu armazenamento de arquivos e informações relacionadas ao gerenciamento de arquivos. Na situação descrita, isso pareceria incrementos de 4K, portanto, cada entrada "nova" / "exclusiva" no sistema de arquivos reservará 4K, independentemente de o tamanho real dos dados preencher o 4K inteiro. Se os dados relacionados ocuparem todo o 4K, outro bloco de 4K será reservado e preenchido conforme necessário para armazenar todo o fluxo / sequência de dados relacionados.

Dependendo das exclusões "rígidas" versus "flexíveis", conforme gerenciadas pelo sistema de arquivos, a exclusão pode não (geralmente não para a funcionalidade "cancelar a exclusão") liberar imediatamente o (s) bloco (s) reservado (s). Alguns sistemas de arquivos podem diferenciar tipos diferentes de "exclusões" e fornecer recursos correspondentes de gerenciamento de blocos de armazenamento.

Como o gerenciamento de armazenamento é abordado e implementado difere nos sistemas de arquivos, portanto, em sistemas operacionais que oferecem suporte a sistemas de arquivos múltiplos / modulares, o sistema operacional normalmente fornece apenas "ganchos" para a integração do sistema de arquivos.

user48838
fonte
1

Adicionando alguns comentários desmedidos à boa resposta de user48838:

Tudo é um arquivo, incluindo diretórios. Para armazenar todas as informações desse arquivo, você precisa de espaço.

Também seria válido mostrar, digamos, '64B usado' para um diretório pequeno e realmente mostrar a quantidade de espaço usado, mas estaríamos usando vários 4K em disco de qualquer maneira, por isso foi uma decisão de design mostrar apenas o quantidade de espaço usado.

Do ponto de vista do design do FS, por que você se incomodaria em calcular o que foi usado? Não é necessário. E então você teria que mover as entradas para evitar deixar buracos ... ick.

Quando exclusões acontecem e o tamanho do diretório diminui para que você possa liberar um bloco, todo o gerenciamento precisa acontecer antes que você possa realmente fazê-lo. Por que se preocupar em salvar alguns KB? As chances são de que você precisará expandi-lo mais tarde.

Deixado como um exercício para o leitor: Pense em por que o diretório / lost + found foi criado vazio, mas ocupa 16K (pelo menos no ext3).

MikeyB
fonte