FreeBSD: Fix RLIMIT_FSIZE handling for block cloning
commitdea8fabf73b1017c396e6331d194bf5f139187c8
authorMark Johnston <markj@FreeBSD.org>
Tue, 23 Jul 2024 14:20:46 +0000 (23 10:20 -0400)
committerTony Hutter <hutter2@llnl.gov>
Thu, 8 Aug 2024 17:43:02 +0000 (8 10:43 -0700)
tree33bce2f94ade190d3a81cb32b631904f3b7e609d
parent1f5bf91a85e93afa17bc9c03fe7fade0852da046
FreeBSD: Fix RLIMIT_FSIZE handling for block cloning

ZFS implements copy_file_range(2) using block cloning when possible.
This implementation must respect the RLIMIT_FSIZE limit.

zfs_clone_range() already checks the limit, so it is safe to remove this
check in zfs_freebsd_copy_file_range().  Moreover, the removed check
produces false positives: the length passed to copy_file_range(2) may be
larger than the input file size; as the man page notes, "for best
performance, call copy_file_range() with the largest len value
possible."  In particular, some existing code passes SSIZE_MAX there.

The check in zfs_clone_range() clamps the length to the input file's
size before checking, but the removed check uses the caller supplied
length, so something like

$ echo a > /tmp/foo
$ limits -f 1024 cat /tmp/foo > /tmp/bar

fails because FreeBSD's cat(1) uses copy_file_range(2) in the manner
described above.

Reported-by: Philip Paeps <philip@FreeBSD.org>
Signed-off-by: Mark Johnston <markj@FreeBSD.org>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
module/os/freebsd/zfs/zfs_vnops_os.c