[Bug 3979] Use reflink for fast cross filesystem copy and rename

bugzilla-daemon at mindrot.org bugzilla-daemon at mindrot.org
Wed Jul 15 08:38:50 AEST 2026


https://bugzilla.mindrot.org/show_bug.cgi?id=3979

Darren Tucker <dtucker at dtucker.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dtucker at dtucker.net

--- Comment #4 from Darren Tucker <dtucker at dtucker.net> ---
(In reply to Darren Moffat from comment #3)
> Reflink isn't a macro it is defined in <unistd.h> as:
> 
> #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
> extern int reflink(const char *, const char *, int);
> extern int reflinkat(int, const char *, int, const char *, int, int);

I dunno if your compiler differs, but at least as far as gcc is
concerned a function declaration is not a definition according to the
preprocessor:

$ uname -a
SunOS sol11 5.11 11.4.0.15.0 i86pc i386 i86pc

$ cat test.c
#include <stdio.h>
#include <unistd.h>

int main(void)
{
#ifdef reflink
        printf("reflink defined.\n");
#else
        printf("reflink NOT defined.\n");
#endif
        int r = reflink(NULL, NULL, 0);
        printf("reflink returned %d\n", r);
}

$ gcc -Wall test.c && ./a.out
reflink NOT defined.
reflink returned -1

If I remove the unistd.h include I get:

$ gcc -Wall test.c && ./a.out
test.c: In function 'main':
test.c:11:10: warning: implicit declaration of function 'reflink'; did
you mean 'getline'? [-Wimplicit-function-declaration]
  int r = reflink(NULL, NULL, 0);
          ^~~~~~~
          getline
reflink NOT defined.
reflink returned -1

so the previous test definitely *declared* reflink, but didn't *define*
it according to the preprocessor.  I don't think the first part of your
proof-of-concept patch tested what what you thought it did.

> reflink might not be in Illumos or FreeBSD, it was added to Solaris
> 11.4.  You can get a fairly recent Solaris 11.4 CBE release see:
> https://blogs.oracle.com/solaris/whats-new-in-the-oracle-solaris-
> 11481-cbe-release
> 
> reflink is available on Linux kernels as well:
> https://lwn.net/Articles/331808/

That's an old proposal, AFAICT it never went in in that form.  It's
certainly not in Fedora 44.  The equivalent that did go in is
apparently the FICLONE and FICLONERANGE ioctls
(https://man7.org/linux/man-pages/man2/ioctl_ficlone.2.html) which uses
FDs not pathnames and could potentially be used for this.

[...]
> There is a possible speed up in copy-data by using sendfile(2).

sendfile would probably help a bit by avoiding userspace copies.

> Maybe the only way to use reflink() for fast copy is via a new
> extension because the client would need to send just the file names.

That seems like a pretty niche use case.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
You are watching someone on the CC list of the bug.


More information about the openssh-bugs mailing list