mirror of https://github.com/borgbackup/borg.git
safer truncate_and_unlink implementation
the previous implementation caused collateral damage on hardlink-copies of a repository, see: https://github.com/borgbackup/borg/discussions/6286
This commit is contained in:
parent
6c5e818510
commit
4a2ab496e0
|
@ -207,10 +207,10 @@ def secure_erase(path):
|
|||
|
||||
def truncate_and_unlink(path):
|
||||
"""
|
||||
Truncate and then unlink *path*.
|
||||
Safely unlink (delete) *path*.
|
||||
|
||||
Do not create *path* if it does not exist.
|
||||
Open *path* for truncation in r+b mode (=O_RDWR|O_BINARY).
|
||||
If we run out of space while deleting the file, we try truncating it first.
|
||||
BUT we truncate only if path is the only hardlink referring to this content.
|
||||
|
||||
Use this when deleting potentially large files when recovering
|
||||
from a VFS error such as ENOSPC. It can help a full file system
|
||||
|
@ -218,12 +218,26 @@ def truncate_and_unlink(path):
|
|||
in repository.py for further explanations.
|
||||
"""
|
||||
try:
|
||||
os.unlink(path)
|
||||
except OSError as unlink_err:
|
||||
if unlink_err.errno != errno.ENOSPC:
|
||||
# not free space related, give up here.
|
||||
raise
|
||||
# we ran out of space while trying to delete the file.
|
||||
st = os.stat(path)
|
||||
if st.st_nlink > 1:
|
||||
# rather give up here than cause collateral damage to the other hardlink.
|
||||
raise
|
||||
# no other hardlink! try to recover free space by truncating this file.
|
||||
try:
|
||||
# Do not create *path* if it does not exist, open for truncation in r+b mode (=O_RDWR|O_BINARY).
|
||||
with open(path, 'r+b') as fd:
|
||||
fd.truncate()
|
||||
except OSError as err:
|
||||
if err.errno != errno.ENOTSUP:
|
||||
raise
|
||||
# don't crash if the above ops are not supported.
|
||||
except OSError:
|
||||
# truncate didn't work, so we still have the original unlink issue - give up:
|
||||
raise unlink_err
|
||||
else:
|
||||
# successfully truncated the file, try again deleting it:
|
||||
os.unlink(path)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue