Почему '.' жесткая ссылка в Unix?


51

Я видел много объяснений, почему количество ссылок для пустого каталога в ОС на Unix равно 2 вместо 1. Все они говорят, что это из-за '.' каталог, который каждый каталог указывает на себя. Я понимаю, почему иметь некоторое понятие «.» полезен для указания относительных путей, но что получается при его реализации на уровне файловой системы? Почему бы просто не иметь оболочек или системных вызовов, которые принимают пути, знают, как их интерпретировать?

То, что '..' - это реальная ссылка, имеет для меня гораздо больше смысла - файловая система должна хранить указатель на родительский каталог, чтобы перейти к нему. Но я не понимаю, почему ». быть реальной связью необходимо. Также кажется, что это приводит к уродливому особому случаю в реализации - вы могли бы подумать, что могли бы освободить только пространство, используемое индексами inode, у которых число ссылок меньше 1, но если они являются каталогами, вам действительно нужно проверить количество ссылок меньше 2. Почему несоответствие?


1
Когда у вас есть ..жесткие ссылки, в вашем программном обеспечении для обхода дерева уже должны быть исключения «не выполнять циклы по ссылке на родительский каталог» , так что это также немного усложняет, кроме .ссылки.
dmckee

Ответы:


37

Действительно интересный вопрос. На первый взгляд я вижу следующие преимущества:

Прежде всего, вы утверждаете, что интерпретация " ." как текущего каталога может быть выполнена с помощью командной консоли или системных вызовов. Но наличие точечной записи в каталоге фактически устраняет эту необходимость и обеспечивает согласованность даже на более низком уровне.

Но я не думаю, что это было основной идеей этого дизайнерского решения.

Когда файл создается или удаляется из каталога, метка времени изменения каталога также должна быть обновлена. Эта временная метка хранится в своем inode. Номер индекса хранится в соответствующей записи каталога.

Если точечной записи там не будет, подпрограммам придется искать номер индекса в записи для этого каталога в родительском каталоге, что вызовет поиск в каталоге снова.

НО, к счастью, в текущей директории есть точка. Подпрограмма, которая добавляет или удаляет файл в текущем каталоге, просто должна вернуться к первой записи (где обычно находится точка), и сразу же нашла номер инода для текущего каталога.

В записи точки есть еще одна приятная вещь:

Когда fsckпроверяется гнилая файловая система и приходится иметь дело с несвязанными блоками, которых также нет в свободном списке, он легко может проверить, есть ли в блоке данных (если интерпретируется как список каталогов) точка, указывающая на индекс который в свою очередь указывает на этот блок данных. Если это так, этот блок данных может рассматриваться как потерянный каталог, который должен быть повторно подключен.


Очень полезный ответ.
Navaneeth KN

6
Комментарий о процедурах поиска по каталогу inode является поддельным. Процедурам ядра не нужно искать .в текущем каталоге. Если вы не можете найти ядро, где оно действительно работает таким образом (я сомневаюсь в этом ...)
Дитрих Эпп

1
Я согласен с @DietrichEpp; для того, чтобы система в первую очередь смотрела на записи каталога , она должна уже знать об иноде - потому что так она добирается до блоков данных, содержащих записи каталога.
Lqueryvg

10

(Хм: следующее теперь немного эпично ...)

Дизайн каталога в файловых системах Unix (которые, педантично, обычно, но не обязательно, привязаны к операционным системам Unix), представляет собой прекрасное понимание, которое фактически сокращает количество необходимых особых случаев.

«Каталог» - это на самом деле просто файл в файловой системе. Весь фактический контент файлов в файловой системе находится в inode (из вашего вопроса, я вижу, что вы уже знаете о некоторых из этих вещей). Иноды на диске не имеют структуры - они представляют собой просто большую группу пронумерованных двоичных объектов, которые как арахисовое масло растекаются по диску. Это бесполезно, и действительно отталкивает любого, у кого есть клочок чистоты.

Только специальный индексный дескриптор номер индексного дескриптора 2 (не равно 0 или 1, по причинам традиции); индекс 2 - это файл каталога: корневой каталог . Когда система монтирует файловую систему, она «знает», что должна прочитать каталог inode 2, чтобы начать работу.

Файл каталога - это просто файл с внутренней структурой, который предназначен для чтения opendir (3) и друзьями. Вы можете увидеть его внутреннюю структуру, документированную в dir (5) (в зависимости от вашей ОС); если вы посмотрите на это, вы увидите, что запись файла каталога почти не содержит информации о файле - это все в inode файла. Особенностью этого файла является то, что функция open (2) выдаст ошибку, если вы попытаетесь открыть файл каталога в режиме, который разрешает запись. Различные другие команды (чтобы выбрать только один пример hexdump) откажутся действовать обычным образом с файлами каталогов, просто потому, что это, вероятно, не то, что вы хотите сделать (но это их особый случай, а не файловая система).

Жесткая связь ничего больше и не меньше , чем запись в карте директории файла. Вы можете иметь две (или более) записи в такой карте, которые обе отображаются на один и тот же номер инода: поэтому этот инод имеет две (или более) жесткие ссылки. Это также объясняет, почему в каждом файле есть хотя бы одна «жесткая ссылка». Инод имеет счетчик ссылок, который записывает, сколько раз этот инод упоминается в файле каталога где-то в файловой системе (это число, которое вы видите, когда делаете это ls -l).

ОК: сейчас мы подошли к делу.

Файл каталога представляет собой карту строк («имен файлов») и чисел (номеров inode). Эти номера инодов - это номера инодов файлов, которые находятся в этом каталоге. Файлы, которые находятся в этом каталоге, могут включать другие файлы каталога, поэтому их номера inode будут среди тех, что перечислены в каталоге. Таким образом, если у вас есть файл /tmp/foo/bar, то файл каталога fooсодержит запись для bar, сопоставляющую эту строку с индексом для этого файла. В файле каталога также есть запись /tmpдля файла каталога, fooкоторый находится в каталоге /tmp.

Когда вы создаете каталог с помощью mkdir (2), эта функция

  1. создает файл каталога (с некоторым номером индекса) с правильной внутренней структурой,
  2. добавляет запись в родительский каталог, сопоставляя имя нового каталога с этим новым индексом (который учитывает одну из ссылок),
  3. добавляет запись в новый каталог, сопоставляя строку '.' на тот же индекс (это относится к другой ссылке), и
  4. добавляет еще одну запись в новый каталог, сопоставляя строку «..» с индексом файла каталога, который был изменен на шаге (2) (это учитывает большее количество жестких ссылок, которые вы увидите в файлах каталога, которые содержат подкаталоги ).

Конечным результатом является то, что (почти) единственными частными случаями являются:

  • Функция open (2) пытается сделать так, чтобы вам было труднее выстрелить себе в ногу, не позволяя открывать файлы каталогов для записи.
  • Функция mkdir (2) упрощает и упрощает задачу, добавляя пару дополнительных записей ('.' И '..') в новый файл каталога, исключительно для удобства перемещения по файловой системе. Я подозреваю, что файловая система будет отлично работать без '.' и «..», но было бы неудобно использовать.
  • Файл каталога является одним из немногих типов файлов, которые помечены как «специальные» - это действительно то, что говорит таким вещам, как open (2), вести себя немного по-другому. Смотрите st_modeв stat (2).

(скопировано из оригинального вопроса stackoverflow, 2011-10-20)


1
Вы путаете блоки с инодами. В особом случае для коротких файлов содержимое файла может находиться внутри inode, но неверно утверждать, что inode неструктурированы. Они хорошо структурированы и содержат почти все метаданные файла, кроме имен файлов, по которым может быть найден файл. Индод содержит указатели (прямые, косвенные, дважды косвенные и т. Д.) На блоки на диске, где находится содержимое файла.
Фил П

1
Нет, я не путаю блоки с инодами. Иноды - это абстракция, расположенная над блоками, и целью этой публикации было описание отношений между файлами и каталогами и их содержимого: вся структура файловой системы происходит из файлов каталогов. Это было достаточно долго, не увязнув в реализации inode! (тем не менее, я мог бы написать первые пару абзацев более четко). Также, как вы видите, я прямо заявляю, что вся информация о файле (кроме его имени) находится в inode, а не в файле каталога.
Норман Грей

@NormanGray: Даже когда вы защищаетесь, вы стреляете себе в ногу. Вы сказали: «Весь фактический контент файлов в файловой системе находится в inode…». Это неправильно.  Свойства / атрибуты файла (например, владелец, права доступа, время модификации и т. Д.) Хранятся в inode. Содержание обычного файла хранятся в блоках данных. Если вы не хотите зацикливаться на реализациях inode, не делайте этого, но, пожалуйста, не делайте вводящих в заблуждение чрезмерных упрощений.
G-Man говорит: «Восстановите Монику»
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.