Чому це '.' міцне посилання в Unix?


51

Я бачив багато пояснень того, чому кількість посилань для порожнього каталогу в ОС на базі Unix дорівнює 2, а не 1. Всі вони кажуть, що це через "." каталог, який має кожен каталог, що вказує на себе. Я розумію, навіщо мати якесь поняття "." корисний для визначення відносних шляхів, але що отримується, реалізуючи його на рівні файлової системи? Чому б просто не мати оболонок або системні виклики, які проходять шляхи, знати, як їх інтерпретувати?

Це ".." справжнє посилання має для мене набагато більше сенсу - файловій системі потрібно зберігати вказівник назад до батьківського каталогу, щоб перейти до нього. Але я не бачу, чому "." бути реальною ланкою необхідно. Також здається, що це призводить до некрасивого особливого випадку в реалізації - ви можете подумати, що ви можете звільнити лише простір, який використовують inode, які мають кількість посилань менше 1, але якщо вони мають каталоги, вам потрібно перевірити наявність кількість посилань менше 2. Чому невідповідність?


1
Після того, як у вас є ..жорсткі посилання, у вашому програмному забезпеченні для переходу по дереву вже має бути виняток "не слідкувати за циклами на батьківському посиланні каталогів" , тому це також має складність, за винятком .посилання.
dmckee

Відповіді:


37

Дійсно цікаве питання. На перший погляд я бачу такі переваги:

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

Але я не думаю, що це була основна ідея цього дизайнерського рішення.

Коли файл створюється або видаляється з каталогу, також слід оновити часовий штамп модифікації каталогу. Ця часова мітка зберігається в її inode. Номер inode зберігається у відповідному записі каталогу.

Якщо введення крапки не було б, підпрограми повинні були б шукати номер inode при записі цього каталогу в батьківському каталозі, що призведе до повторного пошуку каталогу.

Але, на щастя, в поточному каталозі є крапка. Підпрограма, що додає або видаляє файл у поточному каталозі, просто має перейти назад до першого запису (де зазвичай знаходиться точка-запис) і негайно знайшла номер inode для поточного каталогу.

Є ще третя приємна річ щодо крапки:

Під час fsckперевірки гнилої файлової системи та доводиться мати справу з непоєднаними блоками, які також відсутні у вільному списку, легко перевірити, чи є у блоку даних (коли інтерпретується як список каталогів) крапка запису, яка вказує на inode що в свою чергу вказує на цей блок даних. Якщо так, цей блок даних може розглядатися як втрачений каталог, який потрібно знову підключити.


Дуже корисна відповідь.
Navaneeth KN

6
Коментар щодо процедур, що шукають inode каталогу, неправдивий. Підпрограми ядра не потрібно шукати .у поточному каталозі. Якщо ви не знайдете ядро, де воно насправді працює таким чином (я сумніваюся в цьому ...)
Дітріх Епп

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

10

(Хм: наступне зараз трохи епічне ...)

Конструкція каталогу в файлових системах unix (які, як правило , є педантичними, але не обов'язково приєднуються до ОС Unix), представляє прекрасне розуміння, що фактично зменшує кількість необхідних спеціальних випадків.

«Каталог» - це справді лише файл у файловій системі. Весь власний вміст файлів у файловій системі знаходиться в inodes (з вашого запитання я бачу, що ви вже знаєте про деякі з цих матеріалів). На дисках немає структури - вони просто велика купа пронумерованих крапок байтів, розкиданих, як арахісове масло, на диску. Це не корисно, і справді відштовхує тих, хто має шматок охайності.

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

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

Жорстка зв'язок нічого більше і не менш , ніж запис в карті директорії файлу. Ви можете мати два (або більше) записів на такій карті, які обидва відображають один і той же номер інода: такий inode має два (або більше) жорстких посилань. Це також пояснює, чому кожен файл має принаймні одне "жорстке посилання". У inode є довідковий підрахунок, який записує, скільки разів цей inode згадується у файлі каталогу десь у файловій системі (це число, яке ви бачите, коли це робите ls -l).

Гаразд: ми зараз переходимо до справи.

Файл каталогів - це карта рядків ("імен файлів") до чисел (номерів inode). Ці номери inode є числами вкладень файлів, які знаходяться у цьому каталозі. Файли, що знаходяться в "каталозі", можуть містити інші файли каталогів, тому їхні числа індексів будуть серед перелічених у каталозі. Таким чином, якщо у вас є файл /tmp/foo/bar, то файл каталогу fooвключає в себе запис для bar, відображення цього рядка в inode для цього файлу. У файлі каталогів також є запис для файлу /tmpкаталогу, fooякий знаходиться в каталозі "in" /tmp.

Коли ви створюєте каталог з mkdir (2), ця функція

  1. створює файл каталогу (з деяким номером inode) з правильною внутрішньою структурою,
  2. додає запис до батьківського каталогу, відображаючи ім'я нового каталогу в цьому новому inode (який містить одне з посилань),
  3. додає запис у новий каталог, відображаючи рядок '.' до того ж inode (це пояснює інше посилання) та
  4. додає ще один запис у новий каталог, відображаючи рядок ".." до inode файлу каталогу, який він змінив на кроці (2) (це враховує більшу кількість жорстких посилань, які ви побачите у файлах каталогів, які містять підкаталоги ).

Кінцевим результатом є те, що (майже) єдиними особливими випадками є:

  • Функція open (2) намагається ускладнити стрілянину в ногу, запобігаючи відкриванню файлів каталогів для запису.
  • Функція mkdir (2) робить речі приємними та легкими, додавши до нового файлу каталогу кілька додаткових записів ('.' Та '..'), щоб зручніше переміщатися по файловій системі. Я підозрюю, що файлова система працюватиме ідеально без "." і "..", але це буде біль для використання.
  • Файл каталогів є одним з небагатьох типів файлів, які позначені як "особливі". Це дійсно те, що говорить про те, що відкриті (2) мають поводитися дещо інакше. Дивіться st_modeу stat (2).

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


1
Ви плутаєте блоки з inode. Як особливий випадок, для коротких файлів вміст файлів може знаходитися всередині inode, але помилково стверджувати, що inode неструктуровані. Вони високоструктуровані, містять майже всі метадані файлу, за винятком назви файлів, за якими файл може бути знайдений. Inode містить покажчики (прямі, непрямі, подвійні непрямі тощо) на блоки на диску, де вміст файлу.
Філ П

1
Ні, я не плутаю блоки з inode. Вклади - це абстракція, що сидить над блоками, і суть цієї публікації полягала в описі взаємозв'язку між файлами та каталогами та їх вмістом: вся структура файлової системи походить з файлів каталогів. Це було досить довго, вже не забиваючись у inode-реалізаціях! (якщо сказати, я можу, можливо, написати перші пару абзаців більш чітко). Також, як бачите, я прямо заявляю, що вся інформація про файл (крім його імені) знаходиться в inode, а не у файлі каталогу.
Норман Грей

@NormanGray: Навіть захищаючись, ти стріляєш собі в ногу. Ви сказали: "Весь фактичний вміст файлів у файловій системі знаходиться в інодах ...." Це неправильно.  Властивості / атрибути файлу (наприклад, власник, дозволи, час модифікації тощо) зберігаються в inode. Зміст звичайного файлу зберігається в блоках даних. Якщо ви не хочете зациклюватися на впровадженні inode, тоді не робіть, але також не робіть оманливих надмірних спрощень.
G-Man каже: "Відновіть Моніку"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.