спроектирована в SGI для параллельного I/O ещё в 1994 году — allocation groups как встроенный шардинг файловой системыdesigned at SGI for parallel I/O back in 1994 — allocation groups as filesystem-level sharding built in from day one

XFS: структуры на диске и алгоритмы работыXFS: on-disk structures and working algorithms

XFS — не журналируемая надстройка над блочными указателями, как ext4, и не CoW-эксперимент, как Btrfs, а файловая система, с первого дня спроектированная вокруг параллелизма: раздел делится на allocation groups, каждая из которых почти автономна и может обрабатывать выделение блоков независимо от других под другим потоком. B+-деревья вместо линейных списков — стандарт для всего: свободного места, inode, extent-карты файла, а с недавних лет — и обратного отображения физического блока на владельца (rmap), на котором строятся reflink и онлайн-проверка целостности без размонтирования.XFS isn't a journaling layer over block pointers like ext4, nor a CoW experiment like Btrfs — it's a filesystem designed from day one around parallelism: a partition is split into allocation groups, each nearly autonomous and able to handle block allocation independently of the others under a different thread. B+-trees instead of linear lists are the standard for everything: free space, inodes, a file's extent map, and, in recent years, reverse-mapping a physical block to its owner (rmap), which reflink and online integrity checking without unmounting are built on.

Что этоWhat it is

XFS появилась в декабре 1994 года вместе с IRIX 5.3 — собственной UNIX-системой SGI для рабочих станций и серверов, где основной нагрузкой были огромные видеофайлы и научные данные, а не тысячи мелких документов. Уже к 1996 году она стала файловой системой по умолчанию в IRIX 6.2, в 1997-м научилась выравнивать выделение блоков под геометрию аппаратных RAID-массивов, а к 1999-му получила version-2 директории, масштабируемые до десятков миллионов файлов в одном каталоге. Порт на Linux начала команда SGI в Мельбурне, код открыли под GPL в 2000-м, первый стабильный релиз для Linux вышел в 2001-м, а в мейнлайн ядро XFS попала в 2002 году (Linux 2.5.36). С середины 2010-х XFS — файловая система по умолчанию в Red Hat Enterprise Linux и его производных.XFS appeared in December 1994 alongside IRIX 5.3 — SGI's own UNIX for workstations and servers, where the primary workload was huge video files and scientific data rather than thousands of small documents. By 1996 it was already the default filesystem in IRIX 6.2, in 1997 it learned to align block allocation to hardware RAID array geometry, and by 1999 it gained version-2 directories, scaling to tens of millions of files in a single directory. The Linux port was started by an SGI team in Melbourne, the code was opened under the GPL in 2000, the first stable Linux release shipped in 2001, and XFS landed in the mainline kernel in 2002 (Linux 2.5.36). Since the mid-2010s, XFS has been the default filesystem in Red Hat Enterprise Linux and its derivatives.

параметрparameterext4BtrfsXFS
внутренний параллелизмinternal parallelismblock group (в основном для локальности, не для параллельной записи)block groups (mostly for locality, not parallel writes)одно B-дерево на весь том, параллелизм ограниченone B-tree for the whole volume, limited parallelismallocation groups — почти независимые единицы выделения, спроектированные под параллельную запись с разных CPUallocation groups — nearly independent allocation units, designed for parallel writes from different CPUs
защита от сбояcrash protectionжурнал метаданных (JBD2)metadata journal (JBD2)copy-on-write всего дереваcopy-on-write of the whole treeжурнал метаданных с отложенной записью (delayed logging, CIL)a metadata journal with delayed logging (CIL)
reflink / снапшотыsnapshots—встроены с самого началаbuilt in from the startreflink — да (с 4.9, на rmap); файловых снапшотов нетreflink — yes (since 4.9, built on rmap); no filesystem-level snapshots
онлайн-проверка/починкаonline check/repairнет (нужен offline e2fsck)no (needs offline e2fsck)scrub — да, но это верификация чексумм, не структурная починкаscrub — yes, but that's checksum verification, not structural repairxfs_scrub — да, структурная проверка и починка без размонтирования, на базе rmapxfs_scrub — yes, structural check and repair without unmounting, built on rmap
изменение размераresizingonline только ростonline growth onlyonline в обе стороныonline both waysonline только рост (xfs_growfs); уменьшение — только пересоздание, кроме экспериментальной несерийной фичиonline growth only (xfs_growfs); shrinking requires recreation, aside from an experimental unstable feature
типичная область примененияtypical use caseуниверсальная, десктоп и серверgeneral purpose, desktop and serverдесктоп, снапшот-центричные сценарииdesktop, snapshot-centric workloadsбольшие файлы, параллельный I/O, RHEL-серверы, медиа/научные данныеlarge files, parallel I/O, RHEL servers, media/scientific data

Как это устроено внутриHow it's built internally

Центральная идея XFS — разбить весь раздел на allocation group (AG), каждая из которых почти самодостаточна: имеет собственную копию суперблока, собственные B+-деревья свободного места и inode, и может выделять блоки и inode независимо от остальных AG. Именно это позволяет нескольким процессам писать в разные части файловой системы параллельно без конкуренции за общую блокировку:The central idea of XFS is splitting the entire partition into allocation groups (AGs), each nearly self-sufficient: it has its own superblock copy, its own free-space and inode B+-trees, and can allocate blocks and inodes independently of the other AGs. This is exactly what lets several processes write to different parts of the filesystem in parallel without contending for a shared lock:

/dev/sdX (раздел XFS) AG 0 AG 1 AG 2 ... AG 0 — содержимое superblock AGI AGF AGFL (1 блок/сектор) free space B+tree by-block (AGF root) B+tree by-size (AGF root) inode B+tree чанки по 64 inode (AGI root) rmap B+tree (физ.→ владелец) данные файлов и inode этой группы
Первый блок (или сектор — если он меньше блока ФС, все четыре структуры делят один блок) каждой AG содержит суперблок, AGI (заголовок inode-структур), AGF (заголовок структур свободного места) и AGFL (резервные блоки для перестроения B+-деревьев без отдельного выделения). Дальше идут корни собственных B+-деревьев группы. Только первая (primary) AG хранит по-настоящему глобальную информацию — общее свободное место и число inode по всему тому.The first block (or sector — if smaller than the filesystem block, all four structures share one block) of every AG holds the superblock, the AGI (inode structure header), the AGF (free-space structure header), and the AGFL (reserve blocks for rebuilding B+-trees without a separate allocation). What follows are the roots of the group's own B+-trees. Only the first (primary) AG stores truly global information — overall free space and inode counts across the whole volume.

Свободное место внутри AG отслеживается не одним, а двумя B+-деревьями одновременно, индексирующими одни и те же диапазоны по разным ключам — это позволяет отвечать сразу на два разных вопроса без полного перебора:Free space within an AG is tracked not by one but by two B+-trees at once, indexing the same ranges under different keys — this lets two different questions be answered without a full scan:

деревоtreeключkeyкакой вопрос решаетwhat question it answers
by-block (bnobt)номер начального блока диапазонаthe starting block number of a range«есть ли свободное место рядом с этим конкретным блоком?» — нужно для выделения смежно с уже записанными данными файла"is there free space near this specific block?" — needed for allocating contiguous with a file's already-written data
by-size (cntbt)размер свободного диапазонаthe size of a free range«где ближайший диапазон достаточного размера?» — нужно для выделения одним куском большого файла без лишней фрагментации"where's the nearest range big enough?" — needed for allocating a large file as one chunk with minimal fragmentation

Оба дерева обновляются в одной транзакции при каждом выделении/освобождении блоков — отсюда и нужен резервный список AGFL: без него операция вставки в оба B+-дерева могла бы сама потребовать выделения нового блока под узел дерева, создавая рекурсивную зависимость («чтобы выделить место, нужно место»), которую AGFL разрывает, держа несколько блоков в резерве заранее.Both trees are updated in a single transaction on every block allocation/free — which is exactly why the AGFL reserve list is needed: without it, inserting into either B+-tree could itself require allocating a new block for a tree node, creating a recursive dependency ("allocating space requires space") that the AGFL breaks by keeping a few blocks reserved in advance.

Данные файла адресуются собственным B+-деревом — bmbt (block map B-tree), логически тем же приёмом, что extent-дерево ext4, но реализованным как полноценное B+-дерево, а не компактный формат внутри inode с ограниченной глубиной:A file's data is addressed by its own B+-tree — the bmbt (block map B-tree), logically the same trick as ext4's extent tree, but implemented as a full B+-tree rather than a compact inode-embedded format with limited depth:

inode (extent format) список экстент-записей прямо в теле inode мало фрагментов ext4_extent-подобная offset/length/ phys.block/state много фрагментов — переключение формата inode (btree format) корень bmbt в теле inode блоки bmbt на диске — полноценное B+-дерево, глубина растёт по мере фрагментации без верхнего лимита ext4
Для файла с небольшим числом экстентов запись хранится компактно прямо в inode (extent format) — как и в ext4. При превышении лимита формат переключается на btree format: корень полноценного B+-дерева всё ещё в inode, но узлы дерева выносятся в отдельные блоки на диске без искусственного ограничения на глубину, характерного для компактного формата ext4.For a file with few extents, the record is stored compactly right in the inode (extent format) — same as ext4. Past a limit, the format switches to btree format: the root of a full B+-tree still lives in the inode, but the tree's nodes move out into separate on-disk blocks with no artificial depth cap like ext4's compact format has.

С версии 4.9 (для XFS с фичей rmap) появилось третье дерево на AG — rmap btree, обратное отображение «какой физический блок кому принадлежит» вместо прямого «какой логический блок файла где физически лежит». Это не дублирование bmbt, а другой ключ к тем же данным, необходимый там, где bmbt принципиально не справляется — когда один физический блок используется сразу несколькими владельцами:Since version 4.9 (for XFS with the rmap feature) a third per-AG tree appeared — the rmap btree, a reverse mapping of "which physical block belongs to whom" instead of the forward "where does this file's logical block physically live". This isn't a bmbt duplicate — it's a different key into the same data, needed exactly where bmbt fundamentally falls short: when one physical block is used by several owners at once:

file A: bmbt offset 0 → block 5000 file B: bmbt offset 0 → block 5000 (после reflink: оба владеют одним физическим блоком) block 5000 физический блок «кому принадлежит?» — без rmap: сканировать все inode rmap btree 5000 → {A, B} прямой ответ rmap также делает возможным online repair: bmbt конкретного файла можно перестроить заново из rmap-записей той же AG, если исходное дерево повреждено — без размонтирования
После reflink-копии два файла ссылаются на один физический блок через свои независимые bmbt. Без обратного отображения выяснить, кто ещё владеет этим блоком, можно только полным сканированием всех inode файловой системы. rmap btree хранит запись прямо в обратную сторону, а заодно позволяет xfs_scrub перестроить повреждённое bmbt файла заново — из записей rmap той же allocation group, без размонтирования тома.After a reflink copy, two files reference one physical block through their independent bmbts. Without a reverse mapping, finding out who else owns that block requires a full scan of every inode in the filesystem. The rmap btree stores the mapping in reverse directly, and as a side effect lets xfs_scrub rebuild a file's corrupted bmbt from that AG's rmap records, without unmounting the volume.

Журналирование в XFS защищает те же метаданные, что и JBD2 в ext4, но устроено иначе на уровне реализации — delayed logging откладывает физическую запись изменений в лог-буфер, накапливая их в памяти в структуре CIL (Committed Item List):Journaling in XFS protects the same metadata as JBD2 does in ext4, but works differently at the implementation level — delayed logging postpones physically writing changes to the log buffer, accumulating them in memory in a structure called the CIL (Committed Item List):

Практический эффект delayed logging — журнал перестаёт быть узким местом при интенсивной модификации одних и тех же метаданных (например, частое обновление времени доступа в одном и том же каталоге с множества потоков): физически на диск попадает не поток отдельных изменений, а их итоговый результат за интервал между checkpoint-ами.The practical effect of delayed logging is that the journal stops being a bottleneck under heavy modification of the same metadata (say, frequent access-time updates in the same directory from many threads): what actually hits the disk isn't a stream of individual changes but their net result over the interval between checkpoints.

Как этим пользуются на практикеHow it's used in practice

командаcommandчто происходитwhat happens
mkfs.xfs -d agcount=32 /dev/sdX1явно задаёт число allocation group при создании — на многоядерном сервере с параллельной записью большее число AG снижает конкуренцию за блокировки отдельных группexplicitly sets the number of allocation groups at creation time — on a multi-core server with parallel writes, more AGs reduce lock contention on individual groups
xfs_info /mntпоказывает реальное число AG, размер каждой, размер и версию журнала — прямой взгляд на структуру уже смонтированного томаshows the actual AG count, each one's size, and the journal's size and version — a direct look at an already-mounted volume's structure
xfs_growfs /mntувеличивает том онлайн, добавляя новые allocation group поверх существующих — не требует размонтирования; обратной операции (shrink) для стандартного пути нетgrows the volume online by adding new allocation groups on top of the existing ones — no unmount required; there's no reverse (shrink) operation on the standard path
cp --reflink=always src dstсоздаёт лёгкую копию, разделяющую физические блоки с оригиналом через rmap — данные физически копируются только при последующем расхождении (тот же принцип, что и в Btrfs, но с явным обратным отображением вместо общего extent tree)creates a lightweight copy sharing physical blocks with the original via rmap — data is physically copied only once the two later diverge (the same principle as Btrfs, but with an explicit reverse mapping instead of a shared extent tree)
xfs_scrub /dev/sdX1запускает онлайн-проверку структурной целостности метаданных на смонтированном томе, используя rmap для перекрёстной сверки — при обнаружении повреждения умеет чинить его в фоне, без размонтирования и остановки сервисаruns an online structural integrity check of metadata on a mounted volume, using rmap for cross-verification — on finding corruption it can repair it in the background, without unmounting or stopping the service
xfs_db -r -c "sb 0" -c print /dev/sdX1отладочный интерфейс XFS — печатает содержимое суперблока прямо с диска в режиме только для чтения, включая версию формата и включённые фичи (rmap, reflink, CRC)XFS's debugging interface — prints the superblock contents straight off disk in read-only mode, including the format version and enabled features (rmap, reflink, CRC)

Грабли и мифыGotchas & myths

XFS до сих пор нельзя надёжно уменьшить онлайнXFS still can't be reliably shrunk online

Штатный xfs_growfs умеет только увеличивать том; официальная документация проекта прямо перечисляет уменьшение как нерешённую задачу («Shrinking Support»). Экспериментальная реализация online shrink существует, но маркирована как «используйте на свой страх и риск» и не рекомендована для прода. Единственный практически надёжный способ уменьшить раздел XFS — это dump данных, пересоздание файловой системы меньшего размера и restore, то есть фактически офлайн-миграция, а не изменение существующего тома.the standard xfs_growfs can only grow a volume; the project's official documentation lists shrinking outright as an unresolved task ("Shrinking Support"). An experimental online shrink implementation exists but is marked "use at your own risk" and isn't recommended for production. The only practically reliable way to shrink an XFS partition is dumping the data, recreating a smaller filesystem, and restoring — effectively an offline migration, not a resize of the existing volume.

rmap и reflink добавили «eventual consistency» туда, где раньше её не былоrmap and reflink introduced "eventual consistency" where there wasn't any before

Само расширение механизма отложенных операций (deferred ops), понадобившееся для согласованного обновления rmapbt/refcountbt/bmbt в одной сложной транзакции, стало источником задокументированных разработчиками отчётов о «несогласованности метаданных» — не потому что данные реально повреждены, а потому что промежуточное состояние между шагами составной операции временно не совпадает с тем, что ожидает более простая проверка. Это цена, которую reflink и rmap платят за свою гибкость, и именно поэтому официальный online-fsck дизайн-документ отдельно обсуждает эту модель согласованности.the very expansion of the deferred-operations mechanism, needed to consistently update rmapbt/refcountbt/bmbt in one compound transaction, has itself become a documented source of "metadata inconsistency" reports by the developers — not because the data is actually corrupted, but because a compound operation's intermediate state temporarily doesn't match what a simpler check expects. That's the price reflink and rmap pay for their flexibility, and it's exactly why the official online-fsck design document separately discusses this consistency model.

allocation group — не то же самое, что диск или RAID-устройствоan allocation group isn't the same thing as a disk or a RAID device

AG — чисто логическое деление одного тома XFS, а не физическое распределение по разным дискам (в отличие от того, как chunk tree в Btrfs явно решает, на каком устройстве физически лежат данные). Параллелизм, который дают AG, работает и на одном физическом диске — выигрыш идёт от независимости структур метаданных и меньшей конкуренции за блокировки, а не от параллельного физического доступа к разным носителям.an AG is a purely logical division of a single XFS volume, not a physical spread across different disks (unlike how Btrfs's chunk tree explicitly decides which device data physically lives on). The parallelism AGs provide works even on a single physical disk — the win comes from independent metadata structures and reduced lock contention, not from parallel physical access to different media.

ТерминыTerms

allocation group (AG)
почти автономная область раздела XFS со своими структурами метаданных и B+-деревьями — единица, вокруг которой строится внутренний параллелизм файловой системы; аналог block group ext4, но спроектированный именно под параллельное выделение, а не только локальность данных.a nearly autonomous region of an XFS partition with its own metadata structures and B+-trees — the unit the filesystem's internal parallelism is built around; an ext4 block-group analogue, but designed specifically for parallel allocation, not just data locality.
AGI / AGF / AGFL
три служебные структуры в начале каждой AG: AGI — заголовок inode-структур (корень дерева inode), AGF — заголовок структур свободного места (корни двух деревьев by-block/by-size), AGFL — резервный список блоков, разрывающий рекурсивную зависимость «нужно место, чтобы выделить место».three bookkeeping structures at the start of every AG: the AGI — the inode structure header (the inode tree's root), the AGF — the free-space structure header (the roots of the two by-block/by-size trees), and the AGFL — a reserve block list breaking the recursive "need space to allocate space" dependency.
bmbt (block map B-tree)
B+-дерево, адресующее данные конкретного файла — логический аналог extent-дерева ext4, но реализованный как полноценное дерево с узлами на диске вместо компактного формата, ограниченного глубиной внутри inode.the B+-tree addressing a specific file's data — a logical analogue of ext4's extent tree, but implemented as a full tree with on-disk nodes instead of a compact, depth-limited inode-embedded format.
rmap (reverse mapping) btree
B+-дерево на уровне AG, хранящее обратное отображение «физический блок → владелец(ы)» вместо прямого «файл → физический блок»; без него узнать всех владельцев блока можно только сканированием всех inode. Основа для reflink и online repair.a per-AG B+-tree storing the reverse mapping "physical block → owner(s)" instead of the forward "file → physical block"; without it, finding all a block's owners requires scanning every inode. The basis for reflink and online repair.
delayed logging / CIL
механизм, накапливающий изменения метаданных в памяти (Committed Item List) вместо немедленной записи в лог-буфер на диске; при синхронизации весь CIL сбрасывается одной checkpoint-транзакцией, схлопывая повторные изменения одного объекта в одну запись.a mechanism accumulating metadata changes in memory (the Committed Item List) instead of writing them immediately to an on-disk log buffer; on sync, the entire CIL is flushed as one checkpoint transaction, collapsing repeated changes to one object into a single record.
AIL (Active Item List)
список элементов метаданных, уже записанных в журнал, но ещё не записанных на их постоянное место на диске — промежуточное состояние между «безопасно на случай сбоя» и «применено окончательно».the list of metadata items already written to the journal but not yet written to their permanent on-disk location — the intermediate state between "safe against a crash" and "finally applied".
xfs_scrub
инструмент онлайн-проверки и починки структурной целостности XFS без размонтирования тома — использует rmap для перекрёстной сверки и перестроения повреждённых структур (например, bmbt файла) из независимого источника той же информации.the tool for online structural integrity checking and repair of XFS without unmounting the volume — uses rmap for cross-verification and to rebuild corrupted structures (e.g. a file's bmbt) from an independent source of the same information.