Como os diretórios são implementados em sistemas de arquivos Unix?

18

Minha pergunta é como os diretórios são implementados? Eu posso acreditar em uma estrutura de dados como uma variável, e. tabela, matriz ou similar. Como o UNIX é Open Source, posso procurar na origem o que o programa faz quando cria um novo diretório. Você pode me dizer onde procurar ou elaborar sobre o assunto? Que um diretório "é" um arquivo que eu poderia entender e é um diretório realmente um arquivo? Não tenho certeza se é verdade que os arquivos estão armazenados "em" arquivos enquanto ainda está no caminho você poderia dizer o arquivo palavra sobre quase nada e não tenho certeza do que absolutamente não é um arquivo desde que você poderia chamar até mesmo uma variável Arquivo. Por exemplo, um link certamente não é um arquivo e um link é como um diretório, mas isso viola que um diretório é um arquivo?

    
por Niklas Rosencrantz 12.08.2011 / 03:34

4 respostas

21

A estrutura interna dos diretórios depende do sistema de arquivos em uso. Se você quiser saber exatamente o que acontece, dê uma olhada nas implementações do sistema de arquivos.

Basicamente, na maioria dos sistemas de arquivos, um diretório é uma matriz associativa entre nomes de arquivos (chaves) e números de inodes (valores) . Algo como isto¹:

1167010 .
1158721 ..
1167626 subdir
 132651 barfile
 132650 bazfile

Esta lista é codificada de alguma forma - mais ou menos - eficiente dentro de uma cadeia de (geralmente) blocos de 4KB. Observe que o conteúdo de arquivos regulares é armazenado de forma semelhante. No caso de diretórios, não faz sentido saber qual tamanho é realmente usado dentro desses blocos. É por isso que os tamanhos dos diretórios relatados por du são múltiplos de 4KB.

Os inodes estão lá para unir os blocos, formando uma única entidade, ou seja, um 'arquivo' no sentido geral. Eles são identificados por um número que é algum tipo de endereço e cada um é normalmente armazenado como um único bloco especial.

O gerenciamento de tudo isso acontece no modo kernel. O software apenas pede a criação de um diretório com uma função chamada int mkdir(const char *pathname, mode_t mode); , levando a uma chamada do sistema, e todo o resto é realizado nos bastidores.

Sobre a estrutura de links:

Um link físico não é um arquivo, é apenas uma nova entrada de diretório (isto é, uma associação nome - número do inode ) referente a uma entidade inode preexistente². Isso significa que o mesmo inode pode ser acessado de diferentes nomes de caminhos. Em particular, uma vez que metadatas (permissões, propriedade, timestamps…) são armazenadas dentro do inode, elas são únicas e independentes do nome de caminho escolhido para acessar o arquivo.

Um link simbólico é um arquivo e é distinto do seu destino. Isso significa que ele tem seu próprio inode. Ele costumava ser tratado como um arquivo normal: o caminho de destino era armazenado em um bloco de dados. Mas agora, por razões de eficiência em sistemas de arquivos ext recentes, caminhos menores que 60 bytes são armazenados dentro do próprio inode (usando os campos que normalmente seriam usados para armazenar os ponteiros em blocos de dados).

-
1. isso foi obtido usando ls -ai1 testdir .
2. cujo tipo deve ser diferente de 'diretório' hoje em dia.

    
por 12.08.2011 / 04:25
12

Para expandir a postagem de Stéphane Gimenez, criar um novo diretório é o processo de criação de um novo inode com o valor st_mode de S_IFDIR (com o modo de permissões), criando duas entradas no primeiro bloco de dados do novo inode com a ligação (2) chamada do sistema: '.' que aponta para este novo inode e '..' que aponta para o diretório pai, criando uma entrada no diretório pai com o inode e o nome do novo diretório - a primeira e a última parte são feitas pela chamada do sistema mknod ( 2). Além disso, somente o root pode usar o mknod (2) atualmente para tarefas como as que estamos falando.

Por exemplo, mkdir("/home/larry.user/xyzzy", 0666) é essencialmente o seguinte (este foi o código C dos dias do SysV [1]):

int mode = 0666;
char newdir[] = "/home/larry.user/xyzzy";
char path1[NAMESZ+4, path2[NAMESZ+4], *p;
mknod(newdir, S_IFDIR|mode);
strcpy(path1, newdir);
strcat(path1, "/."); /* "." link */
link(newdir, path1);
strcat(path1, ".");  /* ".." link */
strcpy(path2, newdir);
if ((p = strrchr(path2, '/') == (char *)0) /* root directory */
    link(".", path1);
else {
    *p = '
int mode = 0666;
char newdir[] = "/home/larry.user/xyzzy";
char path1[NAMESZ+4, path2[NAMESZ+4], *p;
mknod(newdir, S_IFDIR|mode);
strcpy(path1, newdir);
strcat(path1, "/."); /* "." link */
link(newdir, path1);
strcat(path1, ".");  /* ".." link */
strcpy(path2, newdir);
if ((p = strrchr(path2, '/') == (char *)0) /* root directory */
    link(".", path1);
else {
    *p = '%pre%';
    link(path2, path1);
}
'; link(path2, path1); }
  1. Haviland e Salama, "UNIX System Programming", 1987, pp69-71.

Isso era muito propenso a erros (e uma das principais razões para o fsck), então uma chamada de sistema mkdir (2) foi criada para poder fazer isso para você.

Note que amy sistema de arquivos objeto poderia ser criado com mknod (2): arquivo regular, diretório, arquivo de dispositivo, symlink, etc. Então, para responder a uma das perguntas do OP, sim, um diretório é um arquivo, o que significa dizer , "é um objeto, representado por um inode, residente em um sistema de arquivos que se comporta com uma interface de E / S".

    
por 12.08.2011 / 05:15
2

Se você quiser ter mais informações sobre sistemas de arquivos Unix / Linux, recomendo 2 livros Entendendo o Kernel do Linux e O Desenvolvimento do Kernel do Linux . Esses são os melhores livros para entender o kernel do Linux.

Nos sistemas Unix "Common File Model", cada diretório é considerado um arquivo, que contém uma lista de arquivos e diretórios.

No VFS (Virtual File Systems), os diretórios são representados em uma estrutura chamada dentry . O dentry é uma estrutura C com um nome de cadeia ( d_name ), um ponteiro para um inode ( d_inode ) e um ponteiro para o dentry pai ( d_parent ). Um inode é uma estrutura para manipular informações sobre um arquivo no sistema de arquivos. Por exemplo, se você tiver o diretório /tmp/test/foo , o VFS criará um objeto dentry para cada componente no nome do caminho. Portanto, ele criará um objeto dentry para / , um segundo objeto dentry para a entrada test do diretório raiz e um terceiro objeto dentry para a entrada foo do diretório de teste.

    
por 12.08.2011 / 13:41
1

Você pode começar lendo o link . Para obter mais detalhes, obtenha o excelente livro clássico "O Design e a Implementação do Sistema Operacional 4.4 BSD".

    
por 12.08.2011 / 04:33