storage/reflink: native FICLONE in _copy_file() happy path

Avoid a subprocess launch, and distinguish reflink vs. fallback copy in
the log.
This commit is contained in:
Rusty Bird 2018-09-11 23:50:14 +00:00
parent edda3a1734
commit 3d986be02a
No known key found for this signature in database
GPG Key ID: 469D78F47AAF2ADF

View File

@ -412,14 +412,17 @@ def _attempt_ficlone(src, dst):
def _copy_file(src, dst): def _copy_file(src, dst):
''' Copy src to dst as a reflink if possible, sparse if not. ''' ''' Copy src to dst as a reflink if possible, sparse if not. '''
if not os.path.exists(src): with _replace_file(dst) as tmp_io:
raise FileNotFoundError(src) with open(src, 'rb') as src_io:
with _replace_file(dst) as tmp: if _attempt_ficlone(src_io, tmp_io):
LOGGER.info('Copying file: %s -> %s', src, tmp.name) LOGGER.info('Reflinked file: %s -> %s', src, tmp_io.name)
cmd = 'cp', '--sparse=always', '--reflink=auto', src, tmp.name return True
LOGGER.info('Copying file: %s -> %s', src, tmp_io.name)
cmd = 'cp', '--sparse=always', src, tmp_io.name
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if p.returncode != 0: if p.returncode != 0:
raise qubes.storage.StoragePoolException(str(p)) raise qubes.storage.StoragePoolException(str(p))
return False
def is_reflink_supported(dst_dir, src_dir=None): def is_reflink_supported(dst_dir, src_dir=None):
''' Return whether destination directory supports reflink copies ''' Return whether destination directory supports reflink copies