diff --git a/src/borg/item.pyx b/src/borg/item.pyx index 642b7b264..5ca93404f 100644 --- a/src/borg/item.pyx +++ b/src/borg/item.pyx @@ -1,3 +1,4 @@ +import stat from collections import namedtuple from .constants import ITEM_KEYS @@ -193,6 +194,10 @@ class Item(PropDict): raise AttributeError size = getattr(self, attr) except AttributeError: + if stat.S_ISLNK(self.mode): + # get out of here quickly. symlinks have no own chunks, their fs size is the length of the target name. + # also, there is the dual-use issue of .source (#2343), so don't confuse it with a hardlink slave. + return len(self.source) # no precomputed (c)size value available, compute it: try: chunks = getattr(self, 'chunks') diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py index e44f2753b..874987263 100644 --- a/src/borg/testsuite/archiver.py +++ b/src/borg/testsuite/archiver.py @@ -1748,6 +1748,8 @@ class ArchiverTestCase(ArchiverTestCaseBase): out_fn = os.path.join(mountpoint, 'input', 'link1') sti = os.stat(in_fn, follow_symlinks=False) sto = os.stat(out_fn, follow_symlinks=False) + assert sti.st_size == len('somewhere') + assert sto.st_size == len('somewhere') assert stat.S_ISLNK(sti.st_mode) assert stat.S_ISLNK(sto.st_mode) assert os.readlink(in_fn) == os.readlink(out_fn) diff --git a/src/borg/testsuite/item.py b/src/borg/testsuite/item.py index 4dedcdc1f..785a962ca 100644 --- a/src/borg/testsuite/item.py +++ b/src/borg/testsuite/item.py @@ -149,7 +149,7 @@ def test_unknown_property(): def test_item_file_size(): - item = Item(chunks=[ + item = Item(mode=0o100666, chunks=[ ChunkListEntry(csize=1, size=1000, id=None), ChunkListEntry(csize=1, size=2000, id=None), ]) @@ -157,5 +157,5 @@ def test_item_file_size(): def test_item_file_size_no_chunks(): - item = Item() + item = Item(mode=0o100666) assert item.get_size() == 0