Архитектура VFS, часть 2 — Inodes: что это и как с этим работать

Файл в линуксе — это не "имя на диске", а три отдельные сущности: запись в каталоге, inode и блоки данных. Понимание того, как они связаны, объясняет почти всё "странное" (нет) поведение файловой системы: почему df -h показывает свободное место, а файл не создаётся; почему удалённый файл продолжает занимать диск; почему перенос гигантского файла на 100 ГБ между папками происходит мгновенно.
В этой статье разберём архитектуру VFS на уровне inode — без углубления в архитектуру, но на достаточном уровне, чтобы уметь заниматься диагностикой и с уверенностью отвечать собеседующему, почему на диске терабайты свободного места, а новый файлик создать не получается.
Что конкретно мы сегодня изучим:
Что такое Inodes? Что такое каталог?
Как на самом деле Linux хранит файлы.
Виды ссылок: хардлинки и симлинки.
Команды для диагностики: как посмотреть inode, найти файл по номеру и понять, куда делось место.
1. Что такое Inode? Что такое каталог?
Inode (айноды или index node - "индексный дескриптор") - это структура данных, которая хранит всю служебную информацию о файле или каталоге. Однако не хранит его имя или содержимое.
В айноде хранится:
Размер файла.
Права доступа.
Идентификаторы владельца и группы (UID и GID).
Временные метки (время создания, изменения и последнего доступа —
atime,mtime,ctime).Счётчик жёстких ссылок, указывающих на этот файл.
Указатели на физические блоки диска, где реально лежат данные файла.
Структура (основные поля данных) айноды:
File mode - Определяет тип файла (обычный файл, каталог, символическая ссылка, блочное устройство и тд) и права доступа к файлу для владельца, группы и остальных.
Owner ID (UID) - идентификатор пользователя-владельца файла.
Group ID (GID) - идентификатор группы, которой принадлежит файл.
File Size (Размер файла) - размер файла в байтах.
Links Count (Счетчик жестких ссылок) - количество жестких ссылок, указывающих на данный inode. Файл удаляется с диска только тогда, когда это значение становится равным 0.
Timestamps (Временны́е метки) - включают сразу три поля:
atime - время последнего открытия файла.
mtime - время последнего изменения содержимого файла.
ctime - время последнего изменения метаданных файла (например, смена прав, владельца).
crtime - время создания файла. Встречается не везде, но есть в XFS, BTRFS.
Block Pointers (Указатели на дисковые блоки) - поле фиксированного размера, которое указывает, где на диске физически хранятся данные файла. Указатели бывают разных типов, и у каждого свой механизм указания адресов:
В прямых блоках это адрес блока с данными файла.
В косвенных блоках это адрес служебного блока, который полностью заполнен точно такими же 32-битными числами (адресами следующего уровня).
Вы заметили, что имени файла в inode нет? Имя и связь с номером айноды хранятся внутри каталога, который сам по себе является отдельным файлом. О нём мы сегодня также поговорим.
Важные особенности:
Уникальность. Каждый файл или каталог имеют свой уникальный номер inode в пределах данной файловой системы.
Фиксированное количество. При форматировании диска создаётся таблица inode. Количество айнод ограничено.
Проблема исчерпания. Если на вашем диске ещё полно свободного места, но закончились inode (обычно из-за огромного количества мелких файлов), система выдаст ошибку, что диск переполнен и создать новый файл нельзя.
Таблица inode - это выделенная область на диске, которая создаётся при его форматировании и представляет собой пронумерованный массив всех айнод. Такая таблица есть у всех файловых систем.
Когда вы форматируете диск, всё его пространство разбивается на логические зоны. В самом начале диска резервируется фиксированное место под физические данные:
Суперблок. Хранит общую информацию о файловой системе (размер, тип и тд)
Таблица inode. Это непрерывная цепочка секторов диска, где упорядоченно друг за другом лежат пустые структуры данных. Первая айнода, вторая, тысячная, миллионная...
Блоки данных. Всё оставшееся и самое большое пространство диска, где будут храниться ваши тексты, фото и видео.
По умолчанию утилиты форматирования(например, mkfs.ext4) рассчитывают количество айнод по формуле: 1 айнода на каждые 16 килобайт пространства диска. Через параметры это значение можно поменять, а некоторые файловые системы умеют создавать айноды динамически прямо в процессе работы, поэтому у них таблица inode не имеет фиксированного размера и не может «закончиться» раньше самого диска.
Что такое каталог?
С точки зрения файловой системы, каталог - это точно такой же файл, у которого есть свой inode. Но у содержимого (блоках данных) этого файла другая структура, чем у условных текстовых файлов.
Проблема: inode - это нумерованная структура данных, которая хранит метаданные файла, но не хранит имя. Как же нам обратиться к файлу, зная только его имя?
Для этого и нужен каталог: для того, чтобы связывать понятные человеку имена файла (например, passwords.txt) с их числовыми идентификаторами - именами inode.
Содержимое каталога - это таблица. Его блоки данных хранят простой список записей. Каждая запись состоит из двух основных полей:
[ Текстовое имя ] <-> [ Номер inode ]
Служебные записи
Внутри каждого каталога всегда есть две обязательные записи, которые напрямую завязаны на inode:
.(точка): Ссылается на номерinodeэтого же каталога...(две точки): Ссылается на номерinodeродительского каталога.
Именно поэтому у любого созданного каталога счетчик ссылок в метаданных inode всегда равен минимум 2 (сама ссылка из родительского каталога + запись . внутри него).
Пример: как ОС ищет файл /home/user/photo.jpg
Когда вы вызываете файл по его пути, ядро производит пошаговое обращение через цепочку каталогов:
ОС обращается к корневому каталогу
/. Его номерinodeжестко зашит в файловой системе (обычно это inode N2)Читаются блоки данных корневого каталога, в которых ищется строка
"home". Рядом с ней находится номерinodeдля этого каталога.ОС переходит к найденному
inodeкаталогаhome, открывает его блоки данных и ищет там строку"user", получая следующийinode.Процесс повторяется для каталога
user, где наконец находится строка"photo.jpg"и соответствующий ейinodeсамого файла.Из
inodeфайлаphoto.jpgОС считывает адреса физических блоков на диске и выдает вам его содержимое.
2. В итоге - как Linux хранит файлы?
Чтобы не дублировать раздел выше, подытожим:
В Linux всякий файл - это запись в каталоге + inode + блоки данных, на которые указывает inode.
Сделать из прочитанного можно следующие выводы:
Файл можно удалить, только когда на него никто не ссылается. Если вы удалите имя файла из каталога, но этот файл сейчас открыт какой-то программой, инод и блоки данных останутся на диске. Файловая система окончательно сотрет инод и освободит блоки только тогда, когда Links Count (и из каталогов, и от запущенных процессов) станет равен нулю.
Перемещение файла внутри одного раздела происходит мгновенно. Если вы переносите фильм весом 50 ГБ из папки в папку на одном диске, Linux не копирует байты. Он просто стирает запись [Имя] <-> [inode] в старом каталоге и создает её в новом. Сам файл спокойно лежит на диске и в ус не дует.
Ссылки: хардлинки и симлинки
Ссылки - это механизм файловый системы, позволяющий обращаться к одному и тому же файлу (оригиналу) или каталогу по разным именам или путям.
Ссылки делятся на два вида: жёсткие (Hard Links, хардлинки) и символические (Symbolic Links, симлинки)
Что такое жёсткие ссылки?
Жёсткая ссылка - это запись в каталоге, ссылающаяся на тот же айнод, что и её "оригинал". По факту - это просто новое имя для файла.
Отмечу, что после создания хардлинка понятия "оригинал" в строгом смысле нет. Оба имени равноправны. Ни одно из них не является «главным» — оба указывают на один inode, и в самом inode хранится счётчик ссылок (link count), который показывает, сколько имён сейчас ссылаются на него.
Создать хардлинк можно командой ln без дополнительных параметров (она создаёт их по умолчанию):
ln original.txt hard_link.txtНебольшой пример того, как работает link count в нашем случае:
Создали
file1- inode с link count = 1.Сделали
ln file1 file2- link count = 2, оба имени равнозначны.Удалили
file1(rm file1) - link count = 1, данные по-прежнему доступны черезfile2.Удалили
file2- link count = 0, inode и блоки данных освобождаются.
Именно поэтому понятие "оригинал" здесь больше условность. С точки зрения ФС это просто два имени одного inode
Итоги:
Жёсткие ссылки не занимают место под данные — только запись в каталоге (несколько байт). Поэтому ими пользуются для экономии места.
Жёсткие ссылки нельзя делать на каталоги — это создало бы циклы, когда каталог обращается сам к себе или своему родителю.
Жёсткие ссылки не работают между разными файловыми системами — потому что номер inode уникален только в пределах одной ФС.
Изменение содержимого через любое имя видно через все остальные — ведь данные и метаданные одни и те же.
Права и владелец тоже общие — изменили
chmodчерезfile2, изменилось и дляfile1.
Что такое символические ссылки?
Символическая ссылка - это отдельный файл с отдельной айнодой, содержащий в себе путь к целевому файлу или каталогу. Аналогия: ярлык в Windows.
Целевой файл/каталог - это файл/каталог, на который указывает символическая ссылка.
Чем символическая ссылка отличается от обычного файла с путём внутри? Внутри айноды этого файла, в поле File mode, ставится флаг S_IFLNK. Именно по этому флагу ядро мгновенно понимает, что перед нами не данные, а указатель, и чтение нужно перенаправить.
Симлинк - это текстовый файл-путеводитель. Когда вы или любая программа открываете симлинк, ядро Linux смотрит внутрь него, видит там строку с путем (например, /var/log/app.log) и автоматически переводит фокус на этот целевой файл. Для программ этот процесс прозрачен: они думают, что работают с реальным файлом, но на самом деле работают через ссылку.
Создать симлинк можно командой ln с параметром -s:
ln -s original.txt softlink.txtВ отличие от хардлинков, симлинки могут указывать на каталоги:
ln -s original_folder/ soft_folder/Чтобы увидеть более наглядные примеры взаимодействия с симлинками, очень рекомендую эту статью: https://habr.com/ru/companies/timeweb/articles/925150/
Что будет, если удалить/переместить целевой файл? В таком случае символическая ссылка станет "висячей" и при попытке обратиться к ней программа получит ошибку No such file or directory.
Важные выводы и особенности:
Так как симлинк - отдельный файл с отдельной айнодой, у него есть свои права доступа. Права на сам симлинк не имеют значения. Ядро при обращении проверяет права целевого файла, на который симлинк указывает.
Симлинки могут указывать как на файлы, так и на каталоги, а также работать между разными файловыми системами или разделами.
При удалении или перемещении целевого файла симлинк не удаляется автоматически, а становится «битым» или «висячим», так как строка пути внутри него начинает указывать на несуществующий объект.
В современных файловых системах существует оптимизация Fast Symlinks: если длина пути меньше 60 символов, строка записывается прямо внутрь айноды симлинка, благодаря чему он вообще не занимает блоки на диске и считывается мгновенно.
Путь внутри симлинка может быть абсолютным (весь путь от корневого каталога) или относительным (адрес файла относительно каталога, где находится симлинк)
Практика: команды для диагностики
Я бы разделил команды по их применению, то есть на четыре группы: проверка использования айнод, получение номеры айноды, работа с конкретными файлами по номеру айнод.
1. Общая диагностика
# Простейший способ для просмотра использования айнод на всех смонтированных ФС
$ df -i
# Проверяет использование места на диске (чтобы убедиться, чтобы проблемы действительно в айнодах)
$ df -h
# Выводит 10 папок с самым большим количеством файлов (то есть айнод) в текущем каталоге
$ find . -printf '%h\n' | sort | uniq -c | sort -rn | head -10
# Подсчитывает количество айнод в текущем каталоге
$ find . | wc -l2. Получение номера айноды
# Узнать номер айноды файла
$ ls -i <path/to/file>
# Посмотреть полные метаданные файла
$ stat <path/to/file>
# Выводит список файлов текущего каталога и номера айнод первым столбцом
$ ls -li3. Работа с файлами по номеру айноды
# Найти файл на диске по номеру айноды
$ sudo find / -inum <inode_number>
# Удалить файл по его айноде
$ find . -inum <inode_number> -delete
# Позволяет выполнить с файлом любую команду по номеру его айноды
$ find <path/to/file> -inum <inode_number> -exec <command> {} \;Источники
https://adminvps.ru/blog/chto-takoe-inody-inode-v-linux-prostoe-i-podrobnoe-rukovodstvo/
Нейросеть DeepSeek - консультация.
Нейросеть Gemini - консультация.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
0%Всё разложено по полочкам, сложностей не возникло0
0%В целом всё понятно, но некоторые моменты пришлось перечитывать0
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.