Обзор
В Linux выбор файловой системы — архитектурное решение с долгосрочными последствиями. Три основные ФС покрывают почти все сценарии: ext4 (стабильность, универсальность), XFS (высокая производительность на больших файлах), Btrfs (CoW, снэпшоты, встроенный volume management). Четвёртый игрок — ZFS (через OpenZFS) — не в mainline-ядре из-за лицензии (CDDL), но широко используется. Ещё один кандидат, bcachefs, из mainline выбыл: в 6.17 его пометили как externally maintained, а в 6.18 код вырезали из дерева ядра, оставив внешний DKMS-модуль.
LVM (Logical Volume Manager) — слой абстракции между блочным устройством и файловой системой, обеспечивающий гибкое управление пространством: ресайз, снэпшоты, thin provisioning. С Btrfs потребность в LVM уменьшается (Btrfs имеет встроенный volume management), но для ext4/XFS LVM остаётся необходимым.
В FreeBSD доминирует UFS2 + soft updates (аналог ext4 по зрелости) и ZFS (дефолт с FreeBSD 13, тесно интегрирован с ядром). Linux не имеет ZFS в ядре, поэтому Btrfs — попытка создать «Linux-native ZFS».
ext4: надёжный дефолт
Архитектура
ext4 (Fourth Extended Filesystem, 2008) — эволюционное развитие линейки ext2→ext3→ext4. Ключевые механизмы:
Extents вместо indirect block mapping. Extent — непрерывный диапазон блоков, описываемый тройкой (logical block, physical block, length). Один extent может описать до 128MB данных (при 4K блоках). Радикально сокращает количество метаданных для больших файлов и уменьшает фрагментацию по сравнению с ext3.
Journaling — журнал записывает метаданные (или метаданные + данные, в зависимости от режима) перед фактической записью. Три режима: journal (журналируются и метаданные, и данные — безопаснее, но медленнее), ordered (дефолт — данные записываются до метаданных, метаданные журналируются), writeback (только метаданные, данные могут быть не синхронизированы — быстрее, но возможна запись мусора после crash).
Delayed allocation — блоки выделяются не при write(), а при flush на диск. Позволяет аллокатору видеть полную картину и выделять непрерывные extents. Побочный эффект: при crash данные, записанные write() но не flush'нутые, могут быть потеряны — это не баг, а trade-off, но неожиданный для тех, кто привык к ext3 поведению.
Inline data — маленькие файлы хранятся прямо в inode, без выделения блоков данных: первые 60 байт помещаются в i_block, остальное уходит в область расширенных атрибутов. Фича inline_data не входит в набор по умолчанию — mke2fs включает её только по явной просьбе.
Лимиты
Максимальный размер файла: 16 TiB (с 4K блоками). Максимальный размер ФС: 1 EiB. Максимальное количество файлов: определяется при mkfs (фиксированное количество inode). Число подкаталогов в одном каталоге упирается не в HTree, а в лимит 65 000 жёстких ссылок на inode (то есть 64 998 подкаталогов), но фича dir_nlink (в ext4 с ядра 2.6.28, входит в дефолтный набор mke2fs) этот предел снимает. На практике ext4 отлично работает до десятков TB и миллионов файлов.
Практика
mkfs.ext4 -L mydata /dev/sda1
tune2fs -l /dev/sda1 # параметры ФС
tune2fs -m 1 /dev/sda1 # зарезервировано для root (дефолт 5% — много для больших дисков)
tune2fs -c 0 -i 0 /dev/sda1 # отключить периодические fsck
e2fsck -f /dev/sda1 # проверка (unmounted!)
resize2fs /dev/sda1 # ресайз (grow online, shrink offline)
XFS: производительность на масштабе
Архитектура
XFS (SGI, 1994, в Linux с 2001) — 64-bit journaling ФС, спроектированная для параллельного I/O и больших файлов. Дефолт в RHEL 7+.
Allocation Groups (AG) — XFS разделяет ФС на независимые AG (аналогия: шардирование). Каждая AG имеет свои B+-деревья для свободного пространства, inode, extents. Это позволяет параллельные аллокации из разных AG на разных CPU — ключевое преимущество на multi-core серверах с высоким параллелизмом I/O.
B+-деревья повсюду. Свободное пространство, inode, extents, directory entries — всё хранится в B+-деревьях. Это обеспечивает O(log n) для операций и предсказуемую производительность при росте объёма.
Delayed allocation + extent-based — как в ext4, но реализация зрелее для больших файлов.
Metadata journaling only — XFS журналирует только метаданные (нет аналога ext4 data=journal). Для данных полагается на ordered writes и write barriers.
Особенности
Полноценного shrink у XFS нет. xfs_growfs -D умеет отрезать только свободный хвост последней allocation group, и ядро помечает эту операцию как экспериментальную; удаление целых AG не реализовано (в коде growfs на этот случай стоит TODO и возврат -EINVAL), а ужать ФС до одной AG нельзя вовсе. Причина фундаментальна: выкинуть AG из конца ФС означало бы миграцию всех её данных. На практике — при использовании с LVM планируйте размеры заранее.
XFS не допускает удаление журнала или его отключение. Гарантия целостности метаданных — всегда.
Reflinks (mkfs.xfs включает их по умолчанию с xfsprogs 5.1, июль 2019) — lightweight копирование файлов (cp --reflink), как в Btrfs. Блоки данных shared между файлами до момента модификации (CoW-семантика для отдельных файлов).
mkfs.xfs -L mydata /dev/sda1
xfs_info /dev/sda1 # параметры ФС
xfs_growfs /mount/point # grow (online)
xfs_repair /dev/sda1 # repair (unmounted)
xfs_fsr /mount/point # дефрагментация (online)
Btrfs: CoW и встроенный volume management
Архитектура
Btrfs (B-tree FS, Oracle, 2007, стабильные core features с ~2020) — Copy-on-Write ФС с integrated volume management. Дефолт в Fedora (с 33), openSUSE.
Copy-on-Write. Btrfs никогда не перезаписывает данные на месте. Каждая запись создаёт новые блоки, старые освобождаются позже. Следствия: атомарные обновления (crash safety — старые данные валидны до завершения новой записи), но write amplification (одна логическая запись может породить каскад обновлений B-дерева).
Субтома (subvolumes) — лёгкие «разделы» внутри одной ФС. Каждый субтом может быть смонтирован отдельно, иметь свои mount options. Типичная схема: @rootfs и @home как субтома — позволяет делать снэпшоты системы независимо от home.
Снэпшоты — мгновенные read-only или read-write копии субтома. Снэпшот — не копирование данных, а создание нового корня B-дерева, указывающего на те же блоки. Стоимость: O(1), независимо от объёма данных. При модификации данных CoW создаёт новые блоки только для изменённого.
Checksumming — CRC32C (дефолт) или xxhash/sha256/blake2 для данных и метаданных. Обнаруживает silent data corruption (bit rot), которую ext4/XFS не замечают.
Встроенный multi-device management — Btrfs может управлять несколькими дисками: RAID0, RAID1, RAID10 (стабильны), RAID5/6 (нестабильны — write hole, не рекомендуется для production). Заменяет mdadm + LVM для простых сценариев.
Transparent compression — zstd (рекомендуемый), zlib, lzo. Включается per-mount или per-file: mount -o compress=zstd.
send/receive — инкрементальная передача различий между снэпшотами. Основа для backup-решений (btrbk, snapper).
Практика
mkfs.btrfs -L mydata /dev/sda1
# Субтома
btrfs subvolume create /mnt/@rootfs
btrfs subvolume create /mnt/@home
btrfs subvolume list /mnt/
# Снэпшоты
btrfs subvolume snapshot /mnt/@rootfs /mnt/@rootfs-snap-20250225
btrfs subvolume snapshot -r /mnt/@rootfs /mnt/@rootfs-backup # read-only
# Инкрементальный бэкап
btrfs send /mnt/@rootfs-backup | btrfs receive /backup/
# Информация
btrfs filesystem show
btrfs filesystem df /mnt/ # использование по data/metadata/system
btrfs device stats /mnt/ # ошибки I/O и checksums
btrfs scrub start /mnt/ # проверка целостности (online)
btrfs balance start /mnt/ # ребалансировка данных между chunk'ами
Gotchas
CoW и базы данных. Random small writes в CoW-ФС порождают write amplification и фрагментацию. Для файлов БД (PostgreSQL data dir, MySQL/InnoDB tablespaces) рекомендуется: chattr +C /var/lib/postgresql/ (отключение CoW для directory — новые файлы создаются с NOCOW). Альтернатива — отдельный субтом с nodatacow.
Свободное место. df на Btrfs может показывать неточные данные: CoW, снэпшоты и metadata overhead усложняют учёт. btrfs filesystem usage /mnt/ — более точная команда. Переполнение metadata-пространства (при достаточном data-пространстве) — известная проблема, требующая btrfs balance.
RAID5/6 — write hole проблема не решена. В официальной таблице статусов btrfs (срез по ядру 7.2) профиль RAID56 по-прежнему единственный с пометкой unstable, а mkfs.btrfs(8) предупреждает об этом прямо при создании ФС. Не использовать в production.
LVM: Logical Volume Manager
Архитектура
LVM — слой абстракции между физическими дисками и файловыми системами. Три уровня: PV (Physical Volume) — физический диск или раздел с LVM-метаданными. VG (Volume Group) — пул пространства из одного или нескольких PV. LV (Logical Volume) — виртуальный блочный раздел, вырезанный из VG, на котором создаётся ФС.
Disk 1 [PV] ──┐
├── Volume Group "vg0" ──┬── LV "root" (ext4, 50G)
Disk 2 [PV] ──┘ ├── LV "home" (xfs, 200G)
└── LV "data" (xfs, free space)
Ключевые возможности
Online resize — lvextend -L +50G /dev/vg0/home && xfs_growfs /home (или resize2fs для ext4). Сокращение (lvreduce) — только для ext4 (offline), XFS не умеет shrink.
Snapshots (classic) — CoW-снэпшот LV. При создании snapshot-LV выделяется пространство для COW. Оригинал продолжает работать; при модификации исходные блоки копируются в snapshot перед перезаписью. Ограничение: performance penalty при активном snapshot (каждая запись → дополнительное чтение + запись), пространство snapshot конечно (при переполнении snapshot инвалидируется).
Thin provisioning — тонкие тома, выделяющие пространство по мере записи. thin pool — фактическое хранилище, thin LV — виртуальные тома, сумма которых может превышать физическое пространство (overcommit). Thin snapshots эффективнее classic — нет COW penalty для оригинала.
Striping / Mirroring — LVM может stripe данные через несколько PV (аналог RAID0) или mirror (RAID1). На практике чаще используют mdadm для RAID и LVM поверх.
# Создание
pvcreate /dev/sda1 /dev/sdb1
vgcreate vg0 /dev/sda1 /dev/sdb1
lvcreate -L 100G -n data vg0
mkfs.ext4 /dev/vg0/data
# Расширение
lvextend -L +50G /dev/vg0/data
resize2fs /dev/vg0/data # или xfs_growfs для XFS
# Снэпшот
lvcreate -s -L 10G -n data-snap /dev/vg0/data # classic snapshot
mount /dev/vg0/data-snap /mnt/snap
# Thin provisioning
lvcreate --type thin-pool -L 500G -n thinpool vg0
lvcreate --thin -V 200G -n vm1 vg0/thinpool
lvcreate --thin -V 200G -n vm2 vg0/thinpool # overcommit: 400G из 500G pool
# Информация
pvs; vgs; lvs # краткий вывод
pvdisplay; vgdisplay; lvdisplay # подробный
Когда что использовать
ext4 — дефолт для десктопов, серверов, виртуальных машин, контейнеров. Лучший выбор когда нужна максимальная стабильность, зрелый fsck, предсказуемая производительность. Используйте с LVM если нужны гибкие разделы.
XFS — серверы с тяжёлым I/O, большие файлы (VM images, media, backup storage), базы данных с последовательным I/O (analytics, OLAP). RHEL дефолт. Используйте с LVM (помните: no shrink).
Btrfs — рабочие станции и серверы, где критичны снэпшоты (rollback после обновлений — snapper в openSUSE), бэкап через send/receive, компрессия. Fedora/openSUSE дефолт. Не нужен LVM (встроенный volume management). Осторожно с БД (disable CoW) и не используйте RAID5/6.
LVM + ext4/XFS — enterprise standard, когда нужен гибкий volume management без смены ФС. Thin provisioning для виртуализации.
Btrfs вместо LVM — на single-disk или RAID1 системах Btrfs субтома заменяют LVM LV, снэпшоты Btrfs заменяют LVM snapshots (и работают лучше — нет COW penalty).
Нюансы и trade-off'ы
Journaling vs CoW crash safety. Ext4/XFS: журнал защищает метаданные, но данные записанные незадолго до crash могут быть потеряны или содержать мусор (в writeback mode). Btrfs: CoW гарантирует, что на диске всегда консистентное состояние — либо старые данные, либо полностью новые. Btrfs не нуждается в fsck после crash (в теории). На практике btrfs check менее зрелый, чем e2fsck.
Checksumming trade-off. Ext4/XFS не проверяют целостность данных (только метаданные через журнал). Silent bit rot обнаруживается только при чтении повреждённого файла и обычно не исправляется. Btrfs/ZFS проверяют контрольные суммы при каждом чтении. С RAID1: обнаруживают ошибку и восстанавливают с исправной копии (self-healing). Стоимость: CPU overhead (CRC32C ~1%, sha256 заметно больше) и дополнительные метаданные.
Write amplification в Btrfs. CoW + B-tree означает, что модификация одного блока данных может вызвать каскадное обновление дерева до корня. На практике от 1.1x до 4.2x amplification в зависимости от паттерна доступа. На SSD это влияет на wear и IOPS; на HDD — на throughput.
ext4 inode count fixed at mkfs. Количество inode определяется при создании ФС (bytes-per-inode ratio). Если закончатся inode — нельзя создавать файлы, даже если есть свободное место. Btrfs и XFS создают inode динамически.
dm-verity и integrity. Для immutable root ФС (ChromeOS, Android, Fedora CoreOS) используется dm-verity — device-mapper target, проверяющий целостность блоков по Merkle tree. Не файловая система, а слой под ней. Аналог в FreeBSD — GELI verified boot.
Сравнение с FreeBSD
UFS2 + soft updates. UFS2 — дефолтная ФС FreeBSD (аналог ext4). Soft updates — альтернатива журналированию: упорядочивание метаданных-операций так, чтобы на диске всегда было консистентное состояние. Soft updates + journaling (SUJ, с FreeBSD 9) — гибрид, добавляющий journal для ускорения fsck. UFS2 зрелая и стабильная, но уступает ext4 по производительности и не имеет extents.
ZFS в FreeBSD. ZFS — дефолт с FreeBSD 13, тесно интегрирован с ядром (в отличие от Linux, где OpenZFS — out-of-tree модуль). ZFS предоставляет: CoW, checksumming, снэпшоты, клоны, дедупликация, компрессия, RAID-Z (1/2/3), встроенный volume management (zpools, datasets). По функциональности ZFS > Btrfs, но Btrfs — in-kernel и не имеет лицензионных проблем.
GEOM. FreeBSD GEOM — модульный framework для трансформации блочных устройств: шифрование (geli), зеркалирование (gmirror), striping (gstripe), journaling (gjournal). В Linux аналог — device-mapper (dm-crypt, dm-raid, dm-thin, dm-verity), на котором построен LVM.
Boot environments. ZFS в FreeBSD (и Btrfs в Linux с grub-btrfs/snapper) позволяют создавать boot environments — снэпшоты корневой ФС, загружаемые из bootloader. Неудачное обновление → выбрать предыдущий снэпшот в GRUB → система восстановлена. openSUSE с snapper делает это автоматически. FreeBSD bectl — штатный инструмент для управления boot environments.
Источники
- ext4 — kernel.org — документация ядра
- XFS — kernel.org — документация ядра
- Btrfs — kernel.org — документация ядра
- Btrfs Wiki — официальная wiki
- LVM — Red Hat — руководство по LVM
- Btrfs vs ext4 vs XFS — Phoronix — бенчмарки
- BfFS: Billion-files comparison — масштабное сравнение ФС
- Btrfs gotchas — ArchWiki — практическое руководство
- snapper — инструмент управления снэпшотами (Btrfs/LVM)
- FreeBSD Handbook: File Systems — ZFS в FreeBSD
Связанные заметки
- Linux — обновление и управление загрузкой — snapshot-откаты на Btrfs и LVM
- Linux — справочник команд: файловые системы и хранение — диагностика I/O и состояния накопителей
- FreeBSD — ZFS — пулы, датасеты и boot environments, для сравнения
- Linux — сводный cheatsheet — быстрая справка по mount, lsblk и LVM
- SATA, SAS и NVMe — интерфейсы, по которым эти файловые системы добираются до накопителя
- Резервное копирование: стратегия и проверка восстановления — почему снепшот Btrfs или LVM не заменяет бэкап
- Восстановление незагружающейся системы — fsck, резервный суперблок ext4 и почему
xfs_repair -L— последнее средство
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.