Файловые системы

Диск выполняет всего две операции — чтение блока байтов по номеру и запись блока байтов по номеру. Ни файлов, ни каталогов, ни прав доступа, ни имён на нём нет; всё это является надстройкой, возводимой сверху файловой системой, которая знает, где что расположено.

Для физика, у которого данные эксперимента измеряются терабайтами, от выбора файловой системы и схемы дисков зависит, переживёт ли архив, собранный за годы, отказ оборудования.

Слайды к главе. Материал главы изложен также во второй части лекции «Как организован Linux» с демонстрациями в терминале; слайды лекции доступны на сайте книги и в PDF.

1. Немного о дисках

Классический жёсткий диск состоит из пластин, разделённых на дорожки и секторы (обычно по 512 байт или 4 КБ). У SSD пластин нет, но наружу он предоставляет всё тот же интерфейс из пронумерованных секторов одинакового размера. Файловая система этой разницы почти не замечает. Располагается она внутри раздела, описанного в таблице MBR или GPT.

2. Задачи файловой системы

ФС решает несколько задач:

  • Индексация и поиск данных (через структуры наподобие inode).
  • Управление свободным пространством, то есть учёт блоков, остающихся незанятыми.
  • Контроль доступа (права, ACL).
  • Оптимизация производительности (кеширование, дефрагментация*).
  • Надёжность (журналирование).

*Дефрагментация менее критична для современных ФС (ext4, XFS, btrfs) и SSD.

3. Виды файловых систем

Все файловые системы Linux скрывает за единым интерфейсом, называемым VFS (Virtual File System). Благодаря ему open и read работают одинаково и на локальном ext4, и на сетевом NFS, и на псевдофайлах из /proc, а программе, вызывающей их, не требуется знать, с чем она имеет дело.

FAT (File Allocation Table)

FAT происходит из эпохи дискет; сегодня она применяется для флеш-накопителей, которые должны открываться на любом компьютере, и для EFI-раздела, с которого загружается установленная система.

  • Плюсы: простая, читаемая всеми операционными системами.
  • Минусы: журналирования нет, а размеры, заложенные в формат, ограничены: в FAT32 файл не больше 4 ГБ, а раздел штатными средствами Windows не отформатировать больше 32 ГБ.
  • Происхождение чисел в названии: 12, 16 и 32 обозначают разрядность номера кластера в таблице размещения. Предельный размер тома получается умножением числа кластеров на размер кластера, но самих кластеров несколько меньше, чем даёт разрядность: несколько старших номеров занято служебными метками, зарезервированными под «конец файла» и «сбойный кластер». У FAT12 их 4084, а не 4096. У FAT32 под номер отведено 28 бит из 32, а старшие четыре не используются.

ext4 (Fourth Extended Filesystem)

Если файловая система не выбиралась сознательно, почти наверняка используется ext4: она устанавливается по умолчанию в большинстве дистрибутивов и подходит для расчётного узла общего назначения.

  • Стандарт для Ubuntu, Debian и многих других дистрибутивов.
  • Журналируемая, то есть повышающая надёжность записью метаданных операций в специальный журнал перед их выполнением.
  • Использует экстенты (extents), описывающие непрерывный диапазон блоков, для более эффективного хранения больших файлов (вместо прямых и косвенных блоков).
  • Иноды (inodes) хранят метаданные о файле (права, владелец, указатели, ведущие к данным). Их количество ограничено числом, заданным при создании ФС.

XFS

XFS создавалась для больших файлов и параллельного доступа с десятков узлов. Её применяют там, где на диск записываются многогигабайтные наборы наподобие архивов эксперимента и дампов, полученных при моделировании.

  • Высокопроизводительная ФС, подходящая для работы с большими файлами.
  • Использует B+-tree для индексации.
  • Отложенная аллокация, улучшающая производительность.
  • Иноды, создаваемые динамически, по мере необходимости.
  • Стандарт для Red Hat Enterprise Linux.

btrfs (B-Tree File System)

Btrfs создаёт снимки состояния практически без затрат, что удобно на рабочей машине, где требуется откатываться к состоянию, сохранённому до обновления.

  • Современная ФС с продвинутыми функциями.
  • Copy-on-Write (CoW): при изменении файла данные записываются в новое место, а не перезаписываются старые. Это и обеспечивает дешёвые снапшоты (snapshots).
  • Встроенная поддержка RAID и LVM-подобных функций.
  • Субаллокация, обеспечивающая эффективную работу с маленькими файлами.
  • Поддержка TRIM, сообщающего SSD об освободившихся блоках.
  • Стандарт для openSUSE.

4. Конфигурирование файловой системы

Сильнее всего на скорость дисковых операций влияют кеширование и порядок, в котором накопленные запросы передаются на устройство.

  • Кеширование: прочитанные с диска страницы ядро хранит в page cache, откуда повторное чтение того же файла выполняется уже из памяти. Изменённые, но ещё не записанные на диск страницы называют «грязными» (dirty). Отдельного кеша для них нет: это состояние страниц внутри того же page cache. Сбрасывает их фоновый механизм, работающий по таймеру, а принудительно — вызов sync.

  • Планировщики ввода-вывода: определяют, в каком порядке запросы передаются на диск. Текущий и доступные приведены в /sys/block/<device>/queue/scheduler. Начиная с ядра 5.0 остались только многоочередные планировщики:

    • none работает без переупорядочивания, как обычный FIFO. Обычно является лучшим выбором для NVMe-накопителей, которым перестановка запросов ничего не даёт.
    • mq-deadline следит за сроками выполнения запросов, не позволяя им зависать. Разумное значение по умолчанию для SATA-дисков и SSD.
    • bfq «честно» распределяет полосу между процессами; полезен на настольной системе, где важна отзывчивость.
    • kyber является простым планировщиком для быстрых устройств, ограничивающим задержки.

    Старые одноочередные планировщики cfq, deadline и noop из ядра удалены, но их названия ещё встречаются в статьях.

Утилиты для работы с ФС:

  • mkfs, mke2fs создают ФС.
  • tune2fs изменяет параметры ФС ext*.
  • debugfs отлаживает ФС ext*.
  • fsck проверяет ФС и восстанавливает структуры, повреждённые сбоем.

5. Монтирование

В Linux нет букв дисков: любая файловая система подключается в общее дерево каталогов, растущее из корня, в выбранную точку монтирования наподобие /mnt, /home или /data. Пока раздел не смонтирован, данные на нём недоступны.

  • Команды: mount, umount.
  • /etc/fstab хранит описания файловых систем, монтируемых при загрузке автоматически.
    # Пример строки в /etc/fstab
    UUID=ed465c6e-949a-41c6-8e8b-c8da348a3577 / ext4 defaults 0 1
    
  • Параметры монтирования: rw/ro (чтение и запись или только чтение), noatime (не обновлять время последнего доступа, что на архиве, состоящем из миллионов файлов, заметно экономит записи), acl (поддержка списков контроля доступа) и другие.
  • systemd.mount является альтернативой fstab, построенной на юнитах systemd.

6. RAID (Redundant Array of Independent Disks)

RAID объединяет несколько физических дисков в один логический массив, видимый системе как обычный диск. Цель — либо пережить отказ диска без потери данных, либо сложить скорости нескольких дисков, работающих одновременно, а в некоторых уровнях и то и другое.

УровеньПринципНадёжностьПроизводительностьЁмкость
RAID 0Striping (чередование)НизкаяВысокая (чт/зап)N
RAID 1Mirroring (зеркалирование)ВысокаяВысокая (чт)1 диск
RAID 5ЧётностьСредняяВысокая (чт)N-1
RAID 6Двойная чётностьВысокаяВысокая (чт)N-2
RAID 10Зеркалирование + чередованиеВысокаяВысокая (чт/зап)N/2

В колонке «Ёмкость» \(N\) обозначает число дисков в массиве (все одинакового размера). У RAID 1, сколько бы дисков ни было собрано в зеркало, полезная ёмкость равна ёмкости одного диска: остальные хранят копии записанного. Поэтому зеркало почти всегда собирают из двух дисков.

RAID резервным копированием не является. Массив защищает от отказа диска, но не от файла, удалённого по ошибке, не от шифровальщика и не от пожара в серверной. Всё перечисленное произойдёт на всех дисках одновременно.

Создание программного RAID в Linux: Аппаратный контроллер не требуется: массив собирает ядро, а управляет им утилита mdadm.

# Пример создания RAID 1
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
mkfs.ext4 /dev/md0
mount /dev/md0 /mnt/raid
# Сохранение конфигурации
mdadm --detail --scan >> /etc/mdadm.conf   # в Debian/Ubuntu: /etc/mdadm/mdadm.conf

7. LVM (Logical Volume Manager)

LVM вводит между дисками и файловыми системами дополнительный слой, благодаря которому раздел перестаёт быть привязанным к части конкретного диска. Логический том можно увеличить, не переразмечая диск заново, можно собрать том больше любого из имеющихся дисков, а можно создать мгновенный снимок состояния, например перед перезаписью архива.

Понятий три, и они вкладываются друг в друга. Физическим томом (physical volume, PV) называют диск или раздел, отданный под управление LVM. Несколько физических томов объединяются в группу томов (volume group, VG), общий пул пространства всех дисков. Из группы, в свою очередь, выделяются логические тома (logical volume, LV), на которых и создаются файловые системы.

Порядок команд при создании:

  • pvcreate /dev/sdX1 /dev/sdY1 передаёт разделы под управление LVM;
  • vgcreate my_vg /dev/sdX1 /dev/sdY1 собирает из этих физических томов группу;
  • lvcreate -n my_vol -L 10G my_vg выделяет из группы логический том на 10 ГБ;
  • mkfs.ext4 /dev/my_vg/my_vol создаёт на нём файловую систему.

Заключение

Файловая система выбирается под ожидаемую нагрузку. ext4 остаётся разумным значением по умолчанию, XFS применяют для больших файлов, Btrfs — там, где нужны снимки, откатывающие систему к сохранённому состоянию. Схема дисков продумывается до того, как на них будут записаны данные; переразмечать массив, заполненный терабайтами, значительно дороже, чем заранее потратить полчаса на планирование. Ни RAID, ни снимки не заменяют резервную копию, хранимую в другом месте.

Задание. Собрать зеркало из двух дисков и проверить, что система переживёт отказ любого из них: «Установка Arch Linux вручную с RAID1 и UEFI».