summaryrefslogtreecommitdiffstats
path: root/src/shared/copy.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-04-28 15:16:00 +0200
committerLennart Poettering <lennart@poettering.net>2023-04-28 15:16:30 +0200
commit535358ad2e0f844c77dbacff37ad456e8ffed8a2 (patch)
treeecdd6946ab27a535d989777d534bab73f5a04eca /src/shared/copy.c
parentcopy: don't call clone ioctls twice (diff)
downloadsystemd-535358ad2e0f844c77dbacff37ad456e8ffed8a2.tar.xz
systemd-535358ad2e0f844c77dbacff37ad456e8ffed8a2.zip
copy: shortcut reflink_range() to reflink() in some cases
Diffstat (limited to '')
-rw-r--r--src/shared/copy.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/shared/copy.c b/src/shared/copy.c
index 90c6e2c0ef..14b9b61d8a 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -1631,6 +1631,12 @@ int reflink_range(int infd, uint64_t in_offset, int outfd, uint64_t out_offset,
assert(infd >= 0);
assert(outfd >= 0);
+ /* Inside the kernel, FICLONE is identical to FICLONERANGE with offsets and size set to zero, let's
+ * simplify things and use the simple ioctl in that case. Also, do the same if the size is
+ * UINT64_MAX, which is how we usually encode "everything". */
+ if (in_offset == 0 && out_offset == 0 && IN_SET(sz, 0, UINT64_MAX))
+ return reflink(infd, outfd);
+
r = fd_verify_regular(outfd);
if (r < 0)
return r;