From 7bcca193d5ed2e1cd8f2b4106156d02fe6ad370d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leo=20Nikkil=C3=A4?= Date: Sat, 8 Jun 2024 01:14:18 +0300 Subject: [PATCH] Fix `reflink: "auto"` option The docs say: > The `auto` option uses reflinks when possible and falls back to plain > copying when necessary. I've been using this option for a while, and recently discovered that despite the option, copying fails between two BTRFS filesystems with: Error: OS/filesystem does not support reflinks. during link of paths /mnt/fs1/file, /mnt/fs2/file I tracked this down to how the configuration is handled in the importer. --- beets/importer.py | 2 ++ docs/changelog.rst | 1 + test/test_importer.py | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/beets/importer.py b/beets/importer.py index 55ee29226..138c12916 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -1684,6 +1684,8 @@ def manipulate_files(session, task): operation = MoveOperation.LINK elif session.config["hardlink"]: operation = MoveOperation.HARDLINK + elif session.config["reflink"] == "auto": + operation = MoveOperation.REFLINK_AUTO elif session.config["reflink"]: operation = MoveOperation.REFLINK else: diff --git a/docs/changelog.rst b/docs/changelog.rst index 9deb0aa92..bcfc6b210 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -9,6 +9,7 @@ Changelog goes here! Please add your entry to the bottom of one of the lists bel Bug fixes: * Improved naming of temporary files by separating the random part with the file extension. +* Fixed the ``auto`` value for the :ref:`reflink` config option. For packagers: diff --git a/test/test_importer.py b/test/test_importer.py index 8809af49b..3ddf6f93d 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -235,6 +235,30 @@ class NonAutotaggedImportTest(_common.TestCase, ImportHelper): == (s2[stat.ST_INO], s2[stat.ST_DEV]) ) + @unittest.skipUnless(_common.HAVE_REFLINK, "need reflinks") + def test_import_reflink_arrives(self): + # Detecting reflinks is currently tricky due to various fs + # implementations, we'll just check the file exists. + config["import"]["reflink"] = True + self.importer.run() + for mediafile in self.import_media: + self.assert_file_in_lib( + b"Tag Artist", + b"Tag Album", + util.bytestring_path(f"{mediafile.title}.mp3"), + ) + + def test_import_reflink_auto_arrives(self): + # Should pass regardless of reflink support due to fallback. + config["import"]["reflink"] = "auto" + self.importer.run() + for mediafile in self.import_media: + self.assert_file_in_lib( + b"Tag Artist", + b"Tag Album", + util.bytestring_path(f"{mediafile.title}.mp3"), + ) + def create_archive(session): (handle, path) = mkstemp(dir=py3_path(session.temp_dir))