git: e3b27cc3546f - stable/14 - copy_file_range: Call vn_rdwr() at least once
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 May 2024 13:07:44 UTC
The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=e3b27cc3546fb39ec579d023b3520d15a1628021 commit e3b27cc3546fb39ec579d023b3520d15a1628021 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2024-04-04 15:18:03 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2024-05-08 13:06:16 +0000 copy_file_range: Call vn_rdwr() at least once This ensures that we invoke VOP_READ on the input file even if it's empty, which in turn helps ensure that filesystems update the atime of the file. PR: 274615 Reviewed by: olce, rmacklem, kib MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D43524 (cherry picked from commit 08f3d5b60cdfff434e391d96cdffc5a90c550b07) --- sys/kern/vfs_vnops.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 51386d0e9581..1171b72a3a96 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3341,7 +3341,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, off_t startoff, endoff, xfer, xfer2; u_long blksize; int error, interrupted; - bool cantseek, readzeros, eof, lastblock, holetoeof, sparse; + bool cantseek, readzeros, eof, first, lastblock, holetoeof, sparse; ssize_t aresid, r = 0; size_t copylen, len, savlen; off_t outsize; @@ -3482,6 +3482,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, endts.tv_sec++; } else timespecclear(&endts); + first = true; holetoeof = eof = false; while (len > 0 && error == 0 && !eof && interrupted == 0) { endoff = 0; /* To shut up compilers. */ @@ -3583,10 +3584,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, */ xfer -= (*inoffp % blksize); } - /* Loop copying the data block. */ - while (copylen > 0 && error == 0 && !eof && interrupted == 0) { + + /* + * Loop copying the data block. If this was our first attempt + * to copy anything, allow a zero-length block so that the VOPs + * get a chance to update metadata, specifically the atime. + */ + while (error == 0 && ((copylen > 0 && !eof) || first) && + interrupted == 0) { if (copylen < xfer) xfer = copylen; + first = false; error = vn_lock(invp, LK_SHARED); if (error != 0) goto out; @@ -3596,7 +3604,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, curthread); VOP_UNLOCK(invp); lastblock = false; - if (error == 0 && aresid > 0) { + if (error == 0 && (xfer == 0 || aresid > 0)) { /* Stop the copy at EOF on the input file. */ xfer -= aresid; eof = true;