Re: [PATCH] fs: skip copy_file_range write limits when there is no data
From: Amir Goldstein
Date: Mon Oct 26 2026 - 05:04:26 EST
On Mon, Oct 26, 2026 at 3:58 AM Hungyu Lin <dennylin0707@xxxxxxxxx> wrote:
>
> generic_copy_file_checks() reduces count to zero for a source offset at
> or beyond EOF, but still checks the destination write limits. If pos_out
> is at RLIMIT_FSIZE, this sends SIGXFSZ and returns -EFBIG even though
> there is no data to write.
>
> For example, GNU cat copying a 1024-byte regular file to another regular
> file with RLIMIT_FSIZE=1024 copies all bytes and is then killed by its
> next copy_file_range() call at EOF. A zero-length request can fail in
> the same way.
>
> Check write limits only when count is nonzero, as the ordinary write
> checks already do. Keep the other copy validation in place.
>
> Fixes: 96e6e8f4a68d ("vfs: add missing checks to copy_file_range")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Hungyu Lin <dennylin0707@xxxxxxxxx>
Thanks for the fix!
Reviewed-by: Amir Goldstein <amir73il@xxxxxxxxx>
> ---
> fs/read_write.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/fs/read_write.c b/fs/read_write.c
> index 4da846a2bf17..c05ad2c42e75 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -1531,9 +1531,11 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
> else
> count = min(count, size_in - (uint64_t)pos_in);
>
> - ret = generic_write_check_limits(file_out, pos_out, &count);
> - if (ret)
> - return ret;
> + if (count) {
> + ret = generic_write_check_limits(file_out, pos_out, &count);
> + if (ret)
> + return ret;
> + }
>
> /* Don't allow overlapped copying within the same file. */
> if (inode_in == inode_out &&
> --
> 2.43.0
>