Inode и методы выделения блоков

Где на диске на самом деле лежит файл и как ОС находит все его кусочки.

Inode — структура, которая хранит метаданные файла и указатели на дисковые блоки с его данными; именно inode, а не имя, по-настоящему идентифицирует файл.

Inode: «паспорт» файла

В Unix-подобных системах у каждого файла есть inode (индексный узел). В нём лежит всё о файле, кроме имени и самих данных: размер, права, владелец, временные метки и — главное — указатели на блоки данных на диске.

Имя файла хранится отдельно — в каталоге, который связывает имя с номером inode. Поэтому один и тот же файл (inode) может иметь несколько имён (это «жёсткие ссылки»). Удаление имени не удаляет файл, пока на его inode ссылается хотя бы одно имя.

каталог:  "report.txt" -> inode 12
inode 12: размер=4096, права=rw-, владелец=ernest,
          блоки данных -> [88, 89, 142, 143]

Проблема: как inode указывает на блоки

Файл может быть огромным и занимать тысячи блоков. Хранить список всех блоков прямо в inode нельзя — он раздуется. Решение — многоуровневые указатели: несколько прямых указателей на блоки данных, плюс косвенные указатели на блоки, которые сами содержат указатели. Так маленькие файлы адресуются мгновенно, а большие — через дополнительные уровни.

Методы выделения блоков

Есть три классических способа разместить блоки файла на диске.

1. Непрерывное выделение

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

2. Связное выделение

Блоки разбросаны, каждый хранит указатель на следующий — как односвязный список. Плюс — нет внешней фрагментации, файл легко растёт. Минус — медленный произвольный доступ: чтобы добраться до блока N, надо пройти все предыдущие. Потеря одного указателя рвёт файл.

3. Индексное выделение

Все указатели на блоки файла собраны в один индексный блок (это и есть подход inode). Плюс — быстрый произвольный доступ, нет внешней фрагментации. Минус — индексный блок занимает место, для маленьких файлов это накладно.

МетодПроизвольный доступРост файлаФрагментация
Непрерывныйбыстрыйсложновнешняя
Связныймедленныйлегконет внешней
Индексныйбыстрыйлегконет внешней

Сравним доступ к блоку

Покажем разницу в стоимости произвольного доступа: связный метод проходит блоки по цепочке, индексный — берёт указатель сразу.

# Файл из блоков, хотим прочитать блок с индексом target (0-based)
blocks = ["b0", "b1", "b2", "b3", "b4"]
target = 4

# Связное выделение: идём по цепочке от начала
steps_linked = 0
for i in range(len(blocks)):
    steps_linked += 1
    if i == target:
        break
print(f"Связное выделение: {steps_linked} шагов, чтобы дойти до блока {target}")

# Индексное выделение: берём указатель из таблицы за 1 шаг
index_table = {i: blocks[i] for i in range(len(blocks))}
print(f"Индексное выделение: 1 шаг -> {index_table[target]}")

Вывод:

Связное выделение: 5 шагов, чтобы дойти до блока 4
Индексное выделение: 1 шаг -> b4

Итог

  • Inode хранит метаданные файла и указатели на его блоки, но не имя и не данные.
  • Имя хранится в каталоге и связывается с номером inode; имён может быть несколько.
  • Большие файлы адресуются многоуровневыми (косвенными) указателями.
  • Методы выделения: непрерывный, связный, индексный.
  • Индексный (как у inode) сочетает быстрый произвольный доступ и отсутствие внешней фрагментации.
Проверьте себя
1. Что НЕ хранится в inode?
AРазмер файла
BИмя файла
CПрава доступа
DУказатели на блоки данных
2. Какой недостаток у связного (связанного списком) выделения блоков?
AВнешняя фрагментация
BМедленный произвольный доступ — к блоку N нужно пройти все предыдущие
CФайл нельзя увеличить
DНевозможно хранить метаданные
3. Чем хорош индексный метод выделения (подход inode)?
AОн не требует места под указатели
BБыстрый произвольный доступ и отсутствие внешней фрагментации
CФайл обязательно занимает подряд идущие блоки
DОн работает только для маленьких файлов
Поддержать проект