Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/io_uring/nop.c
29266 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/kernel.h>
3
#include <linux/errno.h>
4
#include <linux/fs.h>
5
#include <linux/file.h>
6
#include <linux/io_uring.h>
7
8
#include <uapi/linux/io_uring.h>
9
10
#include "io_uring.h"
11
#include "rsrc.h"
12
#include "nop.h"
13
14
struct io_nop {
15
/* NOTE: kiocb has the file as the first member, so don't do it here */
16
struct file *file;
17
int result;
18
int fd;
19
unsigned int flags;
20
__u64 extra1;
21
__u64 extra2;
22
};
23
24
#define NOP_FLAGS (IORING_NOP_INJECT_RESULT | IORING_NOP_FIXED_FILE | \
25
IORING_NOP_FIXED_BUFFER | IORING_NOP_FILE | \
26
IORING_NOP_TW | IORING_NOP_CQE32)
27
28
int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
29
{
30
struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
31
32
nop->flags = READ_ONCE(sqe->nop_flags);
33
if (nop->flags & ~NOP_FLAGS)
34
return -EINVAL;
35
36
if (nop->flags & IORING_NOP_INJECT_RESULT)
37
nop->result = READ_ONCE(sqe->len);
38
else
39
nop->result = 0;
40
if (nop->flags & IORING_NOP_FILE)
41
nop->fd = READ_ONCE(sqe->fd);
42
else
43
nop->fd = -1;
44
if (nop->flags & IORING_NOP_FIXED_BUFFER)
45
req->buf_index = READ_ONCE(sqe->buf_index);
46
if (nop->flags & IORING_NOP_CQE32) {
47
struct io_ring_ctx *ctx = req->ctx;
48
49
if (!(ctx->flags & (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)))
50
return -EINVAL;
51
nop->extra1 = READ_ONCE(sqe->off);
52
nop->extra2 = READ_ONCE(sqe->addr);
53
}
54
return 0;
55
}
56
57
int io_nop(struct io_kiocb *req, unsigned int issue_flags)
58
{
59
struct io_nop *nop = io_kiocb_to_cmd(req, struct io_nop);
60
int ret = nop->result;
61
62
if (nop->flags & IORING_NOP_FILE) {
63
if (nop->flags & IORING_NOP_FIXED_FILE) {
64
req->file = io_file_get_fixed(req, nop->fd, issue_flags);
65
req->flags |= REQ_F_FIXED_FILE;
66
} else {
67
req->file = io_file_get_normal(req, nop->fd);
68
}
69
if (!req->file) {
70
ret = -EBADF;
71
goto done;
72
}
73
}
74
if (nop->flags & IORING_NOP_FIXED_BUFFER) {
75
if (!io_find_buf_node(req, issue_flags))
76
ret = -EFAULT;
77
}
78
done:
79
if (ret < 0)
80
req_set_fail(req);
81
if (nop->flags & IORING_NOP_CQE32)
82
io_req_set_res32(req, nop->result, 0, nop->extra1, nop->extra2);
83
else
84
io_req_set_res(req, nop->result, 0);
85
if (nop->flags & IORING_NOP_TW) {
86
req->io_task_work.func = io_req_task_complete;
87
io_req_task_work_add(req);
88
return IOU_ISSUE_SKIP_COMPLETE;
89
}
90
return IOU_COMPLETE;
91
}
92
93