mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-06 16:40:47 +00:00
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
This commit is contained in:
parent
c1326c01df
commit
08f3d5b60c
|
@ -3339,7 +3339,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;
|
||||
|
@ -3480,6 +3480,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. */
|
||||
|
@ -3581,10 +3582,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;
|
||||
|
@ -3594,7 +3602,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;
|
||||
|
|
Loading…
Reference in a new issue