Skip to content

Commit

Permalink
Fix reflink: "auto" option
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lnikkila committed Jun 7, 2024
1 parent 1b59479 commit 7bcca19
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
2 changes: 2 additions & 0 deletions beets/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
24 changes: 24 additions & 0 deletions test/test_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,30 @@ def test_import_hardlink_arrives(self):
== (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))
Expand Down

0 comments on commit 7bcca19

Please sign in to comment.