1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2025-01-04 06:21:46 +00:00

fuse: fix hardlinks in versions view, fixes #1599

This commit is contained in:
Thomas Waldmann 2016-09-15 20:31:57 +02:00
parent c021cf466a
commit 39170479aa

View file

@ -15,7 +15,7 @@
logger = create_logger()
from .archive import Archive
from .helpers import daemonize, safe_encode
from .helpers import daemonize
from .item import Item
from .lrucache import LRUCache
@ -136,6 +136,7 @@ def _create_dir(self, parent):
def process_archive(self, archive, prefix=[]):
"""Build fuse inode hierarchy from archive metadata
"""
self.file_versions = {} # for versions mode: original path -> version
unpacker = msgpack.Unpacker()
for key, chunk in zip(archive.metadata.items, self.repository.get_many(archive.metadata.items)):
_, data = self.key.decrypt(key, chunk)
@ -155,7 +156,6 @@ def process_archive(self, archive, prefix=[]):
self.items[inode] = item
continue
segments = prefix + os.fsencode(os.path.normpath(item.path)).split(b'/')
del item.path
parent = 1
for segment in segments[:-1]:
parent = self.process_inner(segment, parent)
@ -169,14 +169,31 @@ def file_version(item):
ident = adler32(chunkid, ident)
return ident
def make_versioned_name(name, version, add_dir=False):
if add_dir:
# add intermediate directory with same name as filename
path_fname = name.rsplit(b'/', 1)
name += b'/' + path_fname[-1]
return name + os.fsencode('.%08x' % version)
if self.versions and not is_dir:
parent = self.process_inner(name, parent)
version = file_version(item)
if version is not None:
name += safe_encode('.%08x' % version)
# regular file, with contents - maybe a hardlink master
name = make_versioned_name(name, version)
self.file_versions[item.path] = version
del item.path # safe some space
if 'source' in item and stat.S_ISREG(item.mode):
inode = self._find_inode(item.source, prefix)
# a hardlink, no contents, <source> is the hardlink master
source = item.source
if self.versions:
# adjust source name with version
version = self.file_versions[source]
source = os.fsdecode(make_versioned_name(os.fsencode(source), version, add_dir=True))
name = make_versioned_name(name, version)
inode = self._find_inode(source, prefix)
item = self.cache.get(inode)
item.nlink = item.get('nlink', 1) + 1
self.items[inode] = item