Re: [PATCH v2] [PATCH v2] io_uring/register: add IORING_REGISTER_CLONE_FILES opcode

From: Harshal Chavan

Date: Fri Jun 19 2026 - 03:33:55 EST


On 6/17/26 14:54, Jens Axboe wrote:
> Not sure the offsets and partial copies are going to be worth it, but
> I'm willing to have my mind changed. But that's a minor thing really.
>
> Also a question whether the destination should've already allocated a
> sparse table. This kind of bundles the two into one. In general, as
> mention on the GH link, I do think this should work exactly like cloning
> buffers. It'd be somewhat confusing if they don't match up, as it's
> essentially the same operation, just on a different node type.


> > + /* Copy original dst nodes from before the cloned range */
> > + for (i = 0; i < min(arg->dst_off, ctx->file_table.data.nr); i++) {
> > + struct io_rsrc_node *node = ctx->file_table.data.nodes[i];
> > +
> > + if (node) {
> > + new_file_table.data.nodes[i] = node;
> > + node->refs++;
> > + io_file_bitmap_set(&new_file_table, i);
> > + }
> > + }
>
> This definitely won't work - I also mentioned in the GH link that nodes
> cannot be shared, you have to allocate new nodes on the destination
> side.

> The file nodes rely on non-atomic refs when being used, which is
> protected by the ctx->uring_lock as that's always held for the fast path
> issue. If you just assign the node by reference, now you have two
> different rings manipulating the same node in memory, but they don't
> agree on synchronization.

Thanks for the detailed explanation.
In v3, I have rewritten the cloning loops to utilize a new
helper function. It strictly calls io_rsrc_node_alloc(), get_file(),
and io_fixed_file_set() for every single transferred node. We no longer
share references across rings; the destination ring is fully populated
with its own newly allocated, private nodes to avoid any non-atomic
reference races.