Page MenuHomeFreeBSD

fix the performance of cp(1) when copying large non-sparse files
ClosedPublic

Authored by rmacklem on Jan 2 2021, 11:51 PM.

Details

Summary

PR252358 reported a serious performance problem
when copying a large non-sparse file on a UFS file
system.
This problem seems to have been caused by a large
number of SEEK_HOLE operations, with one done
for each copy_file_range(2) call.

This patch modifies cp(1) to use a large (SSIZE_MAX)
len argument, reducing the number of system calls
and resolving the performance issue.

While here, convert the type of the "rcount" from "int"
to "ssize_t" so that it is consistent with that returned
by both read(2) and copy_file_range(2).

Test Plan

Tested by copying both large non-sparse and
large sparse files via cp(1) and timing how long
the copy takes.

The copy of the non-sparse file now completes
20% faster than dd(1) for the same file, for my
test case.

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.