Anatomia do Sistema de Arquivos do Linux

Uma Revisão Baseada na Estrutura em Camadas

Quando o Linux® foi inserido nos sistemas de arquivos, ele era o canivete suíço dos sistemas operacionais. O Linux oferece suporte a um grande número de sistemas de arquivos, do registro de mudança ao armazenamento em cluster para criptografia. Ele é uma plataforma maravilhosa para uso de sistemas dos arquivos mais padrão aos mais exóticos, bem como para o desenvolvimento de sistemas de arquivos. Este artigo explora o Sistema de Arquivo Virtual (VFS)—às vezes chamado de comutador de sistema de arquivo virtual—no kernel Linux e revisa algumas das principais estruturas que ligam os sistemas de arquivos.

M. Tim Jones, Consultant Engineer, Emulex Corp.

M. Tim JonesM. Tim Jones é um arquiteto de firmwares embarcados e autor de Inteligência Artificial: Sistemas de Abordagem, GNU/Linux, Programação de Aplicativos AI (atualmente em sua segunda edição), Programação de Aplicativos AI (em sua segunda edição) e BSD Sockets Programming from a Multilanguage Perspective. Sua formação em engenharia vai desde o desenvolvimento de kernels para nave espacial geossincrônica até a arquitetura de sistema embarcado e o desenvolvimento de protocolos de interligação de redes. Tim é um Engenheiro Consultor para a Emulex Corp. em Longmont, Colorado.


nível de autor Contribuidor do
        developerWorks

30/Out/2007

Arquitetura Básica do Sistema de Arquivos

A arquitetura do sistema de arquivos Linux é um exemplo interessante de complexidade de abstração. Usando um conjunto comum de funções da API, uma grande variedade de sistema de arquivos pode ter suporte em uma grande variedade de dispositivos de armazenamento. Veja, por exemplo, a chamada de função read, que permite que um determinado número de bytes seja lido de um determinado descritor de arquivos. A função read não conhece os tipos de sistemas de arquivos, como ext3 ou NFS. Ela também não conhece uma mídia de armazenamento específica na qual o sistema de arquivos é montado, como disco AT Attachment Packet Interface (ATAPI), disco Serial-Attached SCSI (SAS) ou disco Serial Advanced Technology Attachment (SATA). Ainda assim, quando a função read é chamada para um arquivo aberto, os dados são retornados conforme esperado. Este artigo explora como isso ocorre e investiga as principais estruturas da camada de sistema de arquivos Linux.


O que É um Sistema de Arquivos?

Começarei com uma resposta à pergunta mais básica, a definição de um sistema de arquivos. Um sistema de arquivos é uma organização de dados e metadados em um dispositivo de armazenamento. Com uma vaga definição como esta, você sabe que o código necessário para oferecer suporte a isso será interessante. Como mencionei, há muitos tipos de sistemas de arquivos e mídias. Com toda essa variedade, é possível esperar que a interface do sistema de arquivos Linux seja implementada como uma arquitetura em camadas, separando a camada da interface com o usuário da implementação do sistema de arquivos dos drivers que manipulam os dispositivos de armazenamento.

Sistemas de Arquivos como Protocolos

Outra forma de pensar em um sistema de arquivos é como um protocolo. Como protocolos de rede (como IP), que fornecem significado aos fluxos de dados que passam pela Internet, os sistemas de arquivos fornecem significado aos dados em uma determinada mídia de armazenamento.

Montagem

Associar um sistema de arquivos a um dispositivo de armazenamento no Linux é um processo chamado montagem. O comando mount é utilizado para anexar um sistema de arquivos à hierarquia do sistema de arquivos atual (raiz). Durante a montagem, você fornece um tipo de sistema de arquivos, um sistema de arquivos e um ponto de montagem.

Para ilustrar os recursos da camada do sistema de arquivos Linux (e o uso da montagem), crie um sistema de arquivos em um arquivo dentro do sistema de arquivos atual. Isso é feito criando primeiramente um arquivo de um determinado tamanho utilizando dd (copie um arquivo utilizando /dev/zero como origem) -- em outras palavras, um arquivo que comece com zeros, como mostrado na Lista 1.

Lista 1. Criando um Arquivo Inicializado
$ dd if=/dev/zero of=file.img bs=1k count=10000
10000+0 records in
10000+0 records out
$

Agora você tem um arquivo chamado file.img que possui 10MB. Use o comando losetup para associar um dispositivo de loop ao arquivo (fazendo com que ele se pareça com um dispositivo em bloco em vez de apenas um arquivo comum dentro do sistema de arquivos):

$ losetup /dev/loop0 file.img
$

Agora, com o arquivo aparecendo como um dispositivo em bloco (representado por /dev/loop0), crie um sistema de arquivos no dispositivo com mke2fs. Esse comando cria um novo segundo sistema de arquivos ext2 de tamanho definido, como mostrado na Lista 2.

Lista 2. Criando um Sistema de Arquivos ext2 com o Dispositivo de Loop
$ mke2fs -c /dev/loop0 10000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 1250, rsv_gdb = 39
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2512 inodes, 10000 blocks
500 blocks (5.00%) reserved for the super user
...
$

O arquivo file.img, representado pelo dispositivo de loop (/dev/loop0), agora é montado para o ponto de montagem /mnt/point1 usando o comando mount. Observe a especificação do sistema de arquivos como ext2. Quando montado, é possível tratar esse ponto de montagem como um novo sistema de arquivos usando um comando ls, como mostrado na Lista 3.

Lista 3. Criando um Ponto de Montagem e Montando o Sistema de Arquivos através do Dispositivo de Loop
$ mkdir /mnt/point1
$ mount -t ext2 /dev/loop0 /mnt/point1
$ ls /mnt/point1
lost+found
$

Como mostrado na Lista 4, é possível continuar esse processo criando um novo arquivo dentro do novo sistema de arquivos montado, associando-o ao dispositivo de loop e criando outro sistema de arquivos nele.

Lista 4. Criando um Novo Sistema de arquivos de Loop Dentro de um Sistema de Arquivos de Loop
$ dd if=/dev/zero of=/mnt/point1/file.img bs=1k count=1000
1000+0 records in
1000+0 records out
$ losetup /dev/loop1 /mnt/point1/file.img
$ mke2fs -c /dev/loop1 1000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 125, rsv_gdb = 3
Filesystem label=
...
$ mkdir /mnt/point2
$ mount -t ext2 /dev/loop1 /mnt/point2
$ ls /mnt/point2
lost+found
$ ls /mnt/point1
file.img lost+found
$

Nesta simples demonstração, é fácil ver quão poderoso o sistema de arquivos Linux (e o dispositivo de loop) pode ser. É possível utilizar essa mesma abordagem para criar sistemas de arquivos criptografados com o dispositivo de loop em um arquivo. Isso é útil para proteger seus dados, montando de forma transitória seus arquivos utilizando o dispositivo de loop quando necessário.


Arquitetura do Sistema de Arquivos

Agora que você viu a construção do sistema de arquivos, voltaremos à arquitetura da camada do sistema de arquivos Linux. Este artigo mostra o sistema de arquivos Linux de duas perspectivas. A primeira visualização é da perspectiva da arquitetura de alto nível. A segunda é um pouco mais aprofundada e explora a camada do sistema de arquivos das principais estruturas que a implementam.


Arquitetura de Alto Nível

Enquanto a maioria dos códigos do sistema de arquivos existe no kernel (exceto para sistemas de arquivos do espaço de usuário, que eu mencionarei posteriormente), a arquitetura exibida na Figura 1 mostra os relacionamentos entre os componentes relacionados ao sistema de arquivos principal tanto no espaço de usuário quanto no kernel.

Figura 1. Visualização de Arquitetura dos Componentes do Sistema de Arquivos Linux
Figura 1. Visualização de Arquitetura dos Componentes do Sistema de Arquivos Linux

O espaço de usuário contém os aplicativos (neste exemplo, o usuário do sistema de arquivos) e o GNU C Library (glibc), que fornece a interface do usuário para as chamadas do sistema de arquivos (abrir, ler, gravar e fechar). A interface de chamada do sistema atua como um comutador, canalizando as chamadas do sistema do espaço de usuário para terminais adequados no espaço do kernel.

O VFS é a interface primária para os sistemas de arquivos subjacentes. Este componente exporta um conjunto de interfaces e depois as concentra nos sistemas de arquivos individuais, que podem se comportar muito diferente uns dos outros. Existem dois caches para objetos do sistema de arquivos ((inodes e dentries), que eu definirei brevemente. Cada um fornece um conjunto de objetos do sistema de arquivos usados recentemente.

Cada implementação do sistema de arquivos individual, como ext2, JFS, etc, exporta um conjunto comum de interfaces que é usado (e esperado) pelo VFS. O cache de buffer armazena em buffer os pedidos entre os sistemas de arquivos e os dispositivos de blocos que eles manipulam. Por exemplo, os pedidos de leitura e gravação para drivers de dispositivos subjacentes migram através do cache de buffer. Isso permite que os pedidos sejam armazenados em cache ali para acesso mais rápido (em vez de voltarem ao dispositivo físico). O cache de buffer é gerenciado como um conjunto de listas Least Recently Used (LRU). Observe que é possível utilizar o comando sync para liberar o cache de buffer da mídia de armazenamento (forçar todos os dados não-gravados para fora dos drivers de dispositivo e, subsequentemente, para o dispositivo de armazenamento).

O que É um Dispositivo de Bloco?

Um dispositivo de bloco é aquele no qual os dados que se movem para e dele o fazem em blocos (como setores de disco) e oferece suporte a atributos como armazenamento em buffer e comportamento de acesso aleatório (não é necessário para a leitura sequencial de blocos, mas pode acessar qualquer bloco a qualquer momento). Os dispositivos de bloco incluem unidades de disco rígido, CD-ROMs e discos virtuais. Ele contrasta com os dispositivos de caractere, que diferem por não possuírem uma mídia endereçável fisicamente. Os dispositivos de caractere incluem várias portas e dispositivos de fita, nos quais os dados são colocados em fluxo, caractere por caractere.

Esta é a visão geral do VFS e dos componentes do sistema de arquivos. Agora veremos as principais estruturas que implementam esse subsistema.

Principais Estruturas

O Linux visualiza todos os sistemas de arquivos da perspectiva de um conjunto de objetos comum. Esses objetos são superblock, inode, dentry e file. Na raiz de cada sistema de arquivos está superblock, que descreve e mantém o estado do sistema de arquivos. Cada objeto que é gerenciado dentro de um sistema de arquivos (arquivo ou diretório) é representado no Linux como um inode. O inode contém todos os metadados para gerenciar objetos no sistema de arquivos (inclusive as operações que são possíveis nele). Outro conjunto de estruturas, chamadas dentries, é usado para conversão entre nomes e inodes, para o qual um cache de diretório existe para manter por perto o objeto usado mais recentemente. O dentry também mantém relacionamentos entre diretórios e arquivos para sistemas de arquivos desviados. Por fim, um arquivo VFS representa um arquivo aberto (mantém o estado do arquivo aberto, como o deslocamento de gravação etc).

Camada do Sistema de Arquivo Virtual

O VFS atua como o nível raiz da interface do sistema de arquivos. Ele mantém o rastreio dos sistemas de arquivos suportados atualmente, bem como dos sistemas de arquivos que estão sendo montados no momento.

Os sistemas de arquivos podem ser incluídos ou removidos dinamicamente do Linux usando um conjunto de funções de registro. O kernel mantém uma lista dos sistemas de arquivos suportados atualmente, que pode ser visualizada a partir do espaço de usuário através do sistema de arquivos /proc. Este arquivo virtual também mostra os dispositivos atualmente associados aos sistemas de arquivos. Para incluir um novo sistema de arquivos no Linux, register_filesystem é chamado. Ele obtém um único argumento definindo a referência para uma estrutura do sistema de arquivos (file_system_type), que define o nome do sistema de arquivos, um conjunto de atributos e duas funções superblock. Um sistema de arquivos também pode ter seu registro removido.

Registrar um novo sistema de arquivos coloca o novo sistema de arquivos e suas informações pertinentes em uma lista file_systems (consulte a Figura 2 e linux/include/linux/mount.h). Essa lista define os sistemas de arquivos que podem ter suporte. É possível visualizar essa lista digitando cat /proc/filesystems na linha de comandos.

Figura 2. Sistemas de Arquivos Registrados com o Kernel
Figura 2. Sistemas de Arquivos Registrados com o Kernel

Outra estrutura mantida no VFS é o sistema de arquivos montado (consulte a Figura 3). Ela fornece os sistemas de arquivos que estão montados atualmente (consulte linux/include/linux/fs.h). Ela é vinculada à estrutura superblock , que eu falarei a seguir.

Figura 3. A Lista de Sistemas de Arquivos Montados
Figura 3. A Lista de Sistemas de Arquivos Montados

Superblock

Superblock é uma estrutura que representa um sistema de arquivos. Ela inclui as informações necessárias para gerenciar o sistema de arquivos durante a operação. Inclui o nome do sistema de arquivos (como ext2), o tamanho do sistema de arquivos e seu estado, uma referência para o dispositivo de bloco e informações de metadados (como listas livres, etc). Superblock geralmente é armazenada na mídia de armazenamento, mas pode ser criada em tempo real se não existir nenhuma. É possível encontrar a estrutura superblock (consulte a Figura 4) em ./linux/include/linux/fs.h.

Figura 4. A Estrutura Superblock e Operações Inode
Figura 4. A Estrutura Superblock e Operações Inode

Um elemento importante de superblock é uma definição das operações superblock. Essa estrutura define o conjunto de funções para o gerenciamento de inodes dentro do sistema de arquivos. Por exemplo, inodes podem ser alocados com alloc_inode ou excluído com destroy_inode. É possível ler e gravar inodes com read_inode e write_inode ou sincronizar o sistema de arquivos com sync_fs. É possível localizar a estrutura super_operations em ./linux/include/linux/fs.h. Cada sistema de arquivos fornece seus próprios métodos inode, que implementam as operações e fornecem a abstração comum para a camada VFS.

inode e dentry

Inode representa um objeto no sistema de arquivos com um identificador exclusivo. Os sistemas de arquivos específicos fornecem métodos para converter um nome de arquivo em um identificador de inode exclusivo e depois para uma referência de inode. Uma parte da estrutura inode é mostrada na Figura 5, junto com duas estruturas relacionadas. Observe, particularmente, inode_operations e file_operations. Cada uma dessas estruturas refere-se a operações individuais que podem ser executadas no inode. Por exemplo, inode_operations define essas operações que operam diretamente no inode e file_operations refere-se aos métodos relacionados aos arquivos e diretórios (as chamadas do sistema padrão).

Figura 5. A Estrutura inode e suas Operações Associadas
Figura 5. A Estrutura inode e suas Operações Associadas

Os inodes e dentries são mantidos no cache de inode e diretório, respectivamente. Observe que, para cada inode, há no cache inode um dentry no cache de diretório. É possível encontrar as estruturas inode e dentry definidas em ./linux/include/linux/fs.h.

Cache de Buffer

Exceto para implementações do sistema de arquivo individual (que podem ser encontradas em ./linux/fs), a parte inferior da camada do sistema de arquivos é o cache de buffer. Este elemento mantém o rastreio de pedidos de leitura e gravação de implementações do sistema de arquivo individual e dispositivos físicos (através de drivers de dispositivo). Para eficiência, o Linux mantém um cache dos pedidos para evitar ter que voltar para o dispositivo físico em todos os pedidos. Em vez disso, os buffers (páginas) mais recentemente utilizados são armazenados em cache ali e podem ser rapidamente fornecidos novamente aos sistemas de arquivos individuais.


Sistemas de Arquivos Interessantes

Este artigo não explorou os sistemas de arquivos individuais, que estão disponíveis no Linux, mas precisamos falar deles, mesmo que rapidamente. O Linux oferece suporte a diversos sistemas de arquivos, a partir de sistemas de arquivos antigos como MINIX, MS-DOS e ext2. Ele também oferece suporte aos novos sistemas de arquivos com registro de mudança, como ext3, JFS e ReiserFS. Adicionalmente, o Linux oferece suporte a sistemas de arquivos criptográficos, como CFS, e a sistemas de arquivos virtuais, como /proc.

Um último sistema de arquivos valioso é o Filesystem in Userspace, ou FUSE. Ele é um projeto interessante, que permite que você roteie pedidos do sistema de arquivos através do VFS novamente para o espaço do usuário. Assim, se você tem ideia de criar seu próprio sistema de arquivos, esta é uma ótima forma de começar.


Resumo

Embora a implementação do sistema de arquivos seja comum, ela é um bom exemplo de arquitetura escalável e extensível. A arquitetura do sistema de arquivos desenvolveu-se nos últimos anos, mas ainda oferece suporte a muitos tipos diferentes de sistemas de arquivos e de dispositivos de armazenamento de destino. Utilizando uma arquitetura baseada em plug-in com vários níveis de funções indiretas, é interessante observar a evolução do sistema de arquivos Linux no futuro próximo.

Recursos

Aprender

Obter produtos e tecnologias

  • A macro Filesystem in Userspace (FUSE) é um módulo kernel que permite o desenvolvimento dos sistemas de arquivos no espaço do usuário. A implementação do driver do sistema de arquivos roteia pedidos do VFS novamente para o espaço do usuário. É uma ótima forma de testar o desenvolvimento do sistema de arquivos sem recorrer ao desenvolvimento do kernel. Se você está no Python, pode criar um sistema de arquivos com essa linguagem usando também LUFS-Python.
  • Faça Download de versões de avaliação do produto IBM e obtenha ferramentas de desenvolvimento de aplicativos e produtos de middleware do DB2®, Lotus®, Rational®, Tivoli®e WebSphere®.

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux
ArticleID=382587
ArticleTitle=Anatomia do Sistema de Arquivos do Linux
publish-date=10302007