Mailing List Archive

copy_file_range for File::Copy (or friends)?
Hi all,

I've been going over various libraries and software which
supports copy_file_range / reflinks / file cloning and
noticed Perl doesn't seem to support it natively.

If you're unfamiliar, think of it like `sendfile` on
steroids. For CoW filesystems, it makes a copy lightweight,
and for NFS, it avoids the need for a roundtrip.

I have two questions which I'm wondering about:
1. Does this sound like an idea people are open to for
Perl core's file copying routines?

2. Would File::Copy be the best place for this, given
it currently has no XS? Or would a function need to be
added to Perl itself, and then File::Copy takes advantage of it?

I note that e.g. Sys::Sendfile, IO::SendFile, and File::Copy::clonefile
are varying degrees of prior art in this.

[.Apologies if this isn't the right venue, I asked on #p5p
and it was suggested I ask here if I thought a discussion
might ensue, rather than github issues.]

I'm a long-time Perl writer but first time somewhat-contributor,
so be gentle. Cheers!

best,
sam
Re: copy_file_range for File::Copy (or friends)? [ In reply to ]
On Thu, 06 Jul 2023 06:27:03 +0100
Sam James <sam@gentoo.org> wrote:

> Hi all,
>
> I've been going over various libraries and software which
> supports copy_file_range / reflinks / file cloning and
> noticed Perl doesn't seem to support it natively.
>
> If you're unfamiliar, think of it like `sendfile` on
> steroids. For CoW filesystems, it makes a copy lightweight,
> and for NFS, it avoids the need for a roundtrip.
>
> I have two questions which I'm wondering about:
> 1. Does this sound like an idea people are open to for
> Perl core's file copying routines?

I definitely support making File::Copy faster. Pretty much everything
that copies a file in Perl uses File::Copy, so it would have a big
impact:

https://metacpan.org/module/File::Copy/requires

> 2. Would File::Copy be the best place for this, given
> it currently has no XS? Or would a function need to be
> added to Perl itself, and then File::Copy takes advantage of it?

I see no reason why we can't add XS code to File::Copy. IIRC something
in the toolchain might get confused when a CPAN module update switches
from pure-Perl to XS, but that's not an issue here. File::Copy isn't
dual-life, it isn't installable from CPAN.

The question is, what exactly do you want to do? If you just want to
speed up File::Copy::copy(), with copy_file_range being a hidden
implementation detail, IMO everything should be implemented within
File::Copy.

OTOH, if you want to expose copy_file_range, then it gets more
complicated. It's a very low-level function, it doesn't really fit
File::Copy. And it's not portable. If it were a Windows function, we
could put it in Win32.pm, but we don't have Linux.pm. I guess POSIX.pm
is the closest thing, but I'm not sure if there's a precedent for
putting something Linux-exclusive in there.

>Or would a function need to be
>added to Perl itself, and then File::Copy takes advantage of it?

I don't think it belongs in the interpreter. It's too niche and too
platform-specific. The closest precedent is Internals::getcwd(), but
that's a hack for miniperl only. It exists because miniperl can't use
XS, and there's no reasonable way to get the CWD without it.