1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-26 09:47:58 +00:00

Merge pull request #2094 from enkore/issue/2092

Fix invalid hard links
This commit is contained in:
TW 2017-01-24 22:54:18 +01:00 committed by GitHub
commit cf0192cdd3
2 changed files with 12 additions and 5 deletions

View file

@ -660,8 +660,6 @@ def process_file(self, path, st, cache, ignore_inode=False):
self.add_item(item) self.add_item(item)
status = 'h' # regular file, hardlink (to already seen inodes) status = 'h' # regular file, hardlink (to already seen inodes)
return status return status
else:
self.hard_links[st.st_ino, st.st_dev] = safe_path
is_special_file = is_special(st.st_mode) is_special_file = is_special(st.st_mode)
if not is_special_file: if not is_special_file:
path_hash = self.key.id_hash(os.path.join(self.cwd, path).encode('utf-8', 'surrogateescape')) path_hash = self.key.id_hash(os.path.join(self.cwd, path).encode('utf-8', 'surrogateescape'))
@ -709,6 +707,9 @@ def process_file(self, path, st, cache, ignore_inode=False):
item[b'mode'] = stat.S_IFREG | stat.S_IMODE(item[b'mode']) item[b'mode'] = stat.S_IFREG | stat.S_IMODE(item[b'mode'])
self.stats.nfiles += 1 self.stats.nfiles += 1
self.add_item(item) self.add_item(item)
if st.st_nlink > 1 and source is None:
# Add the hard link reference *after* the file has been added to the archive.
self.hard_links[st.st_ino, st.st_dev] = safe_path
return status return status
@staticmethod @staticmethod

View file

@ -128,15 +128,21 @@ def process_archive(self, archive, prefix=[]):
else: else:
self.items[inode] = item self.items[inode] = item
continue continue
segments = prefix + os.fsencode(os.path.normpath(item[b'path'])).split(b'/') path = item.pop(b'path')
del item[b'path'] segments = prefix + os.fsencode(os.path.normpath(path)).split(b'/')
num_segments = len(segments) num_segments = len(segments)
parent = 1 parent = 1
for i, segment in enumerate(segments, 1): for i, segment in enumerate(segments, 1):
# Leaf segment? # Leaf segment?
if i == num_segments: if i == num_segments:
if b'source' in item and stat.S_ISREG(item[b'mode']): if b'source' in item and stat.S_ISREG(item[b'mode']):
inode = self._find_inode(item[b'source'], prefix) try:
inode = self._find_inode(item[b'source'], prefix)
except KeyError:
file = path.decode(errors='surrogateescape')
source = item[b'source'].decode(errors='surrogateescape')
logger.warning('Skipping broken hard link: %s -> %s', file, source)
continue
item = self.cache.get(inode) item = self.cache.get(inode)
item[b'nlink'] = item.get(b'nlink', 1) + 1 item[b'nlink'] = item.get(b'nlink', 1) + 1
self.items[inode] = item self.items[inode] = item