Перейти к содержанию

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

Что такое файловая система

Файловая система — это способ организации данных на носителе (HDD, SSD и т.п.). Она определяет:

  • как хранятся данные и метаданные (разбиение на блоки, inode-структуры и т.д.);
  • какие типы объектов существуют (файлы, директории, устройства, сокеты и др.);
  • какие операции поддерживаются (жёсткие ссылки, права доступа, расширенные атрибуты и т.д.).

Широко распространённые файловые системы Linux: ext4, XFS, Btrfs, ZFS. Каждая из них по-своему решает задачи надёжности, производительности и возможностей (журналирование, copy-on-write, сжатие и т.п.).

Типы файлов в Linux

Первый символ в выводе ls -l обозначает тип объекта в файловой системе:

Символ Тип Примеры
- Обычный файл /etc/passwd, любой .txt или бинарь
d Директория /home, /tmp
l Символическая ссылка /usr/bin/python -> python3.10
c Символьное (char) устройство /dev/null, /dev/tty, /dev/random
b Блочное устройство /dev/sda, /dev/nvme0n1
p Именованный канал (FIFO) Файл, созданный через mkfifo pipe
s UNIX domain socket /run/systemd/journal/socket

Все эти объекты доступны через единый интерфейс файловой системы: open, read, write, stat и т.д.

Директории с точки зрения файловой системы

Директория — это специальный файл, содержащий список записей (directory entries). Каждая запись связывает имя объекта с его inode:

имя (строка) -> номер inode

Специальные записи . и .. всегда присутствуют в любой директории: они ссылаются на текущую и родительскую директорию соответственно. Именно поэтому счётчик жёстких ссылок (st_nlink) у директории начинается с 2 — одна ссылка из родительского каталога и одна — запись . внутри самой директории.

Суперблок

Суперблок (superblock) — структура в начале файловой системы, содержащая её общие параметры:

  • магическое число (идентификатор типа ФС);
  • размер блока и общее число блоков;
  • число inode и количество свободных inode/блоков;
  • состояние монтирования (корректно размонтирована или нет).

При монтировании ядро читает суперблок и хранит его в памяти. Если система упала до размонтирования, журналирующие ФС ( ext4, XFS) используют журнал для восстановления согласованности.

Расположение структур ext4 на диске (упрощённо):

 диск / раздел
 ┌────────────┬───────────────────────────────────────────────────────────┐
 │ boot block │                   файловая система ext4                   │
 └────────────┴───────────────────────────────────────────────────────────┘
 ┌─────────────┬─────────────────────────────┬─────────────────┬───────────┐
 │  superblock │        block group 0        │  block group 1  │  ...      │
 │  (1 блок)   │                             │                 │           │
 └─────────────┴──────────────┬──────────────┴─────────────────┴───────────┘
              ┌──────────┬──────────┬───────┐
              │  group   │  inode   │ data  │
              │descriptor│  table   │blocks │
              │  table   │(1 inode  │       │
              │          │= 256 Б)  │       │
              └──────────┴──────────┴───────┘

 Одна block group (например, ~128 MB при block size = 4 KB):
 ┌──────────┬──────────────┬────────────────┬──────────────────────────────┐
 │  group   │ block bitmap │  inode bitmap  │  inode table  │  data blocks │
 │descriptor│  (1 блок)    │   (1 блок)     │  (N блоков)   │  (остальное) │
 └──────────┴──────────────┴────────────────┴───────────────┴──────────────┘
  хранит: адрес inode table, адрес bitmap'ов,
          кол-во свободных блоков/inode в группе

Посмотреть информацию о ФС:

df -h              # размер, занятое/свободное место
tune2fs -l /dev/sda1  # суперблок ext4 (требует root)

Inode

Inode (index node) — это структура метаданных объекта в файловой системе. Она хранит всё о файле, кроме его имени:

  • тип и права доступа (st_mode);
  • владелец (st_uid, st_gid);
  • размер (st_size) и временные метки (st_atime, st_mtime, st_ctime);
  • число жёстких ссылок (st_nlink);
  • указатели на блоки данных на диске.

Имя файла хранится не в inode, а в директории. Один inode может быть доступен под несколькими именами — это и есть механизм жёстких ссылок.

 inode (в памяти/на диске)           data blocks (на диске)
 ┌───────────────────────┐
 │ st_ino:    42         │
 │ st_mode:   0644       │           ┌───────────┐
 │ st_uid:    1000       │   blk[0] ─▶  block 0  │  (первые 4 KB данных)
 │ st_gid:    1000       │           └───────────┘
 │ st_size:   12288      │           ┌───────────┐
 │ st_nlink:  2          │   blk[1] ─▶  block 1  │  (следующие 4 KB)
 │ st_atime:  ...        │           └───────────┘
 │ st_mtime:  ...        │           ┌───────────┐
 │ st_ctime:  ...        │   blk[2] ─▶  block 2  │  (последние 4 KB)
 │                       │           └───────────┘
 │ direct blk[0..11]     │ ────┘
 │ indirect              │ ──▶ блок с указателями на блоки данных
 │ dbl_indir             │ ──▶ блок с указателями на indirect-блоки
 └───────────────────────┘

 Директория (тоже файл, данные — список записей):
 ┌───────────────────────────────┐
 │ "."        ──▶ inode 40       │  (текущая директория)
 │ ".."       ──▶ inode 1        │  (родительская)
 │ "file.txt" ──▶ inode 42       │  ← имя живёт здесь, не в inode
 │ "link.txt" ──▶ inode 42       │  ← жёсткая ссылка: тот же inode
 └───────────────────────────────┘

Узнать номер inode для файла:

ls -i              # inode перед именем каждого файла
stat file.txt      # подробная информация, включая поле Inode

Виртуальная файловая система (VFS)

VFS (Virtual File System) — это абстракционный слой ядра Linux, который позволяет работать с разными файловыми системами через единый интерфейс. Благодаря VFS один и тот же код (open, read, write) работает одинаково для ext4, XFS, сетевых ФС (NFS, CIFS) и виртуальных ФС.

 пользователь: open() / read() / write() / stat()
               ┌─────────────────────┐
               │         VFS         │  ← единый интерфейс ядра
               │  (inode, dentry,    │     (struct file_operations)
               │   file, superblock) │
               └──────┬──────┬───────┘
                      │      │
          ┌───────────┘      └──────────────┐
          ▼                                 ▼
 ┌────────────────┐                ┌────────────────┐
 │  ext4 driver   │                │  tmpfs driver  │
 │  (реальный диск│                │  (данные в RAM)│
 │  /dev/sda1)    │                │  /dev/shm      │
 └────────┬───────┘                └────────────────┘
 ┌────────────────┐
 │  block layer   │
 │  (планировщик  │
 │   I/O, кеш)    │
 └────────┬───────┘
 ┌────────────────┐
 │  disk hardware │
 └────────────────┘

Некоторые файловые системы полностью виртуальны: они не хранят данные на реальном диске, а генерируют их динамически:

Путь Тип ФС Описание
/proc/* procfs Псевдофайлы с информацией о процессах и ядре
/sys/* sysfs Информация об устройствах и драйверах
/dev/shm tmpfs Данные хранятся в RAM (разделяемая память)
/dev/null devtmpfs Интерфейс к драйверу, физического места не занимает
/dev/zero devtmpfs Бесконечный поток нулей

Swap-файл

Swap-файл — обычный файл на диске, который ядро использует как область подкачки (swap). Страницы памяти, вытесняемые из RAM, записываются в swap и загружаются обратно по мере необходимости.

Создание swap-файла:

dd if=/dev/zero of=/swapfile bs=1M count=1024
mkswap /swapfile
swapon /swapfile

Swap-файл логически эквивалентен выделенному swap-разделу, но проще в настройке — его можно создать на уже существующей ФС без перераздела диска. Текущее состояние swap можно посмотреть командой swapon --show или через /proc/swaps.

Связанные темы

Источники

  • man 5 proc — виртуальная файловая система /proc
  • man 8 swapon — управление областями подкачки
  • man 8 tune2fs — параметры суперблока ext2/ext3/ext4
  • man 1 stat — получение метаданных файла
  • man 2 stat — системный вызов stat
  • man 7 inode — описание структуры inode в Linux