diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c @@ -1209,6 +1209,10 @@ vfsp->mnt_kern_flag |= MNTK_NO_IOPF; /* vn_io_fault can be used */ vfsp->mnt_kern_flag |= MNTK_NOMSYNC; vfsp->mnt_kern_flag |= MNTK_VMSETSIZE_BUG; + /* + * We support copy_file_range() between multiple filesystems + */ + vfsp->mnt_kern_flag |= MNTK_COPYFR_MULTIFS; #if defined(_KERNEL) && !defined(KMEM_DEBUG) vfsp->mnt_kern_flag |= MNTK_FPLOOKUP; diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -6241,6 +6241,13 @@ int error; uint64_t len = *ap->a_lenp; + /* Make sure that both filesystems are ZFS */ + if ((strcmp(invp->v_mount->mnt_vfc->vfc_name, "zfs") != 0) || (strcmp( + outvp->v_mount->mnt_vfc->vfc_name, "zfs") != 0)) { + mp = NULL; + goto bad_write_fallback; + } + if (!zfs_bclone_enabled) { mp = NULL; goto bad_write_fallback; 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 + * If the two vnode are for the same file system or both filesystems + * support copy_file_range() between multiple filesystems, 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) || + (((invp->v_mount->mnt_kern_flag & MNTK_COPYFR_MULTIFS) != 0) && + ((outvp->v_mount->mnt_kern_flag & MNTK_COPYFR_MULTIFS) != 0))) error = VOP_COPY_FILE_RANGE(invp, inoffp, outvp, outoffp, lenp, flags, incred, outcred, fsize_td); else diff --git a/sys/sys/mount.h b/sys/sys/mount.h --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -493,6 +493,7 @@ #define MNTK_UNLOCKED_INSMNTQUE 0x00001000 /* fs does not lock the vnode for insmntque */ #define MNTK_UNMAPPED_BUFS 0x00002000 #define MNTK_USES_BCACHE 0x00004000 /* FS uses the buffer cache. */ +#define MNTK_COPYFR_MULTIFS 0x00008000 /* FS accepts copy_file_range() between multiple fileystems */ /* UNUSED 0x00008000 */ #define MNTK_VMSETSIZE_BUG 0x00010000 #define MNTK_UNIONFS 0x00020000 /* A hack for F_ISUNIONSTACK */