diff --git a/share/man/man9/VOP_COPY_FILE_RANGE.9 b/share/man/man9/VOP_COPY_FILE_RANGE.9 --- a/share/man/man9/VOP_COPY_FILE_RANGE.9 +++ b/share/man/man9/VOP_COPY_FILE_RANGE.9 @@ -29,7 +29,7 @@ .Sh NAME .Nm VOP_COPY_FILE_RANGE .Nd copy a byte range from one file to another or within one file -in a single file system +in a single file system or between multiple file systems of the same type .Sh SYNOPSIS .In sys/param.h .In sys/vnode.h diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -3906,6 +3906,10 @@ ap->a_incred, ap->a_outcred, ap->a_fsizetd)); } + /* We support copy_file_range() only on the same mountpoint */ + if (invp->v_mount != outvp->v_mount) + goto generic_copy; + /* Lock both vnodes, avoiding risk of deadlock. */ do { mp = NULL; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3076,12 +3076,15 @@ goto out; /* - * If the two vnode are for the same file system, call - * VOP_COPY_FILE_RANGE(), otherwise call vn_generic_copy_file_range() - * which can handle copies across multiple file systems. + * If the two vnode are for the same file system or for the + * same file system type, call VOP_COPY_FILE_RANGE(), otherwise + * call vn_generic_copy_file_range() which can handle copies across + * multiple file systems. */ *lenp = len; - if (invp->v_mount == outvp->v_mount) + if ((invp->v_mount == outvp->v_mount) || + (strcmp(invp->v_mount->mnt_vfc->vfc_name, + outvp->v_mount->mnt_vfc->vfc_name) == 0)) error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp, lenp, flags, incred, outcred, fsize_td); else