Поиск по сайту:

Все, что вы хотели знать об инодах в Linux


Файловая система Linux использует inode. Эти жизненно важные части внутренней работы файловой системы часто понимают неправильно. Давайте посмотрим, что именно они собой представляют и что они делают.

Элементы файловой системы

По определению файловая система должна хранить файлы, и они также содержат каталоги. Файлы хранятся в каталогах, и эти каталоги могут иметь подкаталоги. Что-то где-то должно записывать, где находятся все файлы в файловой системе, как они называются, к каким учетным записям они принадлежат, какие у них разрешения и многое другое. Эта информация называется метаданными, потому что это данные, которые описывают другие данные.

В файловой системе Linux ext4 структуры индексного дескриптора и каталога работают вместе, чтобы обеспечить базовую структуру, в которой хранятся все метаданные для каждого файла и каталога. Они делают метаданные доступными для всех, кто в них нуждается, будь то ядро, пользовательские приложения или утилиты Linux, такие как ls, stat и df.

Inodes и размер файловой системы

Хотя это правда, что есть пара структур, файловая система требует гораздо большего. Существуют тысячи и тысячи каждой структуры. Для каждого файла и каталога требуется индексный дескриптор, а поскольку каждый файл находится в каталоге, для каждого файла также требуется структура каталогов. Структуры каталогов также называются записями каталогов или «dentries».

У каждого индекса есть номер индекса, который уникален в файловой системе. Один и тот же номер индекса может появиться более чем в одной файловой системе. Однако идентификатор файловой системы и номер индексного дескриптора вместе составляют уникальный идентификатор, независимо от того, сколько файловых систем смонтировано в вашей системе Linux.

Помните, что в Linux вы не монтируете жесткий диск или раздел. Вы монтируете файловую систему, которая находится на разделе, поэтому легко иметь несколько файловых систем, не осознавая этого. Если у вас есть несколько жестких дисков или разделов на одном диске, у вас более одной файловой системы. Они могут быть одного типа — например, все ext4 — но они все равно будут разными файловыми системами.

Все иноды хранятся в одной таблице. Используя номер инода, файловая система легко вычисляет смещение в таблице инодов, в которой находится этот инод. Вы можете понять, почему «i» в inode означает index.

Переменная, содержащая номер инода, объявлена в исходном коде как 32-битное длинное целое без знака. Это означает, что номер инода представляет собой целое число с максимальным размером 2^32, что составляет 4 294 967 295 — более 4 миллиардов инодов.

Это теоретический максимум. На практике количество индексных дескрипторов в файловой системе ext4 определяется, когда файловая система создается с соотношением по умолчанию: один индексный дескриптор на 16 КБ емкости файловой системы. Структуры каталогов создаются «на лету», когда файловая система используется, поскольку файлы и каталоги создаются в файловой системе.

Есть команда, которую вы можете использовать, чтобы узнать, сколько инодов находится в файловой системе вашего компьютера. Опция -i (inodes) команды df предписывает ей отображать выходные данные в количестве inodes.

Мы собираемся посмотреть на файловую систему в первом разделе на первом жестком диске, поэтому набираем следующее:

df -i /dev/sda1

Вывод дает нам:

  • Файловая система: файловая система, для которой создается отчет.
  • Inodes: общее количество inodes в этой файловой системе.
  • IUsed: количество используемых инодов.
  • IFree: количество оставшихся инодов, доступных для использования.
  • IUse%: процент используемых инодов.
  • Смонтировано: точка подключения для этой файловой системы.

Мы использовали 10 процентов инодов в этой файловой системе. Файлы хранятся на жестком диске в дисковых блоках. Каждый индекс указывает на блоки диска, в которых хранится содержимое файла, который они представляют. Если у вас есть миллионы крошечных файлов, у вас могут закончиться индексные дескрипторы до того, как закончится место на жестком диске. Тем не менее, это очень сложная проблема.

В прошлом эта проблема возникала у некоторых почтовых серверов, которые хранили сообщения электронной почты в виде отдельных файлов (что быстро приводило к созданию больших коллекций небольших файлов). Однако когда эти приложения изменили свою серверную часть на базы данных, это решило проблему. Средняя домашняя система не исчерпает иноды, и это хорошо, потому что с файловой системой ext4 вы не можете добавить больше инодов без переустановки файловой системы.

Чтобы увидеть размер дисковых блоков в вашей файловой системе, вы можете использовать команду blockdev с параметром --getbsz (получить размер блока):

sudo blockdev --getbsz /dev/sda

Размер блока 4096 байт.

Давайте воспользуемся параметром -B (размер блока), чтобы указать размер блока 4096 байт и проверить обычное использование диска:

df -B 4096 /dev/sda1

Этот вывод показывает нам:

  • Файловая система: файловая система, для которой мы отчитываемся.
  • 4K-blocks: общее количество блоков по 4 КБ в этой файловой системе.
  • Используется: сколько блоков 4K используется.
  • Доступно: количество оставшихся блоков размером 4 КБ, доступных для использования.
  • Использование%: процент использованных блоков по 4 КБ.
  • Смонтировано: точка подключения для этой файловой системы.

В нашем примере файловое хранилище (а также хранилище индексных дескрипторов и структур каталогов) использует 28 процентов места в этой файловой системе за счет 10 процентов инодов, так что мы в хорошей форме.

Метаданные инода

Чтобы увидеть номер инода файла, мы можем использовать ls с опцией -i (inode):

ls -i geek.txt

Номер индекса для этого файла — 1441801, поэтому этот индекс содержит метаданные для этого файла и, традиционно, указатели на дисковые блоки, где файл находится на жестком диске. Если файл фрагментирован, очень велик или и то, и другое, некоторые блоки, на которые указывает индексный дескриптор, могут содержать дополнительные указатели на другие блоки диска. И некоторые из этих других дисковых блоков могут также содержать указатели на другой набор дисковых блоков. Это преодолевает проблему, связанную с тем, что индексный дескриптор имеет фиксированный размер и может содержать конечное число указателей на дисковые блоки.

Этот метод был заменен новой схемой, использующей «экстенты». Они записывают начальный и конечный блоки каждого набора смежных блоков, используемых для хранения файла. Если файл не фрагментирован, вам нужно сохранить только первый блок и длину файла. Если файл фрагментирован, вы должны сохранить первый и последний блоки каждой части файла. Этот метод (очевидно) более эффективен.

Если вы хотите узнать, использует ли ваша файловая система указатели дисковых блоков или экстенты, вы можете заглянуть внутрь индексного дескриптора. Для этого мы воспользуемся командой debugfs с параметром -R (запрос) и передадим ей индексный дескриптор интересующего файла. Это просит debugfs использовать внутреннюю команду stat для отображения содержимого индексного дескриптора. Поскольку номера инодов уникальны только в пределах файловой системы, мы также должны сообщить debugfs файловую систему, в которой находится инод.

Вот как будет выглядеть этот пример команды:

sudo debugfs -R "stat <1441801>" /dev/sda1

Как показано ниже, команда debugfs извлекает информацию из индексного дескриптора и представляет ее нам в формате less:

Нам показывают следующую информацию:

  • Inode: номер интересующего нас inode.
  • Тип: это обычный файл, а не каталог или символическая ссылка.
  • Режим: права доступа к файлу в восьмеричном формате.
  • Флаги: индикаторы, представляющие различные функции или функции. 0x80000 — это флаг экстентов (подробнее об этом ниже).
  • Создание. Сетевая файловая система (NFS) использует это, когда кто-то получает доступ к удаленным файловым системам через сетевое подключение, как если бы они были смонтированы на локальном компьютере. Индексный дескриптор и номер поколения используются как форма дескриптора файла.
  • Версия: версия inode.
  • Пользователь: владелец файла.
  • Группа: группа-владелец файла.
  • Проект: всегда должен быть равен нулю.
  • Размер: размер файла.
  • Файл ACL: список контроля доступа к файлам. Они были разработаны, чтобы вы могли предоставить контролируемый доступ людям, которые не входят в группу владельцев.
  • Ссылки: количество жестких ссылок на файл.
  • Счетчик блоков: объем места на жестком диске, выделенный для этого файла, представленный фрагментами по 512 байт. В нашем файле было выделено восемь из них, что составляет 4096 байт. Итак, наш 98-байтовый файл находится в одном 4096-байтовом блоке диска.
  • Фрагмент: этот файл не фрагментирован. (Это устаревший флаг.)
  • Ctime: время создания файла.
  • Время: время последнего доступа к этому файлу.
  • Mtime: время последнего изменения файла.
  • Crtime: время создания файла.
  • Размер дополнительных полей индексного дескриптора. В файловой системе ext4 появилась возможность выделять больший индексный дескриптор на диске во время форматирования. Это значение представляет собой количество дополнительных байтов, которые использует индексный дескриптор. Это дополнительное пространство также можно использовать для удовлетворения будущих требований к новым ядрам или для хранения расширенных атрибутов.
  • Контрольная сумма индекса: контрольная сумма для этого индекса, которая позволяет определить, поврежден ли индекс.
  • Экстенты: если используются экстенты (в ext4 они используются по умолчанию), метаданные, касающиеся использования файловых блоков на диске, имеют два числа, которые указывают начальный и конечный блоки каждой части. фрагментированного файла. Это более эффективно, чем хранение каждого блока диска, занятого каждой частью файла. У нас один экстент, потому что наш небольшой файл находится в одном блоке диска по этому смещению блока.

Где имя файла?

Теперь у нас есть много информации о файле, но, как вы могли заметить, мы не получили имя файла. Здесь в игру вступает структура каталогов. В Linux, как и у файла, у каталога есть индексный дескриптор. Однако индексный дескриптор каталога указывает не на блоки диска, содержащие файловые данные, а на блоки диска, содержащие структуры каталогов.

По сравнению с inode структура каталогов содержит ограниченный объем информации о файле. Он содержит только номер инода файла, имя и длину имени.

Индексный дескриптор и структура каталогов содержат все, что вам (или приложению) нужно знать о файле или каталоге. Структура каталогов находится в блоке диска каталогов, поэтому мы знаем каталог, в котором находится файл. Структура каталогов дает нам имя файла и номер индексного дескриптора. Инод сообщает нам все остальное о файле, включая метки времени, разрешения и местонахождение файловых данных в файловой системе.

Иноды каталога

Вы можете увидеть номер инода каталога так же легко, как вы можете увидеть его для файлов.

В следующем примере мы будем использовать ls с -l (длинный формат), -i (inode) и -d (каталог) и просмотрите каталог work:

ls -lid work/

Поскольку мы использовали параметр -d (каталог), ls сообщает о самом каталоге, а не о его содержимом. Индекс этого каталога — 1443016.

Чтобы повторить это для каталога home, введите следующее:

ls -lid ~

Индексный дескриптор home каталога — 1447510, а work каталог находится в домашнем каталоге. Теперь давайте посмотрим на содержимое каталога work. Вместо параметра -d (каталог) мы будем использовать параметр -a (все). Это покажет нам записи каталога, которые обычно скрыты.

Набираем следующее:

ls -lia work/

Поскольку мы использовали параметр -a (все), отображаются записи с одной (.) и двойной точкой (..). Эти записи представляют сам каталог (одна точка) и его родительский каталог (двойная точка).

Если вы посмотрите на номер индекса для записи с одной точкой, вы увидите, что это 1443016 — тот же номер индекса, который мы получили, когда обнаружили номер индекса для каталога work. Кроме того, номер инода для записи с двумя точками совпадает с номером инода для каталога home.

Вот почему вы можете использовать команду cd .. для перехода на уровень вверх в дереве каталогов. Аналогичным образом, если вы ставите перед именем приложения или скрипта префикс  ./, вы сообщаете оболочке, откуда запускать приложение или скрипт.

Иноды и ссылки

Как мы уже говорили, для наличия правильно сформированного и доступного файла в файловой системе требуются три компонента: файл, структура каталогов и индексный дескриптор. Файл — это данные, хранящиеся на жестком диске, структура каталогов содержит имя файла и номер его индексного дескриптора, а индексный дескриптор содержит все метаданные для файла.

Символические ссылки — это записи файловой системы, которые выглядят как файлы, но на самом деле являются ярлыками, указывающими на существующий файл или каталог. Давайте посмотрим, как им это удается и как для этого используются три элемента.

Допустим, у нас есть каталог с двумя файлами: один — скрипт, а другой — приложение, как показано ниже.

Мы можем использовать команду ln и параметр -s (символический), чтобы создать программную ссылку на файл скрипта, например:

ls -s my_script geek.sh

Мы создали ссылку на my_script.sh с именем geek.sh. Мы можем ввести следующее и использовать ls для просмотра двух файлов скриптов:

лс-ли *.ш

Запись для geek.sh выделена синим цветом. Первый символ флагов разрешений — это «l» для ссылки, а -> указывает на my_script.sh . Все это указывает на то, что geek.sh является ссылкой.

Как вы, вероятно, ожидаете, два файла сценария имеют разные номера инодов. Что может быть более удивительным, так это то, что программная ссылка geek.sh не имеет тех же разрешений пользователя, что и исходный файл сценария. На самом деле разрешения для geek.sh гораздо более либеральны — все пользователи имеют полные разрешения.

Структура каталогов для geek.sh содержит имя ссылки и ее индексный дескриптор. Когда вы пытаетесь использовать ссылку, ссылаются на ее индексный дескриптор, как и на обычный файл. Инод ссылки будет указывать на блок диска, но вместо данных о содержимом файла блок диска содержит имя исходного файла. Файловая система перенаправляет на исходный файл.

Мы удалим исходный файл и посмотрим, что произойдет, если мы введем следующее для просмотра содержимого geek.sh:

rm my_script.sh
cat geek.sh

Символическая ссылка не работает, и перенаправление не выполняется.

Теперь мы вводим следующее, чтобы создать жесткую ссылку на файл приложения:

ln special-app geek-app

Чтобы просмотреть индексные дескрипторы этих двух файлов, введите следующее:

ls -li

Оба выглядят как обычные файлы. Ничто в geek-app не указывает на то, что это ссылка, в отличие от листинга ls для geek.sh. Кроме того, geek-app имеет те же разрешения пользователя, что и исходный файл. Однако может показаться удивительным, что оба приложения имеют одинаковый номер инода: 1441797.

Запись каталога для geek-app содержит имя «geek-app» и номер инода, но он совпадает с номером инода исходного файла. Итак, у нас есть две записи файловой системы с разными именами, которые указывают на один и тот же индексный дескриптор. На самом деле любое количество элементов может указывать на один и тот же индексный дескриптор.

Мы напечатаем следующее и воспользуемся программой stat для просмотра целевого файла:

stat special-app

Мы видим, что две жесткие ссылки указывают на этот файл. Это хранится в inode.

В следующем примере мы удаляем исходный файл и пытаемся использовать ссылку с секретным безопасным паролем:

rm special-app
./geek-app correcthorsebatterystaple

Удивительно, но приложение работает как положено, но как? Это работает, потому что когда вы удаляете файл, индекс можно использовать повторно. Структура каталогов помечается как имеющая нулевой номер инода, после чего блоки диска становятся доступными для хранения другого файла в этом пространстве.

Однако, если количество жестких ссылок на индексный дескриптор больше одной, количество жестких ссылок уменьшается на единицу, а номер инода структуры каталогов удаленного файла устанавливается равным нулю. Содержимое файла на жестком диске и inode по-прежнему доступно для существующих жестких ссылок.

Мы введем следующее и воспользуемся статистикой еще раз — на этот раз в geek-app:

stat geek-app

Эти сведения извлекаются из того же индекса (1441797), что и предыдущая команда stat. Количество ссылок уменьшилось на одну.

Поскольку у нас осталась только одна жесткая ссылка на этот индексный дескриптор, если мы удалим geek-app, это действительно приведет к удалению файла. Файловая система освободит индекс и пометит структуру каталогов нулевым индексом. Затем новый файл может перезаписать хранилище данных на жестком диске.

Инод Накладные расходы

это аккуратная система, но есть накладные расходы. Чтобы прочитать файл, файловая система должна сделать следующее:

  • Найти правильную структуру каталогов
  • Прочитать номер инода
  • Найти нужный индекс
  • Прочитать информацию об индексном узле
  • Следуйте ссылкам inode или экстентам на соответствующие блоки диска.
  • Прочитать данные файла

Немного больше прыжков необходимо, если данные несмежные.

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

Конечно, ускорение доступа к файловой системе — это то, почему Linux старается максимально упреждающе кэшировать файлы. Это очень помогает, но иногда — как и в случае с любой файловой системой — накладные расходы могут стать очевидными.

Теперь ты узнаешь, почему.

RELATED: Best Linux Laptops for Developers and Enthusiasts