Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions man/io_uring_clone_files.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
.\" Copyright (C) 2026 Harshal Chavan <harshal24.chavan@gmail.com>
.\"
.\" SPDX-License-Identifier: LGPL-2.0-or-later
.\"
.TH io_uring_clone_files 3 "June 24, 2026" "liburing-2.12" "liburing Manual"
.SH NAME
io_uring_clone_files \- Clones registered files between rings
.SH SYNOPSIS
.nf
.B #include <liburing.h>
.PP
.BI "int io_uring_clone_files(struct io_uring *" dst ","
.BI " struct io_uring * " src ");"
.PP
.BI "int __io_uring_clone_files(struct io_uring *" dst ","
.BI " struct io_uring * " src ","
.BI " unsigned int " flags ");"
.PP
.BI "int io_uring_clone_files_offset(struct io_uring *" dst ","
.BI " struct io_uring * " src ","
.BI " unsigned int " dst_off ","
.BI " unsigned int " src_off ","
.BI " unsigned int " nr ","
.BI " unsigned int " flags ");"
.PP
.BI "int __io_uring_clone_files_offset(struct io_uring *" dst ","
.BI " struct io_uring * " src ","
.BI " unsigned int " dst_off ","
.BI " unsigned int " src_off ","
.BI " unsigned int " nr ","
.BI " unsigned int " flags ");"
.PP
.fi
.SH DESCRIPTION
.PP
The
.BR io_uring_clone_files (3)
function clones registered file descriptors from the ring indicated by
.IR src
to the ring indicated by
.IR dst .
Upon successful completion of this operation,
.IR src
and
.IR dst
will have the same set of registered files.

The
.IR dst
ring must not have any files currently registered. If files are currently
registered on the destination ring, they must be unregistered with
.BR io_uring_unregister_files (3)
first or pass the IORING_REGISTER_DST_REPLACE flag to replace the old files in
.IR dst
ring.


Not yet available in the kernel.

The
.BR io_uring_clone_files_offset (3)
function also clones files from the
.IR src
ring to the
.IR dst
ring, however it supports cloning only a subset of the files, where
.BR io_uring_clone_files (3)
always clones all of them.
.IR dst_off
indicates at what offset cloning should start in the destination,
.IR src_off
indicates at what offset cloning should start in the source, and
.IR nr
indicates how many files to clone at the given offset. If both
.IR dst_off ,
.IR src_off ,
and
.IR nr
are given as
.B 0 ,
then
.BR io_uring_clone_files_offset (3)
performs the same action as
.BR io_uring_clone_files (3) .

.IR flags
may be set to the following values:
.TP
.B IORING_REGISTER_SRC_REGISTERED
If the source ring is registered AND the calling thread is the one that
originally registered its ring fd, then this flag may be set to lookup the
registered index rather than use the normal file descriptor. If the normal
file descriptor wasn't closed after registering it, there's no need to set
this flag.
.TP
.B IORING_REGISTER_DST_REPLACE
If set, cloning may happen for a destination ring that already has a file
table assigned. In that case, existing nodes that overlap with the specified
range will be released and replaced.
.PP

.SH NOTES
A ring cannot safely clone its file table into itself. Attempting to use the
same ring for both
.IR src
and
.IR dst
will fail.
.SH RETURN VALUE
On success
.BR io_uring_clone_files (3)
and
.BR io_uring_clone_files_offset (3)
return 0.
On failure, they return
.BR -errno ,
specifically
.TP
.B -EBUSY
The destination ring already has files registered, and
.B IORING_REGISTER_DST_REPLACE
wasn't set.
.TP
.B -EINVAL
An attempt was made to clone a ring into itself, or an invalid flag/offset was specified.
.TP
.B -ENOMEM
The kernel ran out of memory.
.TP
.B -ENXIO
The source ring doesn't have any files registered.
.SH SEE ALSO
.BR io_uring_register (2),
.BR io_uring_unregister_files (3),
.BR io_uring_register_files (3)
12 changes: 12 additions & 0 deletions src/include/liburing.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,18 @@ int io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src)
LIBURING_NOEXCEPT;
int __io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src,
unsigned int flags) LIBURING_NOEXCEPT;
int io_uring_clone_files_offset(struct io_uring *dst, struct io_uring *src,
unsigned int dst_off, unsigned int src_off,
unsigned int nr, unsigned int flags)
LIBURING_NOEXCEPT;
int __io_uring_clone_files_offset(struct io_uring *dst, struct io_uring *src,
unsigned int dst_off, unsigned int src_off,
unsigned int nr, unsigned int flags)
LIBURING_NOEXCEPT;
int io_uring_clone_files(struct io_uring *dst, struct io_uring *src)
LIBURING_NOEXCEPT;
int __io_uring_clone_files(struct io_uring *dst, struct io_uring *src,
unsigned int flags) LIBURING_NOEXCEPT;
int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
unsigned nr_iovecs) LIBURING_NOEXCEPT;
int io_uring_register_buffers_tags(struct io_uring *ring,
Expand Down
13 changes: 13 additions & 0 deletions src/include/liburing/io_uring.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,9 @@ enum io_uring_register_op {
/* register bpf filtering programs */
IORING_REGISTER_BPF_FILTER = 37,

/* clone file descriptors from another ring */
IORING_REGISTER_CLONE_FILES = 38,

/* this goes last */
IORING_REGISTER_LAST,

Expand Down Expand Up @@ -840,6 +843,16 @@ struct io_uring_clone_buffers {
__u32 pad[3];
};


struct io_uring_clone_files {
__u32 src_fd;
__u32 flags;
__u32 src_off;
__u32 dst_off;
__u32 nr;
__u32 pad[3];
};

struct io_uring_buf {
__u64 addr;
__u32 len;
Expand Down
4 changes: 4 additions & 0 deletions src/liburing-ffi.map
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,8 @@ LIBURING_2.15 {
__io_uring_peek_cqe;
io_uring_register_zcrx_ctrl;
io_uring_register_query;
io_uring_clone_files;
__io_uring_clone_files;
io_uring_clone_files_offset;
__io_uring_clone_files_offset;
} LIBURING_2.14;
4 changes: 4 additions & 0 deletions src/liburing.map
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,8 @@ LIBURING_2.15 {
io_uring_register_bpf_filter_task;
io_uring_register_zcrx_ctrl;
io_uring_register_query;
io_uring_clone_files;
__io_uring_clone_files;
io_uring_clone_files_offset;
__io_uring_clone_files_offset;
} LIBURING_2.14;
43 changes: 43 additions & 0 deletions src/register.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,49 @@ int __io_uring_clone_buffers(struct io_uring *dst, struct io_uring *src,
return __io_uring_clone_buffers_offset(dst, src, 0, 0, 0, flags);
}

int __io_uring_clone_files_offset(struct io_uring *dst, struct io_uring *src,
unsigned int dst_off, unsigned int src_off,
unsigned int nr, unsigned int flags)
{
struct io_uring_clone_files buf = {
.src_fd = src->ring_fd,
.flags = flags,
.src_off = src_off,
.dst_off = dst_off,
.nr = nr,
};

if (flags & IORING_REGISTER_SRC_REGISTERED &&
src->int_flags & INT_FLAG_REG_REG_RING) {
buf.src_fd = src->enter_ring_fd;
} else {
buf.src_fd = src->ring_fd;
buf.flags &= ~IORING_REGISTER_SRC_REGISTERED;
}

return do_register(dst, IORING_REGISTER_CLONE_FILES, &buf, 1);
}

int io_uring_clone_files_offset(struct io_uring *dst, struct io_uring *src,
unsigned int dst_off, unsigned int src_off,
unsigned int nr, unsigned int flags)
{
return __io_uring_clone_files_offset(dst, src, dst_off, src_off, nr,
flags | IORING_REGISTER_SRC_REGISTERED);
}

int io_uring_clone_files(struct io_uring *dst, struct io_uring *src)
{
return __io_uring_clone_files_offset(dst, src, 0, 0, 0, IORING_REGISTER_SRC_REGISTERED);
}

int __io_uring_clone_files(struct io_uring *dst, struct io_uring *src,
unsigned int flags)
{
return __io_uring_clone_files_offset(dst, src, 0, 0, 0, flags);
}


int io_uring_register_ifq(struct io_uring *ring,
struct io_uring_zcrx_ifq_reg *reg)
{
Expand Down
1 change: 1 addition & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ test_srcs := \
cancel-race.c \
cbpf_filter.c \
ce593a6c480a.c \
clone-files.c \
close-opath.c \
conn-unreach.c \
connect.c \
Expand Down
Loading