Re: What is needed for ZFS block cloning to work?

Rick Macklem <[email protected]> Sun, 12 Jul 2026 17:18:46 -0700
Newsgroups gmane.os.freebsd.devel.file-systems
Message-ID <CAM5tNy4PaMxxo5oSNLkY_AD+SsSUxkJe+=S_cs9y_Pz987Hs3Q@mail.gmail.com>
On Sun, Jul 12, 2026 at 5:07=E2=80=AFPM Rob Norris <[email protected]> w=
rote:
>
> On Mon, 13 Jul 2026, at 6:01 AM, John F Carr wrote:
>
> Is copy_file_range supposed to use cloning when copying between children =
of
> the same encrypted filesystem?  Or only within a filesystem?
Did you see a EXDEV return from the copy_file_range(2) syscall or from
zfs_clone_range() inside the ZFS code?
If it was the latter, ZFS's VOP_COPY_FILE_RANGE() should return ENOSYS,
which gets the copy done via vn_generic_copy_file_range() in the syscall.
(vn_generic_copy_file_range() just loops around, doing VOP_READ()/VOP_WRITE=
().
It does try to find holes and that's why it can be slow when
vfs.zfs.dmu_offset_next_sync=3D1.

>
>
> Within the same "clone group", which is a filesystem/zvol, its snapshots,=
 and clones created from those snapshots (ie via zfs clone). All datasets w=
ithin such a group share a master key, so a block created in one can be dec=
rypted in another.
>
> Note that "clone group" is not the same thing as "encryption root" - data=
sets with the same encryption root share a wrapping key, but not necessaril=
y the same master key.
>
> I'll note here a possible misunderstanding that I see a lot. For copy_fil=
e_range(), block cloning is an implementation detail. copy_file_range()'s p=
urpose is to ask the kernel to make a logical copy of some data, by whateve=
r means its chooses. It's reasonable to wonder about when cloning is chosen=
 as an academic exercise, but the only thing the call guarantees on success=
 is that reading back the source and destination will yield the same bytes;=
 the underlying structure is irrelevant.
>
> None of that is to say that it shouldn't be more controllable or predicta=
ble, but it would need more work. On Linux the FICLONERANGE ioctl is (effec=
tively) the same as copy_file_range(), but it _must_ clone, or fail. Again =
on Linux, the FIEMAP ioctl or something like it would allow inspecting the =
underlying structure of the object in question (ZFS on Linux implements FIC=
LONERANGE but not FIEMAP, yet). A richer error/result return path would all=
ow us to return back to userspace why a clone didn't happen, but I'm not su=
re that there's any really pleasant facility out there for such things.

For FreeBSD, if cloning or failure of the copy_file_range(2) syscall is
desired, the flag argument COPY_FILE_RANGE_CLONE can be specified.
(to avoid the fallback to the copy loop in the kernel syscall)

rick

>
> Rob.