From owner-svn-src-head@freebsd.org Thu Oct 1 00:33:44 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D01684334EF; Thu, 1 Oct 2020 00:33:44 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4C1vHr4xDlz3yS3; Thu, 1 Oct 2020 00:33:44 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8CA8227E57; Thu, 1 Oct 2020 00:33:44 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0910Xivv029203; Thu, 1 Oct 2020 00:33:44 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0910Xiv8029202; Thu, 1 Oct 2020 00:33:44 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <202010010033.0910Xiv8029202@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Thu, 1 Oct 2020 00:33:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366302 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 366302 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Oct 2020 00:33:44 -0000 Author: rmacklem Date: Thu Oct 1 00:33:44 2020 New Revision: 366302 URL: https://svnweb.freebsd.org/changeset/base/366302 Log: Clip the "len" argument to vn_generic_copy_file_range() at a hole size boundary. By clipping the len argument of vn_generic_copy_file_range() to end at an exact multiple of hole size, holes are more likely to be maintained during the copy. A hole can still straddle the boundary at the end of the copy range, resulting in a block being allocated in the output file as it is being grown in size, but this will reduce the likelyhood of this happening. While here, also modify setting of blksize to better handle the case where _PC_MIN_HOLE_SIZE is returned as 1. Reviewed by: asomers Differential Revision: https://reviews.freebsd.org/D26570 Modified: head/sys/kern/vfs_vnops.c Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Wed Sep 30 22:41:24 2020 (r366301) +++ head/sys/kern/vfs_vnops.c Thu Oct 1 00:33:44 2020 (r366302) @@ -3020,7 +3020,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t * int error; bool cantseek, readzeros, eof, lastblock; ssize_t aresid; - size_t copylen, len, savlen; + size_t copylen, len, rem, savlen; char *dat; long holein, holeout; @@ -3089,7 +3089,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t * * This value is clipped at 4Kbytes and 1Mbyte. */ blksize = MAX(holein, holeout); - if (blksize == 0) + + /* Clip len to end at an exact multiple of hole size. */ + if (blksize > 1) { + rem = *inoffp % blksize; + if (rem > 0) + rem = blksize - rem; + if (len - rem > blksize) + len = savlen = rounddown(len - rem, blksize) + rem; + } + + if (blksize <= 1) blksize = MAX(invp->v_mount->mnt_stat.f_iosize, outvp->v_mount->mnt_stat.f_iosize); if (blksize < 4096)