GNU bug report logs -
#60416
Be more liberal using copy_file_range() with NFS mounted filesystems
Previous Next
Reported by: Braiam <braiamp <at> gmail.com>
Date: Fri, 30 Dec 2022 07:04:01 UTC
Severity: normal
Done: Pádraig Brady <P <at> draigBrady.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 60416 in the body.
You can then email your comments to 60416 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Fri, 30 Dec 2022 07:04:01 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Braiam <braiamp <at> gmail.com>
:
New bug report received and forwarded. Copy sent to
bug-coreutils <at> gnu.org
.
(Fri, 30 Dec 2022 07:04:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
When using a nfs export, cp seems to not try hard enough using
copy_file_range(). This was
the conclusion we arrived in this forum thread[1] at Truenas forums.
It was found a way to force
cp to use it, but it should not be necessary, since there are supposed
to be fallbacks.
I'm unsure if we found something that triggered the undesired behavior.
[1]: https://www.truenas.com/community/threads/nfs-does-not-support-server-side-copy-with-zfs.103309/post-712071
--
Braiam
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Fri, 30 Dec 2022 15:34:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 60416 <at> debbugs.gnu.org (full text, mbox):
On 29/12/2022 16:04, Braiam wrote:
> When using a nfs export, cp seems to not try hard enough using
> copy_file_range(). This was
> the conclusion we arrived in this forum thread[1] at Truenas forums.
> It was found a way to force
> cp to use it, but it should not be necessary, since there are supposed
> to be fallbacks.
>
> I'm unsure if we found something that triggered the undesired behavior.
>
> [1]: https://www.truenas.com/community/threads/nfs-does-not-support-server-side-copy-with-zfs.103309/post-712071
>
Currently we don't use copy_file_range() with sparse files,
as per the Linux man page "copy_file_range() may expand any
holes existing in the requested range".
I confirmed that copy_file_range() definitely expands holes
on ext4 on Linux 5.7 at least.
Also the FreeBSD man page says "this system call attempts
to maintain holes in the output file for the byte range being copied.
However, this does not always work well."
Now maybe we should give precedence to server side copy for remote file systems,
though that would be optimizing runtime and network usage
while potentially pessimizing storage usage
if holes were expanded in the destination.
Now fundamentally copy_file_range() isn't restricted from
maintaining holes from source to destination,
which suggests we could give precedence to copy_file_range()
on remote file systems.
Also perhaps we can improve the heuristic somehow,
even again just for remote file systems.
Maybe determine a file is sparse on remote systems
only if it seems that more than half of the file is sparse.
For completeness, one might be wondering why we're using
copy_file_range() at all with --sparse=never, as that syscall
doesn't guarantee sparseness. However in this case we
only use copy_file_range() with the portion of the file
considered non sparse (and manually write the zeros)¹.
So in summary pseudo code could be:
sparse_file = blocks < size/blocksize;
very_sparse_file = blocks < (size/2)/blocksize;
if ( (!possible_hole_in_range || sparse_mode=auto)
&& reflinks_allowed
&& (
(remote_file && !very_sparse_file)
|| (!remote_file && !sparse_file)
)
)
copy_file_range(...);
Note `stat <your files>; df -T <your files>` would
give us some concrete heuristics for your case at least.
Note it would be useful to get such stats from files
that were completely copied by copy_file_range() on your systems
(i.e. not by cp), to see if holes were expanded for your case.
cheers,
Pádraig
¹ Actually I now notice that where SEEK_HOLE is _not_ available
and copy_file_range() is, then `cp --sparse=never` would not be honored,
as copy_file_range() would expand the holes (confirmed on ext4 at least).
Now I don't know of any practical systems having copy_file_range()
and not having SEEK_HOLE, but I might add the constraint to the code,
at least for clarification reasons.
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Fri, 30 Dec 2022 19:53:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 60416 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 30/12/2022 15:33, Pádraig Brady wrote:
> On 29/12/2022 16:04, Braiam wrote:
>> When using a nfs export, cp seems to not try hard enough using
>> copy_file_range(). This was
>> the conclusion we arrived in this forum thread[1] at Truenas forums.
>> It was found a way to force
>> cp to use it, but it should not be necessary, since there are supposed
>> to be fallbacks.
>>
>> I'm unsure if we found something that triggered the undesired behavior.
>>
>> [1]: https://www.truenas.com/community/threads/nfs-does-not-support-server-side-copy-with-zfs.103309/post-712071
>>
>
> Currently we don't use copy_file_range() with sparse files,
> as per the Linux man page "copy_file_range() may expand any
> holes existing in the requested range".
> I confirmed that copy_file_range() definitely expands holes
> on ext4 on Linux 5.7 at least.
> Also the FreeBSD man page says "this system call attempts
> to maintain holes in the output file for the byte range being copied.
> However, this does not always work well."
>
> Now maybe we should give precedence to server side copy for remote file systems,
> though that would be optimizing runtime and network usage
> while potentially pessimizing storage usage
> if holes were expanded in the destination.
>
> Now fundamentally copy_file_range() isn't restricted from
> maintaining holes from source to destination,
> which suggests we could give precedence to copy_file_range()
> on remote file systems.
>
> Also perhaps we can improve the heuristic somehow,
> even again just for remote file systems.
> Maybe determine a file is sparse on remote systems
> only if it seems that more than half of the file is sparse.
>
> For completeness, one might be wondering why we're using
> copy_file_range() at all with --sparse=never, as that syscall
> doesn't guarantee sparseness. However in this case we
> only use copy_file_range() with the portion of the file
> considered non sparse (and manually write the zeros)¹.
>
> So in summary pseudo code could be:
>
> sparse_file = blocks < size/blocksize;
> very_sparse_file = blocks < (size/2)/blocksize;
>
> if ( (!possible_hole_in_range || sparse_mode=auto)
> && reflinks_allowed
> && (
> (remote_file && !very_sparse_file)
> || (!remote_file && !sparse_file)
> )
> )
> copy_file_range(...);
>
>
> Note `stat <your files>; df -T <your files>` would
> give us some concrete heuristics for your case at least.
> Note it would be useful to get such stats from files
> that were completely copied by copy_file_range() on your systems
> (i.e. not by cp), to see if holes were expanded for your case.
>
> cheers,
> Pádraig
>
> ¹ Actually I now notice that where SEEK_HOLE is _not_ available
> and copy_file_range() is, then `cp --sparse=never` would not be honored,
> as copy_file_range() would expand the holes (confirmed on ext4 at least).
> Now I don't know of any practical systems having copy_file_range()
> and not having SEEK_HOLE, but I might add the constraint to the code,
> at least for clarification reasons.
Looking a bit closer at things, the current code does something like:
if file appears sparse
use SEEK_DATA to iterate over data parts,
try writing data with copy_file_range() if sparse_mode == never
(as thinking was there is no need to look for additional holes)
else
use copy_file_range if sparse_never || sparse_auto
Now the use of copy_file_range() with sparse=never may be problematic,
as assumes copy_file_range() won't add additional holes.
This is problematic in first case as SEEK_HOLE is best effort,
and in the second (else) case as file sparseness is a heuristic.
Also from above analysis the OP's case seems to be first sparse case,
as in second (else) case, with --sparse=auto, copy_file_range()
would have been used (as file appears non sparse (so plain scan used)).
So while we theoretically should only be allowing copy_file_range()
with --sparse=auto, we definitely should not be precluding it in the first
case with that sparse mode.
I.e. for the first case we should only disallow copy_file_range() with
sparse=ALWAYS, because --sparse=auto is best effort, and we've enough
signal from SEEK_DATA as to the likelihood of processing holes or not.
The attached makes that change.
It would be great if you could test that on your systems.
To that end you might find the following tarball useful,
which has the patch already applied:
https://pixelbeat.org/cu/coreutils-9.1.109-bd17b.tar.xz
which can be built like:
tar -xf coreutils-9.1.109-bd17b.tar.xz
cd coreutils-9.1.109-bd17b/
./configure && make -j $(nproc)
then tested with:
src/cp ...
cheers,
Pádraig
[copy-sparse-offload.patch (text/x-patch, attachment)]
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Fri, 30 Dec 2022 22:33:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 60416 <at> debbugs.gnu.org (full text, mbox):
Thanks, looks good, please install.
Reply sent
to
Pádraig Brady <P <at> draigBrady.com>
:
You have taken responsibility.
(Sat, 31 Dec 2022 00:24:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
Braiam <braiamp <at> gmail.com>
:
bug acknowledged by developer.
(Sat, 31 Dec 2022 00:24:02 GMT)
Full text and
rfc822 format available.
Message #19 received at 60416-done <at> debbugs.gnu.org (full text, mbox):
On 30/12/2022 22:32, Paul Eggert wrote:
> Thanks, looks good, please install.
Thanks for the review.
OP also posted good results.
Pushed with NEWS entry.
Marking this as done.
I may follow up with a related patch to
ensure we _don't_ use copy_file_range with --sparse=never.
cheers,
Pádraig
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Sat, 31 Dec 2022 01:37:02 GMT)
Full text and
rfc822 format available.
Message #22 received at 60416-done <at> debbugs.gnu.org (full text, mbox):
On 2022-12-30 16:23, Pádraig Brady wrote:
>
> I may follow up with a related patch to
> ensure we _don't_ use copy_file_range with --sparse=never.
Not sure it's worth the bother. A file system that would create holes
with copy_file_range could also do so with plain 'write', no?
Information forwarded
to
bug-coreutils <at> gnu.org
:
bug#60416
; Package
coreutils
.
(Sat, 31 Dec 2022 12:05:01 GMT)
Full text and
rfc822 format available.
Message #25 received at 60416-done <at> debbugs.gnu.org (full text, mbox):
On 31/12/2022 01:36, Paul Eggert wrote:
> On 2022-12-30 16:23, Pádraig Brady wrote:
>>
>> I may follow up with a related patch to
>> ensure we _don't_ use copy_file_range with --sparse=never.
>
> Not sure it's worth the bother. A file system that would create holes
> with copy_file_range could also do so with plain 'write', no?
Well copy_file_range() would be lower level and within its
remit to propagate holes. The FreeBSD docs allude to this also.
But yes, our use of copy_file_range() is generally restricted
to non holes, so less of an issue for us.
Also there may be users using `cp --sparse=never` to avoid
the perf issue currently, like we saw on the OP web thread.
I'll hold off on that change so.
Hopefully copy_file_range() flags are introduced to give
control over this (like I suggested on lkml years ago).
cheers,
Pádraig
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sat, 28 Jan 2023 12:24:05 GMT)
Full text and
rfc822 format available.
This bug report was last modified 2 years and 138 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.