storage/reflink: bail out early on most FICLONE errnos

Don't fall back on 'cp' if the FICLONE ioctl gives an errno that's not
plausibly reflink specific, because in such a case any fallback could
theoretically mask real but intermittent system/storage errors.

Looking through ioctl_ficlone(2) and the kernel source, it should be
sufficient to do the fallback only on EBADF/EINVAL/EOPNOTSUPP/EXDEV.
(EISDIR/ETXTBSY don't apply to this storage driver, which will never
legitimately attempt to reflink a directory or an active - in the
storage domain - swap file.)
This commit is contained in:
Rusty Bird 2020-01-17 15:56:51 +00:00
parent 90f25890cf
commit ba662d2819
No known key found for this signature in database
GPG Key ID: 469D78F47AAF2ADF

View File

@ -446,7 +446,10 @@ def _attempt_ficlone(src, dst):
try:
fcntl.ioctl(dst.fileno(), FICLONE, src.fileno())
return True
except OSError:
except OSError as ex:
if ex.errno not in (errno.EBADF, errno.EINVAL,
errno.EOPNOTSUPP, errno.EXDEV):
raise
return False
def _copy_file(src, dst):