Файловые системы Linux¶
ext4¶
Дефолт большинства дистрибутивов (проверенная временем) + Журналируемая
- Стабильность, отличная поддержка инструментов (
e2fsck,tune2fs,resize2fs), быстрый fsck, журнал, extents, delayed allocation. - Нет CoW, нет нативных снапшотов, нет компрессии, нет встроенной защиты от bitrot (checksums только
для метаданных; для данных — с ядра 5.4 через
data_checksum, но фича experimental). - Фишки: до 1 EiB, до 16 TiB на файл,
tune2fs -O fast_commitускоряет fsync,chattr +Cдля отключения журналирования на горячих файлах.
Архитектура: block groups + журнал¶
ext4 — прямая эволюция ext3/ext2. Диск нарезан на block groups фиксированного размера (обычно 128 MiB), каждая содержит свой кусок bitmap свободных блоков, таблицу inode и данные. Это даёт локальность: файл и его метаданные стараются жить в одной группе — короткий seek на HDD.
Поверх — журнал (JBD2). По умолчанию режим data=ordered: в журнал пишутся только метаданные, но
данные принудительно сбрасываются на диск ДО коммита метаданных. Это компромисс между скоростью
(data=writeback) и надёжностью (data=journal, где журналятся и данные тоже — медленно, зато
выживает любой crash).
Extents (с ext4) вместо block maps ext3: один extent описывает непрерывный диапазон блоков одной записью. Большие файлы хранятся компактно в дереве extent'ов, поиск блока — O(log n).
Delayed allocation: ext4 не выбирает физические блоки сразу при write(), а копит изменения в
памяти и аллоцирует пачкой при fsync/flush. Меньше фрагментации, лучше throughput. Обратная сторона
— при питании-в-розетку терялись свежие файлы (знаменитый bug 2009 года в Ubuntu); закрыто через
auto_da_alloc, но осадочек остался.
Следствия¶
- Журнал — это не CoW. Запись блока перезаписывает его на месте; в случае crash журнал даёт «откат к консистентному состоянию», а не «атомарную транзакцию для пользователя».
- Никаких снапшотов: нет дерева версий, есть один актуальный набор inode.
- fsck быстрый и предсказуемый — чинит конкретные структуры (bitmap, inode-таблицы, журнал), а не «перестраивает всё из CoW-дерева».
Хорошо¶
- Зрелость. ext4 в проде с 2008, ext3 — с 2001. Самая обкатанная ФС в Linux. Поведение под любой
нагрузкой задокументировано, у любого админа есть мускульная память на
e2fsck/tune2fs/dumpe2fs. - Предсказуемая производительность. Нет CoW-фрагментации, нет «внезапного balance», нет sudden ENOSPC. На HDD + БД с random write ext4 часто обгоняет Btrfs/ZFS без тюнинга.
- Лучший fsck в мире.
e2fsckчинит почти всё, что не уничтожено физически: повреждённый суперблок (есть backup superblocks:mke2fs -nпокажет offsets), сломанные inode, поломанные директории. Время fsck растёт с числом inode, но в разы быстрееxfs_repair. - Resize в обе стороны.
resize2fsумеет и расширить (online), и сжать (offline, после umount). Редкая фича — XFS не умеет shrink, ZFS тоже. - Шифрование на уровне ФС.
fscrypt— per-directory encryption (как в Android/ChromeOS). Не требует LUKS, можно шифровать только/homeили конкретные подпапки. - Прогноз: будет работать всегда. ext4 не зависит от модной фичи года или конфликта мейнтейнеров. Даже когда bcachefs выпилят из ядра, ext4 останется.
Плохо¶
- Нет CoW — нет снапшотов, нет атомарных переключений версий конфига/контейнера. Хочешь снапшот — лезь в LVM thin снизу.
- Нет checksums данных. Если диск молча испортит блок (bitrot), ext4 этого не заметит — отдаст битый блок приложению. На enterprise SSD/HDD с end-to-end protection это менее остро, на consumer-железе с большими объёмами — реальный риск.
- Нет компрессии. Логи, дампы, текстовые данные занимают полный размер. Лечится только на уровне приложения (gzip/zstd на pipeline'е).
- Нет нативного multi-device. ext4 живёт на одном блочном устройстве. Нужен RAID —
mdraidснизу, нужен пул дисков — LVM. Стек получается многоэтажный. - Фрагментация на долгоживущих директориях с миллионами мелких файлов. Не катастрофа, но
e4defragсуществует не просто так. - Inode-таблица фиксирована при mkfs.
mkfs.ext4 -Nили-iзадают число inode. Если упёрся — единственный путь mkfs заново. На FS с миллионами мелких файлов (mail spool) это реальная проблема. XFS и Btrfs аллоцируют inode динамически.
Грабли¶
- Inode exhaustion при свободном месте.
df -iпоказывает 100% used,df— 30%. Лечения «на лету» нет, только mkfs. data=writebackтеряет данные при crash, но включают «для скорости» — потом удивляются.- fsck требует umount: для корня — single-user или
fsck.mode=forceчерез initramfs. resize2fsshrink требуетe2fsckсначала, сжимать можно только до объёма используемых данных.- Discard/TRIM: монтировать с
discardзамедляет delete на SSD; правильнееfstrimпо cron/таймеру systemd.
XFS¶
Дефолт в RHEL/Rocky/Alma. Заточена под крупные файлы и параллелизм.
- Отличный throughput на больших файлах и многопоточной нагрузке (allocation groups), online defrag
(
xfs_fsr), reflinks (CoW-копии файлов), DAX, real-time subvolume. - Раньше нельзя было уменьшать (shrink) — до сих пор нельзя. Тяжелее ext4 на мелких файлах. fsck требует много памяти.
- Фишки:
xfs_io -c "reflink"— мгновенные CoW-копии, идеально для контейнерных образов и снапшотов БД.
Архитектура: allocation groups + B+ деревья + журнал¶
XFS родилась в Silicon Graphics (IRIX, 1993) для видеомонтажа и научных вычислений — то есть для очень больших файлов и многотерабайтных томов на multi-CPU машинах. Это вся ДНК ФС.
Диск делится на Allocation Groups (AG) — обычно 4 и более, каждая со своими структурами учёта (free space btree по offset и по size, inode btree, reverse-mapping btree с v5). AG — это не block group ext4: каждая AG работает почти независимо, со своим локом, поэтому параллельные write'ы в разные файлы идут параллельно в разные AG без contention. Отсюда легендарный scalability на NUMA-машинах.
Inode аллоцируются динамически — нет глобальной таблицы как в ext4. Сколько надо мелких файлов — столько inode. Лимит — свободное место.
Всё внутри — B+ деревья. Свободные блоки, экстенты файлов, inode, директории, ACL, reverse-map. Поэтому XFS отлично масштабируется на 100M+ файлов в директории, на терабайтные файлы, на тысячи параллельных потоков. ext4 на таком захлёбывается.
Журнал — metadata-only (как ext4 data=ordered, своего data=journal-режима нет). По умолчанию
internal (на том же AG-0), можно вынести на отдельное устройство (-l logdev=) — пишут на NVRAM или
быстрый SSD в HPC-конфигурациях.
Delayed allocation, speculative preallocation (XFS заранее резервирует чуть больше места при росте файла, чтобы избежать фрагментации), extent hint'ы.
Версия v5 on-disk format (с 2014, дефолт с RHEL 7.3): CRC32 на ВСЕ метаданные, reverse-mapping (rmapbt) для self-healing, reflinks. Старые v4 в RHEL 9 deprecated.
Следствия¶
- На больших файлах и параллельной нагрузке (БД, Kafka, MinIO, видеостриминг, HPC) XFS почти всегда быстрее ext4 и предсказуемее Btrfs.
- На массе мелких файлов (mail, мелкие конфиги, исходники) ext4 чуть шустрее из-за более компактных директорий и меньшего overhead AG.
- Журнал не защищает данные, только метаданные. После crash файл может быть «частично записан» с
дырой нулей. fsync делает то, что должен; mount option
sync— для параноиков. - Shrink невозможен в принципе. AG-структуры аллоцированы по всему тому, переехать не могут. Это by design, не «не успели реализовать».
Хорошо¶
- Производительность на больших и параллельных нагрузках. Confluent рекомендует XFS для Kafka. MinIO — официально XFS only для прода (на других ФС работает, но не саппортится). EDB/AWS RDS советуют XFS для Postgres. Рекомендации не из вежливости.
- Reflinks (с v5).
cp --reflink,xfs_io -c "reflink"— мгновенное CoW-копирование файла. Поверх Postgres даётpg_basebackup --reflink(PG16+), поверх контейнеров — overlayfs-style сборка образов. Это «полу-снапшоты»: не subvolume, но отдельные файлы делить блоки умеют. - Online grow.
xfs_growfsрасширяет ФС без размонтирования. Стандартный сценарий «lvextend+xfs_growfs» отработан до автоматизма. - Online defrag.
xfs_fsrперебирает файлы по фрагментации и переписывает их компактно, не останавливая нагрузку. У ext4e4defragтоже есть, ноxfs_fsrстарше и стабильнее. - Reverse-mapping (rmapbt) с v5. Когда диск сообщает «бэд-сектор LBA X», rmapbt мгновенно
отвечает «это файл
/var/log/foo, offset 4 MiB» — без обхода всей ФС. - Quotas — нормальные, без btrfs-style тормозов. Project quotas (по дереву директорий, не только по uid/gid) — фича XFS, которой нет в ext4.
- DAX. На persistent memory (Optane и подобные) XFS умеет direct access без page cache — read/write идут прямо в NVDIMM. Очень узкая ниша, но единственная нормально работающая.
Плохо¶
- Shrink невозможен. Захотел уменьшить ФС — только бэкап + mkfs + restore. Главная причина, по которой ext4 всё ещё используют для root.
- Не любит memory pressure при fsck.
xfs_repairзагружает в RAM структуры всей ФС; на больших томах (десятки TiB) может потребоваться 16–64 GiB RAM. Можно-m maxmemили-o bhash=N, но если памяти физически нет — fsck не сделать. - Удаление миллионов мелких файлов медленнее ext4. Транзакции в журнале XFS «тяжелее» из-за B+ деревьев и rmapbt.
- Метаданные журналируются, данные — нет. После crash без fsync файл может оказаться обнулённым
(zero-length). Это известно и стандартно (POSIX так и говорит), но первый раз пугает. Лечение —
приложение должно делать fsync перед
rename(). - Нет нативного multi-device, нет нативного RAID. Снизу всегда LVM/mdraid. Свои снапшоты XFS не делает, только reflinks по файлам.
- Дефолтные mount options консервативные. Для прода обычно крутят:
noatime,logbsize=256k,allocsize=64k(под БД — наоборот,allocsize=1mи больше),inode64(давно дефолт, но проверь на legacy).
Грабли¶
xfs_growfsработает только в сторону роста. Никакихxfs_shrinkне существует и не будет.xfs_repairвне initramfs не запустится для root — нужно single-user/rescue или rebuild.- v4 → v5 апгрейда нет. Только
mkfs.xfsи restore. xfs_quota -xтребует mount с-o uquota/gquota/pquota; включить на смонтированной ФС нельзя — нужен remount/umount.allocsizeслишком большой = «дыры» на маленьких файлах и потеря места до flush. Слишком маленький = фрагментация на растущих логах.
Btrfs¶
Дефолт в openSUSE, Fedora Workstation. Современная CoW ФС.
- Снапшоты, subvolumes, встроенная компрессия (zstd/lzo/zlib), checksums данных и метаданных,
send/receive для инкрементальной репликации, online balance, RAID 0/1/10, dedupe (offline),
chattr +Cдля nodatacow на БД-файлах. - RAID 5/6 до сих пор помечен как unstable (write hole). Производительность падает на сильно фрагментированных workloads (БД, VM-образы) без nodatacow. Историческая репутация хрупкости (хотя за последние годы — заметно стабильнее).
- Фишки:
btrfs subvolume snapshotза миллисекунды,compress=zstd:3бесплатно режет I/O на текстовых данных, Snapper/Timeshift из коробки.
Архитектура: B-tree + CoW¶
Copy-on-Write (CoW) — фундамент. При изменении блока:
- Новый блок пишется в свободное место.
- Указатель в дереве обновляется (тоже через CoW — родительский узел перезаписывается на новом месте).
- Так вверх до корня дерева.
- Корень дерева коммитится атомарно (через superblock update).
Следствия¶
- Никаких partial writes. Либо транзакция целиком, либо её нет. Журнал в классическом смысле (как ext4) не нужен.
- Снапшоты бесплатны — это просто новая ссылка на корень subvolume.
- Фрагментация — обратная сторона. Случайные записи в большой файл разлетаются по диску.
Хорошо¶
- Снапшоты + send/receive.
btrfs send -p prev current | ssh backup btrfs receive /backup— инкрементальная репликация на уровне ФС, без rsync-сканирования. Убийственная фича для бэкапов. - Прозрачная компрессия.
compress=zstd:3в mount options.zstd:1почти бесплатен по CPU, на текстах/логах/исходниках экономит 50–70%. Для бинарей/уже сжатых данных Btrfs сам понимает, что жать бесполезно (heuristic), и пропускает. - Reflinks.
cp --reflink=always— мгновенная CoW-копия. Полезно для VM-образов (golden image → клон за миллисекунды), бэкапов, dev-окружений. - Checksums данных и метаданных (crc32c по умолчанию, можно xxhash/sha256/blake2). На multi-device при scrub автоматически чинятся через копию-зеркало. Защита от bitrot — то, чего нет в ext4/XFS.
- Online всё. Resize (вверх и вниз!), balance (перераспределение чанков), defrag, добавление/удаление устройств — без размонтирования. XFS shrink, кстати, до сих пор невозможен.
- Гибкие RAID-профили на уровне чанков, меняются на ходу:
btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt. - Quotas через qgroups, по subvolume. Но: исторически глючные и тормозящие при больших объёмах. С simple quotas (kernel 6.7+) стало лучше.
Плохо¶
- RAID 5/6 — broken by design до сих пор. Write hole не закрыта. На вики Btrfs прямым текстом: «unstable, do not use for valuable data». Для parity-RAID — ZFS или mdraid под Btrfs.
- Производительность на БД-workload. Без nodatacow (
+C) фрагментация съедает throughput. С+C— нет checksums, нет компрессии. Так себе trade-off для prod-БД. ZFS на таком же сценарии ведёт себя лучше (recordsize tuning). - Quota groups + большие FS = тормоза. Включённые qgroups могут заметно замедлять
btrfs balanceи удаление снапшотов. - ENOSPC-сюрпризы. Btrfs может сказать «нет места» при свободных гигабайтах, потому что чанки
уже выделены под data, а metadata некуда. Лечится
btrfs balance start -dusage=50. Современные ядра справляются лучше, но артефакт остался. - Восстановление после катастрофы.
btrfs check --repair— last resort, может сделать хуже. Best practice — бэкапы иbtrfs restoreдля вытаскивания данных. У ext4e2fsckв этом плане куда дружелюбнее. - Metadata-heavy операции (
rm -rfогромного дерева,find /) медленнее ext4/XFS. CoW + множественные деревья дают оверхед.
Грабли¶
- ENOSPC при свободном месте. Btrfs аллоцирует диск чанками (1 GiB для data, 256 MiB для metadata). Если все чанки расписаны под data, а metadata-чанк заполнился — записать новый файл некуда: для него нужна запись в metadata-tree.
dfврёт, и это by design. Используйbtrfs filesystem usage/btrfs filesystem df.- Снапшоты — не бесплатны в долгую. Старые снапшоты держат старые блоки, free space постепенно тает.
- Quota groups (qgroups) — исторический ад. До simple quotas (6.7+) — best effort стратегия «не включать».
- Восстановление после повреждения — стресс. План — бэкапы +
btrfs restore, неbtrfs check --repair. - Поведение под нехваткой памяти. На тесных по RAM системах CoW + B-tree commit'ы могут вести себя непредсказуемо.
ZFS¶
Порт из Solaris, лицензия CDDL (поэтому не в mainline kernel).
- Всё что у Btrfs + рабочий RAID-Z1/2/3, ARC/L2ARC (кэш в RAM + SSD), ZIL/SLOG, native encryption, send/receive, дедупликация (но прожорливая по RAM), снапшоты с zero overhead.
- Лицензионная несовместимость с GPL — ставится через DKMS, ломается при обновлении ядра. Прожорлив по RAM (~1 GiB на 1 TiB при включённой dedupe — больше). Vdev нельзя расширить добавлением одного диска (хотя RAID-Z expansion появился в 2.3, 2024).
- Фишки: «правильный» enterprise-grade, считается золотым стандартом для NAS/storage. TrueNAS, Proxmox, Ubuntu offer root-on-ZFS.
Архитектура: pool → vdev → dataset, CoW + Merkle-tree¶
ZFS — это не «ФС», а интегрированный stack: volume manager (как LVM) + RAID (как mdraid) + filesystem в одном. Layering нет принципиально: пул знает про диски, ФС знает про блоки, всё видит друг друга и принимает решения вместе.
Структура снизу вверх:
- Физические диски объединяются в vdev (virtual device): mirror, raidz1/2/3, draid, single. Vdev — это unit of redundancy.
- Несколько vdev объединяются в zpool. Запись страйпится по всем vdev пула (как RAID-0 поверх RAID-Z). Добавление vdev в пул расширяет ёмкость без перестройки.
- Внутри пула создаются datasets — либо файловые системы (ZFS-FS, монтируются как любая ФС), либо zvol (блочные устройства для iSCSI/VM-дисков).
- Снапшоты и клоны — на уровне dataset. send/receive — между dataset'ами.
Запись — CoW + transaction groups (TXG). Изменения копятся в RAM (open TXG), раз в несколько секунд
(txg_timeout, по умолчанию 5s) коммитятся атомарно: новые блоки записаны, uberblock (корень)
обновлён в одном из 128 ring-slot'ов. До коммита sync write'ы идут в ZIL (ZFS Intent Log) —
отдельный лог для durability fsync().
Merkle-tree: каждый блок ссылается на дочерние через указатель + checksum. Поэтому ZFS обнаруживает silent corruption на любом уровне — от данных до метаданных до uberblock.
ARC (Adaptive Replacement Cache) — кэш в RAM, умнее Linux page cache: учитывает и recency, и frequency, не вымывается одним sequential scan'ом. L2ARC — расширение ARC на SSD. SLOG — отдельное устройство для ZIL (NVMe/Optane), ускоряет fsync-нагрузки.
Следствия¶
- Storage stack единый, без зазоров. mdraid не знает что выше ФС, ФС не знает что снизу RAID — отсюда write hole в RAID-5. ZFS знает всё. Поэтому RAID-Z не имеет write hole: parity и data пишутся в одной транзакции, либо обе, либо ни одной.
- Снапшоты бесплатны и мгновенны. Это просто ссылка на старый uberblock; пока новые блоки CoW-копируются, старые не удаляются.
- send/receive передаёт diff между двумя снапшотами потоком. Инкрементальный бэкап на удалённый pool — одна команда, без rsync-сканирования.
- Память — лекарство и яд. ARC по умолчанию забирает до 50% RAM (на FreeBSD — больше). На сервере с
8 GiB и нагруженным Postgres это конкуренция между ARC и shared_buffers; нужно крутить
zfs_arc_max.
Хорошо¶
- Надёжный parity-RAID. RAID-Z1/2/3 (1/2/3 диска под parity), draid (для очень больших массивов с distributed spare), mirror. В отличие от Btrfs RAID-5/6, write hole закрыта by design. Причина, по которой ZFS — стандарт для NAS/архивных хранилищ.
- Send/receive с шифрованием.
zfs send -wотправляет уже зашифрованные блоки без расшифровки на отправляющей стороне — приёмник не видит ключи. Идеальный off-site backup на untrusted машину. - Native encryption per-dataset.
zfs create -o encryption=on -o keyformat=passphrase. Ключи можно хранить в файле/KMS, загружать lazy при первом доступе. - ARC. На read-heavy нагрузке ARC бьёт Linux page cache: за счёт adaptive replacement не
вымывается sequential I/O (одного
find /достаточно, чтобы page cache забыл всё нужное; ARC — нет). - Recordsize per-dataset. Для Postgres ставят 8K (= размер страницы), для Kafka сегментов — 1M, для логов/архивов — 1M с компрессией. Редкий уровень контроля.
- Compression by default.
lz4включают почти всегда — почти бесплатен по CPU, на текстах сильно экономит I/O.zstd-3/9— для архивных dataset'ов. - Scrub. Раз в неделю/месяц обходит весь пул, проверяет checksums, чинит из mirror/parity. Bitrot обнаруживается ДО того, как ты захочешь прочитать файл.
- Снапшоты + холды.
zfs holdпредотвращает удаление снапшота, пока он удерживается (например, идёт send). Никаких «удалил снапшот пока шёл бэкап». - Self-healing. Прочитал блок с диска — checksum не сошёлся — взял с зеркала/parity, отдал приложению, переписал плохой блок. Прозрачно для приложения.
- zvol для VM-дисков. Снапшот, клон, send/receive — поверх обычного блочного устройства. Альтернатива qcow2 + LVM thin.
Плохо¶
- Лицензия CDDL. Несовместима с GPL2 ядра Linux — поэтому ZFS не может попасть в mainline. Распространяется как out-of-tree модуль (OpenZFS) через DKMS. При апгрейде ядра модуль пересобирается; если новое ядро ломает API (а это случается раз в 2–3 релиза мажоров) — апгрейд откладывается на 2–8 недель, пока выйдет новый OpenZFS.
- Прожорлив по RAM. ARC на 50% RAM по умолчанию — не баг, by design. На 4–8 GiB машинах ZFS уже неуютно. С dedup совсем плохо: dedup-таблица сидит в ARC, ~5 GiB RAM на 1 TiB уникальных данных. Поэтому dedup в ZFS выключают чаще, чем включают.
- Vdev неэластичный. Долго (до 2024) единственный способ расширить пул — добавить новый vdev (то есть ещё одну группу дисков). RAID-Z expansion (добавление одного диска в существующий vdev) появилось в OpenZFS 2.3 в 2024 — фича сырая, восстанавливается медленно, не убирает старый stripe-pattern.
- Нельзя удалить vdev. Mirror убрать можно, top-level vdev — только если пул mirror-only (
zpool remove). Для raidz remove не поддерживается. Ошибся на mkfs — пересоздавать пул. - Поведение под memory pressure хуже, чем у нативных ФС ядра. ARC долго отдаёт память обратно kernel'у, OOM-killer может пристрелить процесс, который мог бы и пожить.
- Setup сложнее. Установить ZFS на root в Ubuntu — отдельный квест с initramfs и
zfs-mount.service. Любая Linux-распределённость, кроме TrueNAS/Proxmox/Ubuntu, — это «соберите сами». - Не любит overcommit. zvol с volsize больше, чем свободно в пуле, можно создать через sparse — но при заполнении гость отвалится без warning. У ext4/XFS поверх LVM thin — то же самое, просто там это привычнее.
- fsync дорогой без SLOG. Sync write идёт в ZIL (фактически — двойная запись), пока не закоммитится TXG. На обычных SSD терпимо, на HDD без SLOG — катастрофа для Postgres.
Грабли¶
zpool importпосле reboot может потребовать-f, если pool был «not cleanly exported». Стандартная история на нештатном shutdown.- Снапшот zvol съедает место — даже без записей, потому что любая запись в активную копию начинает плодить CoW-копии старых блоков.
- dedup включил → выключить нельзя. Только пересоздание пула.
zfs set dedup=offотключает ТОЛЬКО для НОВЫХ записей; старые dedup-blocks остаются и сидят в DDT. ashiftзадаётся при создании vdev и не меняется. Поставил 9 (512b) на диск с 4K-сектором — потерял производительность навсегда. Стандарт сегодня —ashift=12.- ARC на сервере с БД — крутить
zfs_arc_max(/etc/modprobe.d/zfs.conf:options zfs zfs_arc_max=8589934592для 8 GiB). - send/receive обрывается → recv state остаётся, надо
zfs receive -Aдля abort. - Перевод pool на новую версию OpenZFS — односторонний.
zpool upgradeсделал → на старой версии этот pool уже не импортируешь.
bcachefs¶
В mainline с ядра 6.7 (2024). Молодая, но амбициозная.
- CoW, checksums, компрессия, шифрование, многоуровневое хранилище (tiered storage: NVMe + HDD в одном пуле с автоматической миграцией), erasure coding, replicas.
- Сырая, в проде использовать рано. Конфликты автора (Kent Overstreet) с Линусом — будущее в mainline под вопросом.
- Фишка: настоящий tiered storage без сторонних инструментов (типа bcache+LVM).
Архитектура: эволюция из bcache, B-tree + CoW¶
bcachefs выросла из bcache — block-level кэша SSD-перед-HDD, который Kent Overstreet вёл с 2010. К 2015 стало ясно, что инфраструктура bcache (CoW B-tree, журнал, allocator) достаточно мощная, чтобы стать полноценной ФС — так появилась bcachefs. В mainline принята с 6.7 (январь 2024), статус experimental.
Цель — собрать в одной ФС всё лучшее: надёжность ZFS, фичи Btrfs, скорость ext4/XFS. И tiered storage из bcache как killer feature.
Внутри — CoW B-tree (как Btrfs), но дерево одно глобальное (а не лес как у Btrfs), что упрощает целостность и снижает overhead на mount. Журнал отдельный (а не сам B-tree как у ZFS) — для durability fsync без write amplification CoW-коммита.
Multi-device встроено. Каждое устройство имеет target label (foreground, background, promote, metadata). При записи блок попадает на foreground (быстрый NVMe), фоном мигрирует на background (медленный HDD). При чтении промоутится обратно. Это и есть tiered storage — то, что в Linux раньше делали bcache + LVM + ручной хореографией.
Replication и erasure coding — на уровне ФС, не блочного устройства. replicas=2 = «храни 2 копии»,
как ZFS mirror. erasure_code= на больших write'ах — RAID-5-подобная избыточность с N data + M
parity. По заявлениям автора, write hole закрыта (в отличие от Btrfs RAID-5/6); в проде это пока
никто массово не проверял.
Snapshots и subvolumes — есть, но реализация моложе чем у Btrfs/ZFS.
Следствия¶
- Tiered storage без слоёв. Один формат данных от NVMe до HDD, без перекладывания через bcache/LVM/dm-cache. Это уникально для Linux.
- Молодость = баги. На 2024–2025 регулярно фиксят корректность, не производительность. Никто из вендоров (RHEL, SUSE, Ubuntu) bcachefs официально не саппортит.
- Toolchain тонкий.
bcachefs-toolsесть, но возможностей repair заметно меньше, чем уe2fsck/xfs_repair/btrfs check.
Хорошо¶
- Tiered storage из коробки.
bcachefs format --label=ssd.ssd1 /dev/nvme0n1 --label=hdd.hdd1 /dev/sda --foreground_target=ssd --background_target=hdd --promote_target=ssdсоздаёт ФС, где горячие данные сами едут на NVMe, холодные — на HDD, прозрачно для приложения. В одной команде то, на что в bcache+LVM уходит полдня. - Erasure coding с надеждой на отсутствие write hole. Если выстрелит — первая нативно-Linux'овая parity-ФС без проблем Btrfs RAID-5/6 и без out-of-tree статуса ZFS.
- Чистая архитектура. Один B-tree, явный журнал, понятные структуры. Внутренности проще читать, чем Btrfs/ZFS.
- Per-file/per-directory параметры. Компрессия, checksum-алгоритм, replicas, target можно задать на конкретный файл/подкаталог (xattr), а не только на весь mount.
- Активная разработка. Фичи добавляются регулярно, фидбек с продакшен-пилотов учитывается.
Плохо¶
- Будущее в mainline под вопросом. Конфликт Kent Overstreet с Линусом и другими мейнтейнерами обострился в 2024–2025 (Kent присылал крупные изменения вне merge window и не соглашался с процессом). Обсуждалось удаление из ядра. На 2026 формально ещё в дереве, но статус нестабильный. Если выпилят — придётся жить на out-of-tree модуле, а это уже ZFS-уровень головной боли без enterprise-поддержки.
- Сырой repair.
bcachefs fsckумеет основные сценарии, но на углах ловит баги; единый advice от мейнтейнеров — «делайте бэкапы», а не «чините». Нормально для experimental, но в проде неприемлемо. - Нет официальной поддержки от дистрибутивов. RHEL — нет и не планируется. Ubuntu — есть пакет
bcachefs-tools, но без commercial support. SUSE — экспериментально. - Производительность ещё не настроена. На синтетике bcachefs местами сравним с XFS/ext4, местами — заметно медленнее. Авторские бенчмарки красивые, независимые — разброс.
- Документация ниже среднего. Большая часть знаний в mailing list, commit messages, и личных постах Kent'а.
- Совместимость on-disk формата ломалась несколько раз за 2023–2025. Документировано (experimental), но при апгрейде ядра — readme + tools нужно читать.
Грабли¶
- Не ставить на root, не ставить на критичные данные. До stable-статуса в апстриме — это playground.
- Бэкап на ext4/XFS + restore — план B по умолчанию.
- Версия
bcachefs-toolsдолжна соответствовать версии ядра. Стащил tools поновее — на старом ядре mount может отказать с unknown features. - На multi-device пуле потеря «фонового» (HDD) устройства = потеря холодных данных, если
replicas=1. По умолчаниюreplicas=1. Сюрприз для тех, кто ждал ZFS-семантики. - Compression-эвристики моложе Btrfs/ZFS — на mixed-content томах иногда жмёт уже сжатое.
Когда брать¶
- Домашний NAS с NVMe-кэшем и HDD-массивом, и не страшно потерять данные. Лучшее, что есть в Linux для этого сценария.
- Эксперименты, разработка, тесты — feedback автору всегда полезен.
- Под прод — не сейчас. Минимум — дождаться, пока статус сменится с experimental и появится хотя бы один дистрибутив с коммерческим саппортом.
Сводная таблица¶
| Требование | ext4 | XFS | Btrfs | ZFS | mdraid+LVM+XFS |
|---|---|---|---|---|---|
| Resize ↑ | online | online | online | autoexpand | online |
| Resize ↓ | offline | никогда | online | только через destroy | для ext4 LV |
| Добавить диск | нужен LVM/RAID снизу | нужен LVM/RAID снизу | btrfs device add |
zpool add |
mdadm --add |
| RAID нативно | нет | нет | только 0/1/10 (5/6 broken) | RAID-Z1/2/3, mirrors | всё через mdraid |
| Бэкап БД (Postgres и др.) | только внешние тулзы | reflinks + pgBackRest | нужен +C, теряет фичи |
snapshots/send | thin snapshots + pgBackRest |
| Скорость PG/Kafka/MinIO | хорошо | отлично (офиц. реком.) | плохо: фрагментация | требует тюнинга | отлично |
| Snapshots | нет | нет (только reflinks) | native | native | через LVM thin |
| Checksums данных | нет | нет | да | да | нет |
| Компрессия | нет | нет | zstd | lz4/zstd | нет |
| Mainline kernel | да | да | да | нет, DKMS | да |
| RAM требования | низкие | низкие | средние | высокие (≥8 GB) | низкие |
| MinIO supported | warn | официально | нет | нет | да |
| Kafka рекомендация | ок | официально (Confluent) | нет | warn | да |
| Postgres рекомендация | ок | официально (EDB/AWS) | нет без +C |
warn, с тюнингом | да |
| Сложность setup | низкая | низкая | средняя | средняя | средняя |
| Сложность восстановления | e2fsck |
xfs_repair |
часто = restore from backup | ZFS-специфика | стандартные тулзы |
Главное правило: ставь то, что умеешь восстанавливать. Для root — ext4. Для БД и Kafka — XFS поверх LVM. Для NAS — ZFS. Для домашнего файлопомойничного NAS с NVMe-кэшем — bcachefs, если не жалко. Btrfs — только если CoW-фичи реально нужны и nodatacow на горячих файлах не пугает.