Файл в линуксе — это не «имя на диске», а три отдельные сущности: запись в каталоге, 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 -l
2. Получение номера айноды
# Узнать номер айноды файла$ ls -i <path/to/file># Посмотреть полные метаданные файла$ stat <path/to/file># Выводит список файлов текущего каталога и номера айнод первым столбцом$ ls -li
3. Работа с файлами по номеру айноды
# Найти файл на диске по номеру айноды$ 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 — консультация.
ссылка на оригинал статьи https://habr.com/ru/articles/1104884/