Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 3,255 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
int | int | ||||
vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, | vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, | ||||
struct vnode *outvp, off_t *outoffp, size_t *lenp, unsigned int flags, | struct vnode *outvp, off_t *outoffp, size_t *lenp, unsigned int flags, | ||||
struct ucred *incred, struct ucred *outcred, struct thread *fsize_td) | struct ucred *incred, struct ucred *outcred, struct thread *fsize_td) | ||||
{ | { | ||||
struct vattr va, inva; | struct vattr va, inva; | ||||
struct mount *mp; | struct mount *mp; | ||||
struct uio io; | |||||
off_t startoff, endoff, xfer, xfer2; | off_t startoff, endoff, xfer, xfer2; | ||||
u_long blksize; | u_long blksize; | ||||
int error, interrupted; | int error, interrupted; | ||||
bool cantseek, readzeros, eof, lastblock, holetoeof; | bool cantseek, readzeros, eof, lastblock, holetoeof; | ||||
ssize_t aresid; | ssize_t aresid, r = 0; | ||||
size_t copylen, len, rem, savlen; | size_t copylen, len, rem, savlen; | ||||
char *dat; | char *dat; | ||||
long holein, holeout; | long holein, holeout; | ||||
struct timespec curts, endts; | struct timespec curts, endts; | ||||
holein = holeout = 0; | holein = holeout = 0; | ||||
savlen = len = *lenp; | savlen = len = *lenp; | ||||
error = 0; | error = 0; | ||||
Show All 12 Lines | if (error != 0) | ||||
goto out; | goto out; | ||||
mp = NULL; | mp = NULL; | ||||
error = vn_start_write(outvp, &mp, V_WAIT); | error = vn_start_write(outvp, &mp, V_WAIT); | ||||
if (error == 0) | if (error == 0) | ||||
error = vn_lock(outvp, LK_EXCLUSIVE); | error = vn_lock(outvp, LK_EXCLUSIVE); | ||||
if (error == 0) { | if (error == 0) { | ||||
/* | /* | ||||
* If fsize_td != NULL, do a vn_rlimit_fsize() call, | * If fsize_td != NULL, do a vn_rlimit_fsizex() call, | ||||
* now that outvp is locked. | * now that outvp is locked. | ||||
*/ | */ | ||||
if (fsize_td != NULL) { | if (fsize_td != NULL) { | ||||
struct uio io; | |||||
io.uio_offset = *outoffp; | io.uio_offset = *outoffp; | ||||
io.uio_resid = len; | io.uio_resid = len; | ||||
error = vn_rlimit_fsize(outvp, &io, fsize_td); | error = vn_rlimit_fsizex(outvp, &io, 0, &r, fsize_td); | ||||
len = savlen = io.uio_resid; | |||||
/* | |||||
* No need to call vn_rlimit_fsizex_res before return, | |||||
* since the uio is local. | |||||
*/ | |||||
} | } | ||||
if (VOP_PATHCONF(outvp, _PC_MIN_HOLE_SIZE, &holeout) != 0) | if (VOP_PATHCONF(outvp, _PC_MIN_HOLE_SIZE, &holeout) != 0) | ||||
holeout = 0; | holeout = 0; | ||||
/* | /* | ||||
* Holes that are past EOF do not need to be written as a block | * Holes that are past EOF do not need to be written as a block | ||||
* of zero bytes. So, truncate the output file as far as | * of zero bytes. So, truncate the output file as far as | ||||
* possible and then use va.va_size to decide if writing 0 | * possible and then use va.va_size to decide if writing 0 | ||||
* bytes is necessary in the loop below. | * bytes is necessary in the loop below. | ||||
▲ Show 20 Lines • Show All 509 Lines • Show Last 20 Lines |