[Bug 3979] Use reflink for fast cross filesystem copy and rename
bugzilla-daemon at mindrot.org
bugzilla-daemon at mindrot.org
Tue Jul 14 14:00:25 AEST 2026
https://bugzilla.mindrot.org/show_bug.cgi?id=3979
--- Comment #2 from Darren Tucker <dtucker at dtucker.net> ---
Comment on attachment 3972
--> https://bugzilla.mindrot.org/attachment.cgi?id=3972
Proof of Concept patch
>+#ifdef reflink
>+ if (reflink(oldpath, newpath, 1) == -1) {
>+#else
Is "reflink" actually a macro? It's not on the Solaris 11 VM I have
handy so won't this be a no-op?
>+static int
>+copy_data_via_reflink(uint32_t id)
>+{
>+ char *oldpath, *newpath;
>+ int r;
>+
>+ if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
>+ (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
>+ fatal_fr(r, "parse");
>+
>+ debug("request %u: copy-data via reflink from \"%s\" "
>+ "to \"%s\"", oldpath, newpath);
>+ r = reflink(oldpath, newpath, 1);
>+ free(oldpath);
>+ free(newpath);
>+
>+ return (r);
>+}
>+
> static void
> process_extended_copy_data(uint32_t id)
> {
>@@ -1997,6 +2020,10 @@
> int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED;
> size_t ret;
>
>+ if (copy_data_via_reflink(id) == 0) {
>+ status = SSH2_FX_OK;
>+ goto out;
>+ }
How does this work? copy_data_via_reflink() takes two pathnames, but
process_extended_copy_data() takes two file handles, two offsets and a
length.
A couple of other general questions:
1) it seems like reflink(2) is Solaris-specific? it doesn't seem to be
present in the Illumos or FreeBSD versions I have handy.
2) is reflink(2) atomic like like(2) is?
> The sftp-server copy-data can be implemented using reflink() with a fallback to the existing read/write loop.
reflink() only seems to support a subset of the functionality of
extended-copy-data: both offsets and length all being zero so assuming
it could be made to work that'd have to be checked too.
--
You are receiving this mail because:
You are watching the assignee of the bug.
More information about the openssh-bugs
mailing list