git: 7dc643fe15f9 - stable/14 - vn_copy_file_range(): find write vnodes on which to call the VOP
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 05 Dec 2023 00:43:59 UTC
The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=7dc643fe15f9b18e6821fa17402a0a2005095742 commit 7dc643fe15f9b18e6821fa17402a0a2005095742 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-11-18 08:57:44 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-12-05 00:43:27 +0000 vn_copy_file_range(): find write vnodes on which to call the VOP (cherry picked from commit a9bc8637690ce29496650a41d3c25e225ed22e3d) --- sys/kern/vfs_vnops.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 4669296750e4..6e8a6b23eec6 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3072,10 +3072,12 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp, struct ucred *outcred, struct thread *fsize_td) { struct mount *inmp, *outmp; + struct vnode *invpl, *outvpl; int error; size_t len; uint64_t uval; + invpl = outvpl = NULL; len = *lenp; *lenp = 0; /* For error returns. */ error = 0; @@ -3101,17 +3103,22 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp, if (len == 0) goto out; - inmp = invp->v_mount; - outmp = outvp->v_mount; - if (inmp == NULL || outmp == NULL) { - error = EBADF; + error = VOP_GETLOWVNODE(invp, &invpl, FREAD); + if (error != 0) goto out; - } + error = VOP_GETLOWVNODE(outvp, &outvpl, FWRITE); + if (error != 0) + goto out1; + + inmp = invpl->v_mount; + outmp = outvpl->v_mount; + if (inmp == NULL || outmp == NULL) + goto out2; for (;;) { error = vfs_busy(inmp, 0); if (error != 0) - goto out; + goto out2; if (inmp == outmp) break; error = vfs_busy(outmp, MBF_NOWAIT); @@ -3122,7 +3129,7 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp, vfs_unbusy(outmp); continue; } - goto out; + goto out2; } break; } @@ -3133,16 +3140,21 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp, * which can handle copies across multiple file system types. */ *lenp = len; - if (inmp == outmp || strcmp(inmp->mnt_vfc->vfc_name, - outmp->mnt_vfc->vfc_name) == 0) - error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp, + if (inmp == outmp || inmp->mnt_vfc == outmp->mnt_vfc) + error = VOP_COPY_FILE_RANGE(invpl, inoffp, outvpl, outoffp, lenp, flags, incred, outcred, fsize_td); else - error = vn_generic_copy_file_range(invp, inoffp, outvp, + error = vn_generic_copy_file_range(invpl, inoffp, outvpl, outoffp, lenp, flags, incred, outcred, fsize_td); vfs_unbusy(outmp); if (inmp != outmp) vfs_unbusy(inmp); +out2: + if (outvpl != NULL) + vrele(outvpl); +out1: + if (invpl != NULL) + vrele(invpl); out: return (error); }