Por que é '.' um link rígido no Unix?


51

Eu já vi muitas explicações sobre por que o número de links para um diretório vazio nos sistemas operacionais baseados em Unix é 2 em vez de 1. Todos dizem que é por causa do '.' diretório, que todo diretório aponta para si mesmo. Eu entendo por que ter algum conceito de '.' é útil para especificar caminhos relativos, mas o que é ganho ao implementá-lo no nível do sistema de arquivos? Por que não apenas as conchas ou as chamadas do sistema que seguem caminhos sabem como interpretá-las?

Esse '..' é um link real que faz muito mais sentido para mim - o sistema de arquivos precisa armazenar um ponteiro no diretório pai para navegar até ele. Mas não vejo por que '.' ser um link real é necessário. Também parece que isso leva a um caso especial feio na implementação - você pensaria que só poderia liberar o espaço usado por inodes com uma contagem de links menor que 1, mas se forem diretórios, você realmente precisará verificar um link conta menos de 2. Por que a inconsistência?


11
Depois de ter os ..hardlinks, o seu software de caminhada em árvore já precisa ter uma exceção "não segue ciclos no link do diretório pai" , portanto, há pouca complexidade adicional também, exceto o .link.
dmckee

Respostas:


37

Uma pergunta interessante, de fato. À primeira vista, vejo as seguintes vantagens:

Antes de tudo, você declara que a interpretação " ." como o diretório atual pode ser feita pelo Shell ou por chamadas do sistema. Mas ter a entrada de pontos no diretório realmente remove essa necessidade e força a consistência até em um nível mais baixo.

Mas não acho que essa tenha sido a idéia básica por trás dessa decisão de design.

Quando um arquivo está sendo criado ou removido de um diretório, o carimbo de data / hora de modificação do diretório também precisa ser atualizado. Esse registro de data e hora é armazenado em seu inode. O número do inode é armazenado na entrada do diretório correspondente.

Se a entrada do ponto não estivesse lá, as rotinas teriam que procurar o número do inode na entrada desse diretório no diretório pai, o que causaria uma pesquisa no diretório novamente.

Mas, felizmente, existe a entrada de pontos no diretório atual. A rotina que adiciona ou remove um arquivo no diretório atual precisa voltar à primeira entrada (onde a entrada de pontos geralmente reside) e imediatamente encontrou o número do inode para o diretório atual.

Há uma terceira coisa interessante sobre a entrada de pontos:

Quando fsckverifica um sistema de arquivos podre e precisa lidar com blocos não conectados que também não estão na lista gratuita, é fácil verificar se um bloco de dados (quando interpretado como uma lista de diretórios) possui uma entrada de ponto que aponta para um inode que por sua vez aponta para esse bloco de dados. Nesse caso, esse bloco de dados pode ser considerado como um diretório perdido que deve ser reconectado.


Resposta muito útil.
Navaneeth KN

6
O comentário sobre as rotinas que pesquisam o inode do diretório é falso. As rotinas do kernel não precisam procurar .no diretório atual. A menos que você pode encontrar um kernel onde ele realmente funciona desta forma (eu duvido ...)
Dietrich Epp

11
Eu concordo com @DietrichEpp; para o sistema observar as entradas de diretório em primeiro lugar , ele já deve saber sobre o inode - porque é assim que chega aos blocos de dados que contêm as entradas de diretório.
precisa saber é o seguinte

10

(Hmm: o seguinte agora é um pouco épico ...)

O design do diretório em sistemas de arquivos unix (que, para ser pedante, geralmente é, mas não necessariamente, anexado a sistemas operacionais unix) representa uma visão maravilhosa, que na verdade reduz o número de casos especiais necessários.

Um 'diretório' é realmente apenas um arquivo no sistema de arquivos. Todo o conteúdo real dos arquivos no sistema de arquivos está em inodes (da sua pergunta, posso ver que você já está ciente de algumas dessas coisas). Não há estrutura para os inodes no disco - eles são apenas um monte de blobs numerados de bytes, espalhados como manteiga de amendoim sobre o disco. Isso não é útil e, na verdade, é repulsivo para qualquer pessoa com um pingo de arrumação.

O único inode especial é o inode número 2 (não 0 ou 1, por razões de tradição); inode 2 é um arquivo de diretório: o diretório raiz . Quando o sistema monta o sistema de arquivos, ele 'sabe' que precisa ler o inode 2 para começar.

Um arquivo de diretório é apenas um arquivo, com uma estrutura interna que deve ser lida por opendir (3) e amigos. Você pode ver sua estrutura interna documentada na dir (5) (dependendo do seu SO); se você olhar para isso, verá que a entrada do arquivo de diretório quase não contém informações sobre o arquivo - isso é tudo no inode do arquivo. Uma das poucas coisas especiais sobre esse arquivo é que a função open (2) receberá um erro se você tentar abrir um arquivo de diretório com um modo que permita a gravação. Vários outros comandos (para escolher apenas um exemplo hexdump) se recusam a agir da maneira normal com os arquivos de diretório, apenas porque provavelmente não é isso que você deseja fazer (mas esse é o caso especial deles, não o do sistema de arquivos).

Um link físico nada mais é do que uma entrada no mapa de um arquivo de diretório. Você pode ter duas (ou mais) entradas nesse mapa que mapeiam para o mesmo número de inode: esse inode, portanto, possui dois (ou mais) links físicos. Isso também explica por que cada arquivo tem pelo menos um 'link físico'. O inode possui uma contagem de referência, que registra quantas vezes esse inode é mencionado em um arquivo de diretório em algum lugar do sistema de arquivos (este é o número que você vê quando faz isso ls -l).

OK: estamos chegando ao ponto agora.

O arquivo de diretório é um mapa de cadeias ('nomes de arquivos') para números (números de inode). Esses números de inode são os números dos inodes dos arquivos que estão 'nesse diretório'. Os arquivos que estão 'dentro' desse diretório podem incluir outros arquivos de diretório, portanto, seus números de inode estarão entre os listados no diretório. Portanto, se você tiver um arquivo /tmp/foo/bar, o arquivo de diretório fooincluirá uma entrada para bar, mapeando essa sequência para o inode desse arquivo. Há também uma entrada no arquivo de diretório /tmp, para o arquivo de diretório fooque está 'dentro' do diretório /tmp.

Quando você cria um diretório com mkdir (2), essa função

  1. cria um arquivo de diretório (com algum número de inode) com a estrutura interna correta,
  2. adiciona uma entrada ao diretório pai, mapeando o nome do novo diretório para esse novo inode (que é responsável por um dos links),
  3. adiciona uma entrada ao novo diretório, mapeando a sequência '.' para o mesmo inode (isso representa o outro link) e
  4. adiciona outra entrada ao novo diretório, mapeando a string '..' para o inode do arquivo de diretório modificado na etapa (2) (isso explica o maior número de links físicos que você verá nos arquivos de diretório que contêm subdiretórios )

O resultado final é que (quase) os únicos casos especiais são:

  • A função open (2) tenta dificultar o tiro no pé, impedindo a abertura de arquivos de diretório para gravação.
  • A função mkdir (2) facilita e facilita as coisas adicionando algumas entradas extras ('.' E '..') ao novo arquivo de diretório, apenas para facilitar a movimentação pelo sistema de arquivos. Eu suspeito que o sistema de arquivos funcionaria perfeitamente bem sem '.' e '..', mas seria uma dor de se usar.
  • O arquivo de diretório é um dos poucos tipos de arquivos que são sinalizados como 'especiais' - isso é realmente o que diz que coisas como open (2) se comportam de maneira um pouco diferente. Veja st_modeem stat (2).

(copiado da pergunta original stackoverflow, 20/10/2011)


11
Você está confundindo blocos com inodes. Como caso especial, para arquivos curtos, o conteúdo do arquivo pode estar dentro do inode, mas é falso afirmar que os inodes não são estruturados. Eles são altamente estruturados, contendo quase todos os metadados do arquivo, exceto os nomes de arquivos pelos quais o arquivo pode ser encontrado. O inode contém ponteiros (diretos, indiretos, duplamente indiretos, etc.) para os blocos no disco, onde está o conteúdo do arquivo.
Phil P

11
Não, não estou confundindo blocos com inodes. Os inodes são uma abstração situada acima dos blocos, e o objetivo desta postagem era descrever o relacionamento entre os arquivos e diretórios e seu conteúdo: toda a estrutura do sistema de arquivos vem dos arquivos de diretório. Já era longo o suficiente sem ficar atolado nas implementações de inodes! (Dito isto, eu poderia escrever os primeiros parágrafos com mais clareza). Além disso, como você vê, declaro explicitamente que todas as informações sobre o arquivo (exceto seu nome) estão no inode e não no arquivo de diretório.
Norman Gray

@NormanGray: Mesmo quando você se defende, você atira no próprio pé. Você disse: "Todo o conteúdo real dos arquivos no sistema de arquivos está em inodes ..." Isso está errado.  Propriedades / atributos de um arquivo (por exemplo, proprietário, permissões, hora da modificação, etc.) são armazenados no inode. O conteúdo de um arquivo comum é armazenado em blocos de dados. Se você não quiser ficar preso às implementações de inodes, não o faça, mas também não faça simplificações excessivas enganosas.
G-Man diz 'Reinstate Monica'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.