Устройство файловой системы: FHS, inode, ext4
Разбираемся, как Linux раскладывает файлы по дереву каталогов и что на самом деле такое «файл» с точки зрения файловой системы ext4.
inode — структура с метаданными одного файла (права, владелец, размер, время, указатели на блоки данных), но БЕЗ его имени. Имя живёт отдельно — в каталоге.
Зачем это знать на практике
Рано или поздно вы упрётесь в одну из классических ситуаций: df говорит, что диск занят на 100%, а du насчитывает в разы меньше; rm «удалил» файл, но место не освободилось; на разделе «закончились файлы», хотя свободных гигабайт полно. Все эти загадки объясняются устройством файловой системы — иерархией каталогов и тем, что файл и его имя — это две разные сущности. Понимание inode превращает магию в инженерию.
Стандарт иерархии: FHS
В Linux нет дисков C: и D:. Есть единый корень /, в который монтируется всё остальное. Раскладку каталогов описывает стандарт FHS (Filesystem Hierarchy Standard) — благодаря ему вы знаете, где искать конфиги в любом дистрибутиве.
| Каталог | Что внутри |
/etc | системные конфиги (текстовые файлы): пользователи, сеть, сервисы |
/var | изменяемые данные: логи (/var/log), кэши, очереди, БД |
/usr | программы и библиотеки, установленные пакетным менеджером (/usr/bin, /usr/lib) |
/home | домашние каталоги пользователей |
/bin, /sbin | базовые утилиты (в современных системах — симлинки в /usr) |
/tmp | временные файлы, чистится при перезагрузке |
/proc, /sys | виртуальные ФС: окно в ядро и устройства, на диске их нет |
/dev | файлы устройств (диски, терминалы, /dev/null) |
/proc — файлы, которых нет
/proc — не настоящий каталог на диске, а интерфейс ядра, прикинувшийся файловой системой. Каждый запущенный процесс получает там подкаталог по своему PID, а отдельные «файлы» отдают живое состояние системы:
cat /proc/cpuinfo # модель и число ядер CPU
cat /proc/meminfo # сколько памяти всего и свободно
cat /proc/loadavg # средняя нагрузка за 1/5/15 минут
ls /proc/$$/ # каталог ТЕКУЩЕЙ оболочки ($$ — её PID)
Размер у этих файлов нулевой — они генерируются на лету в момент чтения. Это самый прямой способ «поговорить» с ядром без специальных утилит.
Что такое файл на самом деле
Файл — это inode плюс блоки данных. В inode хранится всё, КРОМЕ имени: тип (обычный файл, каталог, симлинк), права, UID/GID владельца, размер, временные метки и указатели на блоки с содержимым. Имя файла лежит в каталоге, который, по сути, является таблицей пар «имя → номер inode».
Каждый inode имеет уникальный в пределах файловой системы номер. Посмотреть его можно ключом -i:
ls -i /etc/hostname
# 131073 /etc/hostname
stat /etc/hostname
# File: /etc/hostname
# Size: 7 Blocks: 8 IO Block: 4096 regular file
# Device: 803h/2051d Inode: 131073 Links: 1
# Access: (0644/-rw-r--r--) Uid: (0/root) Gid: (0/root)
Команда stat — это прямой дамп inode. Обратите внимание на поле Links: это счётчик жёстких ссылок (имён), указывающих на данный inode. К нему мы вернёмся в уроке про ссылки.
Три времени файла
- atime — время последнего доступа (чтения);
- mtime — время последнего изменения содержимого;
- ctime — время последнего изменения метаданных inode (например,
chmodменяет ctime, но не mtime).
stat -c '%n atime=%x mtime=%y ctime=%z' /etc/hostname
Как это работает под капотом
Файловая система ext4 делит раздел на блоки (обычно по 4 КБ) и группы блоков. В начале раздела лежит суперблок с общими параметрами ФС, а в каждой группе — таблица inode фиксированного размера. Число inode задаётся при создании файловой системы (mkfs.ext4) и потом не меняется. Поэтому возможна ситуация «место есть, а inode кончились»: миллионы крошечных файлов исчерпали таблицу inode раньше, чем гигабайты.
df -i # сколько inode свободно (а не байт)
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 6553600 280143 6273457 5% /
Когда вы открываете файл, ядро по имени из каталога находит номер inode, читает inode, по его указателям добирается до блоков данных. ext4 хранит указатели не списком, а экстентами — диапазонами подряд идущих блоков, что ускоряет работу с большими файлами и снижает фрагментацию. Ещё ext4 ведёт журнал (journal): перед записью изменения сначала фиксируются в журнале, поэтому после внезапного выключения ФС восстанавливается в согласованное состояние, а не «разваливается».
Частые ошибки
- Путать размер файла и занятое место. «Дырявый» (sparse) файл может показывать размер 10 ГБ, но занимать на диске килобайты.
du --apparent-sizeпокажет логический размер, обычныйdu— реально занятые блоки. - Думать, что
rmстирает данные сразу. Удаление лишь убирает имя из каталога и уменьшает счётчик ссылок. Пока файл открыт хоть одним процессом, его inode и блоки живут — место освободится только после закрытия дескриптора. - Полагаться на atime. Многие системы монтируют ФС с
relatimeилиnoatime, чтобы не писать на диск при каждом чтении, поэтому atime может быть неточным.
Итоги
- В Linux один корень
/, раскладку каталогов диктует стандарт FHS:/etc— конфиги,/var— логи и данные,/usr— программы. /procи/sys— виртуальные ФС-окна в ядро; их «файлы» генерируются на лету.- Файл = inode (метаданные + указатели на блоки) + само имя в каталоге; имя и inode разделены.
ls -iиstatпоказывают inode;df -i— запас inode, который тоже может закончиться.- ext4 использует экстенты и журнал — отсюда скорость и устойчивость к сбоям.