У Unix, як правило, файл - це деякий запис у таблиці файлів. Існують різні типи файлів: звичайні файли, пристрої, посилання символів, двері, труби, розетки, каталоги ...
Число inode (яке ви можете побачити у висновку ls -i
) - це індекс у цій таблиці.
Тепер ви не маєте доступу до файлів по inode, але по шляху . Шлях являє собою ланцюжок з каталогу записів. Ви помітите, що ми тут не говоримо про папку, а про каталог . Тому що це те, що це каталог (подумайте про телефонний каталог).
Каталог - це особливий вид файлу, який дає імена ряду входів. Запис у каталозі - це відображення від імені до inode.
Даний файл (inode) може мати більше одного імені в одному каталозі (так само, як може бути більше одного імені за номером телефону), а також може мати імена (записи) у більш ніж одному каталозі. Вони називаються посиланнями, також відомими як жорсткі посилання для розрізнення з м'якими посиланнями (особливий тип файлу, який є вказівником на шлях).
Файл (inode) відстежує кількість посилань (записів у будь-якій папці), які він має, так що коли число досягає 0 (при від'єднанні його від останнього каталогу, на яке воно посилалося), воно розміщується.
Це те число (кількість посилань), яке відображається у ls -l
висновку.
Коли файл без каталогу створюється вперше (із системними викликами open
або creat
(або bind
або mknod
для деяких типів файлів)), це робиться шляхом надання шляху до нового файлу (наприклад "/a/b"
). Потім відбувається новий файл і виділяється inode, і додається новий запис до каталогу, пов’язаного з "a"
ім'ям у "/"
кореневому каталозі. Це початкове посилання, тому кількість посилань - одна.
Більше посилань можна додати пізніше за допомогою link()
системного виклику ( ln
команда). І посилання можна видалити за допомогою unlink()
системного виклику ( rm
команда).
Ви помітите, що файли типу каталогу зазвичай мають кількість посилань, більших або рівних 2.
Тепер, коли ви створюєте каталог, ви викликаєте mkdir()
системний виклик. Щось подібне mkdir("/a/b")
. Потім це виділити новий файл каталогу каталогу. У цьому новому каталозі він автоматично створює два записи:
"."
( крапка для каталогу ). Яка посилання на себе. Тож кількість посилань зараз дорівнює 1.
".."
(Для каталогу «s каталогу ). Яке посилання на "/a"
. Тож кількість посилань "/a"
збільшується на одиницю
Тоді цей новий каталог пов'язується "/a"
( "/a"
для нього додається запис ), тому кількість його посилань зараз 2. Якщо "/a/b/c"
каталог створений через ".."
запис "/a/b/c"
, кількість посилань "/a/b"
стане 3.
Більшість Unices обмежують створення подальших посилань на каталог, оскільки вони можуть викликати проблемні петлі. Коли вони дозволяють мати link()
каталог у каталозі, це може робити лише суперпользователь.
Деякі файлові системи на зразок btrfs
відходять від традиційної структури каталогів. Ви помітите, що кількість посилань на каталоги у btrfs
файлових системах завжди одна, навіть якщо ці каталоги містять "."
запис із тим самим номером inode, що і вони в них.
Факт, що кількість посилань традиційно становить 2 плюс кількість підкаталів, має своє використання. Наприклад, у:
find . -name '*.c' -print
Якщо .
не містить підкаталогів, але містить мільйони файлів. Перевіривши кількість посилань .
, find
можна знати, що немає підкаталогу. Тому все, find
що потрібно зробити, - це прочитати вміст каталогу та повідомити про записи, які закінчуються .c
(наприклад, grep '\.c$'
у декількох мегабайтних файлах, нічого не важливого). В іншому випадку find
доведеться перевірити тип кожного окремого файлу, щоб побачити, чи є каталоги, в які слід спуститися туди (в результаті стільки lstat()
системних дзвінків). Звичайно, така оптимізація не працює btrfs
(хоча в сучасних версіях Linux тип файлів також зберігається у записі каталогів для деяких файлових систем (у тому числі btrfs
) і повертається getdents(2)
системним викликом, який використовується для отримання списку записів у довіднику, такlstat
все ще не потрібно).