From ba662d28195da81a85a8b2ef9b716f9ea9cbc575 Mon Sep 17 00:00:00 2001 From: Rusty Bird Date: Fri, 17 Jan 2020 15:56:51 +0000 Subject: [PATCH] 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.) --- qubes/storage/reflink.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qubes/storage/reflink.py b/qubes/storage/reflink.py index 4a4812a3..436658aa 100644 --- a/qubes/storage/reflink.py +++ b/qubes/storage/reflink.py @@ -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):