спроектирована в 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 — не журналируемая надстройка над блочными указателями, как 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.
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.
| параметрparameter | ext4 | Btrfs | XFS |
|---|---|---|---|
| внутренний параллелизмinternal parallelism | block group (в основном для локальности, не для параллельной записи)block groups (mostly for locality, not parallel writes) | одно B-дерево на весь том, параллелизм ограниченone B-tree for the whole volume, limited parallelism | allocation 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 start | reflink — да (с 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 repair | xfs_scrub — да, структурная проверка и починка без размонтирования, на базе rmapxfs_scrub — yes, structural check and repair without unmounting, built on rmap |
| изменение размераresizing | online только ростonline growth only | online в обе стороныonline both ways | online только рост (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 |
Центральная идея 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:
Свободное место внутри 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:
С версии 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:
Журналирование в 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.
| команда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) |
Штатный 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.
Само расширение механизма отложенных операций (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.
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.