Skip to content

Commit 1374e08

Browse files
committed
io_uring: add socket(2) support
Supports both regular socket(2) where a normal file descriptor is instantiated when called, or direct descriptors. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent da214a4 commit 1374e08

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

fs/io_uring.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,16 @@ struct io_accept {
576576
unsigned long nofile;
577577
};
578578

579+
struct io_socket {
580+
struct file *file;
581+
int domain;
582+
int type;
583+
int protocol;
584+
int flags;
585+
u32 file_slot;
586+
unsigned long nofile;
587+
};
588+
579589
struct io_sync {
580590
struct file *file;
581591
loff_t len;
@@ -951,6 +961,7 @@ struct io_kiocb {
951961
struct io_hardlink hardlink;
952962
struct io_msg msg;
953963
struct io_xattr xattr;
964+
struct io_socket sock;
954965
};
955966

956967
u8 opcode;
@@ -1227,6 +1238,9 @@ static const struct io_op_def io_op_defs[] = {
12271238
.needs_file = 1
12281239
},
12291240
[IORING_OP_GETXATTR] = {},
1241+
[IORING_OP_SOCKET] = {
1242+
.audit_skip = 1,
1243+
},
12301244
};
12311245

12321246
/* requests with any of those set should undergo io_disarm_next() */
@@ -6017,6 +6031,62 @@ static int io_accept(struct io_kiocb *req, unsigned int issue_flags)
60176031
return 0;
60186032
}
60196033

6034+
static int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
6035+
{
6036+
struct io_socket *sock = &req->sock;
6037+
6038+
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
6039+
return -EINVAL;
6040+
if (sqe->ioprio || sqe->addr || sqe->rw_flags || sqe->buf_index)
6041+
return -EINVAL;
6042+
6043+
sock->domain = READ_ONCE(sqe->fd);
6044+
sock->type = READ_ONCE(sqe->off);
6045+
sock->protocol = READ_ONCE(sqe->len);
6046+
sock->file_slot = READ_ONCE(sqe->file_index);
6047+
sock->nofile = rlimit(RLIMIT_NOFILE);
6048+
6049+
sock->flags = sock->type & ~SOCK_TYPE_MASK;
6050+
if (sock->file_slot && (sock->flags & SOCK_CLOEXEC))
6051+
return -EINVAL;
6052+
if (sock->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
6053+
return -EINVAL;
6054+
return 0;
6055+
}
6056+
6057+
static int io_socket(struct io_kiocb *req, unsigned int issue_flags)
6058+
{
6059+
struct io_socket *sock = &req->sock;
6060+
bool fixed = !!sock->file_slot;
6061+
struct file *file;
6062+
int ret, fd;
6063+
6064+
if (!fixed) {
6065+
fd = __get_unused_fd_flags(sock->flags, sock->nofile);
6066+
if (unlikely(fd < 0))
6067+
return fd;
6068+
}
6069+
file = __sys_socket_file(sock->domain, sock->type, sock->protocol);
6070+
if (IS_ERR(file)) {
6071+
if (!fixed)
6072+
put_unused_fd(fd);
6073+
ret = PTR_ERR(file);
6074+
if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
6075+
return -EAGAIN;
6076+
if (ret == -ERESTARTSYS)
6077+
ret = -EINTR;
6078+
req_set_fail(req);
6079+
} else if (!fixed) {
6080+
fd_install(fd, file);
6081+
ret = fd;
6082+
} else {
6083+
ret = io_install_fixed_file(req, file, issue_flags,
6084+
sock->file_slot - 1);
6085+
}
6086+
__io_req_complete(req, issue_flags, ret, 0);
6087+
return 0;
6088+
}
6089+
60206090
static int io_connect_prep_async(struct io_kiocb *req)
60216091
{
60226092
struct io_async_connect *io = req->async_data;
@@ -6105,6 +6175,7 @@ IO_NETOP_PREP_ASYNC(sendmsg);
61056175
IO_NETOP_PREP_ASYNC(recvmsg);
61066176
IO_NETOP_PREP_ASYNC(connect);
61076177
IO_NETOP_PREP(accept);
6178+
IO_NETOP_PREP(socket);
61086179
IO_NETOP_FN(send);
61096180
IO_NETOP_FN(recv);
61106181
#endif /* CONFIG_NET */
@@ -7426,6 +7497,8 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
74267497
return io_fgetxattr_prep(req, sqe);
74277498
case IORING_OP_GETXATTR:
74287499
return io_getxattr_prep(req, sqe);
7500+
case IORING_OP_SOCKET:
7501+
return io_socket_prep(req, sqe);
74297502
}
74307503

74317504
printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
@@ -7744,6 +7817,9 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
77447817
case IORING_OP_GETXATTR:
77457818
ret = io_getxattr(req, issue_flags);
77467819
break;
7820+
case IORING_OP_SOCKET:
7821+
ret = io_socket(req, issue_flags);
7822+
break;
77477823
default:
77487824
ret = -EINVAL;
77497825
break;

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ enum {
151151
IORING_OP_SETXATTR,
152152
IORING_OP_FGETXATTR,
153153
IORING_OP_GETXATTR,
154+
IORING_OP_SOCKET,
154155

155156
/* this goes last, obviously */
156157
IORING_OP_LAST,

0 commit comments

Comments
 (0)