From b76679c1c78baa3677797c85724e81d73edaf139 Mon Sep 17 00:00:00 2001 From: oromenahar Date: Thu, 27 Jul 2023 20:32:34 +0200 Subject: [PATCH] BRT should return EOPNOTSUPP Return the more descriptive EOPNOTSUPP instead of EXDEV when the storage pool doesn't support block cloning. Reviewed-by: Brian Behlendorf Reviewed-by: Rob Norris Signed-off-by: Kay Pedersen Closes #15097 --- module/os/freebsd/zfs/zfs_vnops_os.c | 2 +- module/zfs/zfs_vnops.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index 7692200ab250..45cf6fdfc409 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -6290,7 +6290,7 @@ zfs_freebsd_copy_file_range(struct vop_copy_file_range_args *ap) error = zfs_clone_range(VTOZ(invp), ap->a_inoffp, VTOZ(outvp), ap->a_outoffp, &len, ap->a_outcred); - if (error == EXDEV) + if (error == EXDEV || error == EOPNOTSUPP) goto bad_locked_fallback; *ap->a_lenp = (size_t)len; out_locked: diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 3ebd2d0ff7c5..54ea43363bfc 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -1078,6 +1078,16 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp, return (SET_ERROR(EXDEV)); } + /* + * outos and inos belongs to the same storage pool. + * see a few lines above, only one check. + */ + if (!spa_feature_is_enabled(dmu_objset_spa(outos), + SPA_FEATURE_BLOCK_CLONING)) { + zfs_exit_two(inzfsvfs, outzfsvfs, FTAG); + return (SET_ERROR(EOPNOTSUPP)); + } + ASSERT(!outzfsvfs->z_replay); error = zfs_verify_zp(inzp); @@ -1088,12 +1098,6 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp, return (error); } - if (!spa_feature_is_enabled(dmu_objset_spa(outos), - SPA_FEATURE_BLOCK_CLONING)) { - zfs_exit_two(inzfsvfs, outzfsvfs, FTAG); - return (SET_ERROR(EXDEV)); - } - /* * We don't copy source file's flags that's why we don't allow to clone * files that are in quarantine.