The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=045d603aa1580752d5c7a9a8c6021e4dddd7d8b2

commit 045d603aa1580752d5c7a9a8c6021e4dddd7d8b2
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2023-11-18 08:57:44 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2023-12-05 00:44:13 +0000

    vn_copy_file_range(): find write vnodes on which to call the VOP
    
    (cherry picked from commit a9bc8637690ce29496650a41d3c25e225ed22e3d)
---
 sys/kern/vfs_vnops.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 48737be64beb..e37518ebaaa1 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -3027,10 +3027,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;
@@ -3056,17 +3058,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);
@@ -3077,7 +3084,7 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, 
struct vnode *outvp,
                                vfs_unbusy(outmp);
                                continue;
                        }
-                       goto out;
+                       goto out2;
                }
                break;
        }
@@ -3089,14 +3096,20 @@ vn_copy_file_range(struct vnode *invp, off_t *inoffp, 
struct vnode *outvp,
         */
        *lenp = len;
        if (inmp == outmp)
-               error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp,
+               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);
 }

Reply via email to