Files
jellybit/docs/adr/ADR-2026-06-13-hardlinks.md
T
av 66d39297c5 docs: проект переведён на канон документов версии 4
- каталог задач: PLAN.md → ROADMAP.md с каноническими секциями, все 44
  записи получили тип, заголовки приведены к форме своего типа
- расхождения, найденные судьями канона: исключения инварианта «источник
  неприкосновенен», инвариант про один активный infohash, UTC в logging.md,
  поведение из architecture.md заменено ссылками на спеки
- триггеры профиля ревью переписаны под умолчание standard
2026-08-06 13:32:06 +03:00

3.1 KiB

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

  • Дата: 2026-06-13
  • Источник: архивного design.md нет — решение принято до перехода проекта на OpenSpec (первый архивный change — 2026-06-28); первичный материал — история git

Контекст

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).