Compreendendo Inodes e o Sistema de Arquivos no Linux

Armazenamento de Arquivos em Disco

Um arquivo que não está aberto reside no disco rígido. No Linux, um arquivo é composto por dois componentes separados: seu conteúdo e seus atributos. O conteúdo é armazenado em blocos de dados, enquanto os atributos (tamanho, permissões, timestamps, etc.) são mantidos em uma estrutura de 128 bytes chamada inode. Esta separação é fundamental no design do sistema de arquivos.

Para entender como os dados são gravados, precisamos examinar a física do disco. O disco é composto por pratos giratórios, cada um com uma superfície magnética. Cada superfície tem sua própria cabeça de leitura/gravação. Os dados são organizados em círculos concêntricos chamados trilhas, que são divididos em segmentos chamados setores – a unidade mínima de armazenamento, geralmente com 512 bytes ou 4KB.

Para acessar um setor específico, o sistema utiliza a endereçamento CHS (Cilindro, Cabeça, Setor). O cilindro é a trilha em todas as superfícies que está alinhada verticalmente. Mover as cabeças para a trilha correta (seleção de cilindro) e esperar o setor desejado passar sob a cabeça (seleção de setor) são as operações de busca físicas. A eficiência depende de minimizar esses movimentos.

Para simplificar, o sistema operacional abstrai essa complexidade física em um endereço linear contínuo chamado LBA (Logical Block Address). Um mapeamento converte esse LBA em coordenadas CHS reais.

A Estrutura Lógica do Sistema de Arquivos

Um disco grande é dividido em partições. Cada partição pode ser formatada com um sistema de arquivos como o ext4. A formatação inicializa estruturas de metadados cruciais:

  1. Blocos de Dados (Data Blocks): A área onde o conteúdo dos arquivos é efetivamente armazenado. Cada bloco pode ter 1KB, 2KB ou 4KB.
  2. Tabela de Inodes (inode Table): Um array contíguo de inodes. Cada inode contém todos os atributos de um arquivo, exceto seu nome, e mantém ponteiros para os blocos de dados que compõem seu conteúdo.
  3. Bitmap de Blocos (Block Bitmap): Um mapa de bits onde cada bit corresponde a um bloco de dados. Um bit '1' indica que o bloco está em uso; '0' indica livre.
  4. Bitmap de Inodes (inode Bitmap): Um mapa de bits similar para os inodes, indicando quais estão alocados.

A tabela de inodes é organizada em grupos de blocos. Cada grupo contém cópias redundantes de estruturas críticas para resiliência:

  • Super Bloco: Contém informações globais sobre todo o sistema de arquivos (tamanho, contagem de inodes e blocos, etc.). Existem cópias espalhadas por diferentes grupos.
  • Tabela de Descritores de Grupo (GDT): Descreve a localização e o uso das estruturas dentro de cada grupo de blocos.

A operação de formatação (com mkfs) inicializa essas estruturas, definindo os bitmaps e preparando a partição para uso.

Sistema de Indexação de Inodes

Um inode reserva espaço para armazenar ponteiros para blocos de dados. Para suportar aruqivos grandes, utiliza-se um sistema de indexação hierárquico:

Estrutura simplificada de um inode:
struct inode {
    // ... atributos (modo, tamanho, timestamps, etc.)
    uint32_t i_block[15]; // Array de ponteiros
};
  • Índices Diretos (i_block[0] a i_block[11]): Cada um aponta diretamente para um bloco de dados. Ideal para arquivos pequenos (até 48KB com blocos de 4KB).
  • Índice Indireto Simples (i_block[12]): Aponta para um bloco que contém uma lista de ponteiros para blocos de dados. Um bloco de 4KB pode armazenar 1024 ponteiros (4 bytes cada), permitindo arquivos de até ~4MB.
  • Índice Indireto Duplo (i_block[13]): Aponta para um bloco de índices, onde cada entrada aponta para um bloco de índices indiretos simples. Capacidade: ~4GB.
  • Índice Indireto Triplo (i_block[14]): Mais um nível, suportando arquivos de até ~4TB.

Quando um arquivo é deletado, seu conteúdo não é necessariamente apagado. O sistema operacional apenas marca seus blocos de dados como livres no Block Bitmap e libera seu inode no inode Bitmap. A sobrescrita física ocorrerá quando novos dados forem gravados nesses blocos.

Resolução de Nomes e Navegação

Os usuários interagem com nomes de arquivos, não com números de inode. Isso é possível porque diretórios também são arquivos. O conteúdo de um diretório é uma tabela que mapeia nomes de arquivos para seus respectivos números de inode.

Ao executar ls -l em um diretório, o processo do shell:

  1. Encontra o inode do diretório atual (geralmente via caminho absoluto a partir do diretório raiz /).
  2. Lê o bloco de dados do diretório (se tiver permissão de leitura - 'r').
  3. Para cada entrada (nome, inode), lê os atributos do inode correspondente para exibir as informações detalhadas.

As permissões em um diretório controlam ações específicas:

  • r (leitura): Permite listar os nomes dos arquivos dentro dele (conteúdo do diretório).
  • w (escrita): Permite criar, deletar ou renomear arquivos dentro dele (modificar a tabela de mapeamento).
  • x (execução/busca): Permite atravessar o diretório como parte de um caminho (ex.: cd, cat /dir/arquivo). Sem permissão 'x', o sistema não pode acessar o inode do diretório para encontrar seus blocos de dados.

Para encontrar o inode de um diretório, o sistema inicia no inode raiz (sempre inode 2 em sistemas ext) e segue o caminho, buscando o inode de cada componente do caminho no diretório pai.

Links Físicos e Simbólicos

O sistema de arquivos oferece dois mecanismos para criar diferentes caminhos de acesso a um mesmo conteúdo: links físicos (hard links) e links simbólicos (soft links).

Link Físico (Hard Link)

ln arquivo_original link_fisico

Um hard link cria uma nova entrada em um diretório que aponta para o mesmo inode do arquivo original. Portanto, não é um arquivo independente.

  • Compartilham o mesmo número de inode e, consequentemente, os mesmos dados e atributos.
  • A alteração do conteúdo através de um link é refletida em todos os outros, pois apontam para os mesmos blocos de dados.
  • O inode mantém uma contagem de referências (i_nlink). O arquivo só é verdadeiramente deletado quando essa contagem chega a zero.
  • Não podem ser criados entre partições (os inodes são únicos apenas dentro de uma partição) e, por padrão, não podem apontar para diretórios para evitar loops no sistema.

Link Simbólico (Symbolic Link)

ln -s arquivo_original link_simbolico

Um symlink é um arquivo independente com seu próprio inode. Seu bloco de dados contém apenas o caminho do arquivo para o qual ele aponta.

  • É um atalho de caminho. Se o arquivo original for movido ou deletado, o symlink se torna quebrado (dangling).
  • Útil para criar atalhos convenientes a arquivos em diretórios profundos ou para manter múltiplas versões de um programa acessíveis.

Contagem de Links e Diretórios

Observando um diretório com ls -ld, seu número de links (nlink) sempre é pelo menos 2. Isso ocorre porque um diretório sempre tem duas entradas especiais:

  • . (ponto): Um hard link para o próprio diretório.
  • .. (ponto-ponto): Um hard link para o diretório pai.

Portanto, a contagem de links de um diretório (nlink) é igual a 2 mais o número de subdiretórios que ele contém. Isso acontece porque cada subdiretório tem uma entrada .. que aponta de volta para o diretório pai, incrementando sua contagem de referências.

Essas entradas . e .. são gerenciadas internamente pelo sistema operacional. Um usuário comum (mesmo root) não pode criar hard links manuais para diretórios, pois isso poderia introduzir ciclos na árvore de diretórios, tornando a resolução de caminhos infinita e quebrando ferramentas como find.

Tags: ext4 inode data-block filesystem hard-link

Publicado em 7-4 23:22