Files
jellybit/docs/adr/ADR-2026-06-13-hardlinks.md

2.9 KiB

Хардлинки вместо копирования и симлинков

  • Дата: 2026-06-13

Контекст

jellybit раскладывает скачанные qBittorrent'ом файлы в библиотеку Jellyfin. Два требования тянут в разные стороны: раздача должна продолжаться (источник неприкосновенен), а место на диске — не дублироваться. qBittorrent пишет в /srv/media/downloads, Jellyfin читает /srv/media/{movies,series} — всё под единой песочницей /srv/media.

Рассмотренные варианты

  • Хардлинк — второе имя того же inode в /srv/media. Плюсы: ноль доп. места, раздача цела, файл «настоящий» для Jellyfin. Минусы: только в пределах одной ФС; нельзя линковать каталоги (только файлы).
  • Копирование (поведение radarr/sonarr по умолчанию) — дублирует десятки ГБ на каждый релиз; для домашнего сервера дорого и медленно.
  • Симлинк — место экономит, но ломается при перемещении источника, Jellyfin/плееры иногда плохо дружат с символическими ссылками, а удаление раздачи рвёт библиотеку.
  • Перемещение — убивает раздачу (сид, ratio) и нарушает «источник неприкосновенен».

Решение

Раскладываем хардлинками. На одной ФС (/srv) это бесплатно по месту, раздача продолжается, файл неотличим от обычного. Линкуем только файлы, целевые каталоги создаём mkdir. Жёсткий инвариант: jellybit никогда не перемещает и не удаляет исходные файлы; undo удаляет только свои ссылки под /srv/media.

Последствия

  • + Ноль дублирования, мгновенно, раздача цела.
  • + Простая и безопасная модель операций: только add-link и remove-own-link.
  • - Требуется один mount — внутри docker обеспечивается монтированием единой песочницы /srv/media (иначе link(2) даёт EXDEV).
  • - Каталоги хардлинковать нельзя — раскладка пофайловая, целевые папки создаём сами (0755, владелец 1000:1000).