]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/include/seastar/core/linux-aio.hh
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / include / seastar / core / linux-aio.hh
CommitLineData
11fdf7f2
TL
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright (C) 2017 ScyllaDB
20 */
21
22#pragma once
23
24#include <endian.h>
25#include <sys/time.h>
26#include <sys/uio.h>
27#include <signal.h>
28#include <cstdint>
29
30namespace seastar {
31
32namespace internal {
33
34namespace linux_abi {
35
36using aio_context_t = unsigned long;
37
38enum class iocb_cmd : uint16_t {
39 PREAD = 0,
40 PWRITE = 1,
41 FSYNC = 2,
42 FDSYNC = 3,
43 POLL = 5,
44 NOOP = 6,
45 PREADV = 7,
46 PWRITEV = 8,
47};
48
49struct io_event {
50 uint64_t data;
51 uint64_t obj;
52 int64_t res;
53 int64_t res2;
54};
55
56constexpr int IOCB_FLAG_RESFD = 1;
57
58struct iocb {
59 uint64_t aio_data;
60
61#if __BYTE_ORDER == __LITTLE_ENDIAN
62 uint32_t aio_key;
63 int32_t aio_rw_flags;
64#elif __BYTE_ORDER == __BIG_ENDIAN
65 int32_t aio_rw_flags;
66 uint32_t aio_key;
67#else
68#error bad byteorder
69#endif
70
71 iocb_cmd aio_lio_opcode;
72 int16_t aio_reqprio;
73 uint32_t aio_fildes;
74
75 uint64_t aio_buf;
76 uint64_t aio_nbytes;
77 int64_t aio_offset;
78
79 uint64_t aio_reserved2;
80
81 uint32_t aio_flags;
82
83 uint32_t aio_resfd;
84};
85
86struct aio_sigset {
87 const sigset_t *sigmask;
88 size_t sigsetsize;
89};
90
91}
92
93linux_abi::iocb make_read_iocb(int fd, uint64_t offset, void* buffer, size_t len);
94linux_abi::iocb make_write_iocb(int fd, uint64_t offset, const void* buffer, size_t len);
95linux_abi::iocb make_readv_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov);
96linux_abi::iocb make_writev_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov);
97linux_abi::iocb make_poll_iocb(int fd, uint32_t events);
98
99void set_user_data(linux_abi::iocb& iocb, void* data);
100void* get_user_data(const linux_abi::iocb& iocb);
101void set_nowait(linux_abi::iocb& iocb, bool nowait);
102
103void set_eventfd_notification(linux_abi::iocb& iocb, int eventfd);
104
105linux_abi::iocb* get_iocb(const linux_abi::io_event& ioev);
106
107int io_setup(int nr_events, linux_abi::aio_context_t* io_context);
108int io_destroy(linux_abi::aio_context_t io_context);
109int io_submit(linux_abi::aio_context_t io_context, long nr, linux_abi::iocb** iocbs);
110int io_cancel(linux_abi::aio_context_t io_context, linux_abi::iocb* iocb, linux_abi::io_event* result);
111int io_getevents(linux_abi::aio_context_t io_context, long min_nr, long nr, linux_abi::io_event* events, const ::timespec* timeout,
112 bool force_syscall = false);
113int io_pgetevents(linux_abi::aio_context_t io_context, long min_nr, long nr, linux_abi::io_event* events, const ::timespec* timeout, const sigset_t* sigmask,
114 bool force_syscall = false);
115
9f95a23c
TL
116void setup_aio_context(size_t nr, linux_abi::aio_context_t* io_context);
117
11fdf7f2
TL
118}
119
120namespace internal {
121
122inline
123linux_abi::iocb
124make_read_iocb(int fd, uint64_t offset, void* buffer, size_t len) {
125 linux_abi::iocb iocb{};
126 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREAD;
127 iocb.aio_fildes = fd;
128 iocb.aio_offset = offset;
129 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
130 iocb.aio_nbytes = len;
131 return iocb;
132}
133
134inline
135linux_abi::iocb
136make_write_iocb(int fd, uint64_t offset, const void* buffer, size_t len) {
137 linux_abi::iocb iocb{};
138 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITE;
139 iocb.aio_fildes = fd;
140 iocb.aio_offset = offset;
141 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
142 iocb.aio_nbytes = len;
143 return iocb;
144}
145
146inline
147linux_abi::iocb
148make_readv_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
149 linux_abi::iocb iocb{};
150 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREADV;
151 iocb.aio_fildes = fd;
152 iocb.aio_offset = offset;
153 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
154 iocb.aio_nbytes = niov;
155 return iocb;
156}
157
158inline
159linux_abi::iocb
160make_writev_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
161 linux_abi::iocb iocb{};
162 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITEV;
163 iocb.aio_fildes = fd;
164 iocb.aio_offset = offset;
165 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
166 iocb.aio_nbytes = niov;
167 return iocb;
168}
169
170inline
171linux_abi::iocb
172make_poll_iocb(int fd, uint32_t events) {
173 linux_abi::iocb iocb{};
174 iocb.aio_lio_opcode = linux_abi::iocb_cmd::POLL;
175 iocb.aio_fildes = fd;
176 iocb.aio_buf = events;
177 return iocb;
178}
179
9f95a23c
TL
180inline
181linux_abi::iocb
182make_fdsync_iocb(int fd) {
183 linux_abi::iocb iocb{};
184 iocb.aio_lio_opcode = linux_abi::iocb_cmd::FDSYNC;
185 iocb.aio_fildes = fd;
186 return iocb;
187}
188
11fdf7f2
TL
189inline
190void
191set_user_data(linux_abi::iocb& iocb, void* data) {
192 iocb.aio_data = reinterpret_cast<uintptr_t>(data);
193}
194
195inline
196void*
197get_user_data(const linux_abi::iocb& iocb) {
198 return reinterpret_cast<void*>(uintptr_t(iocb.aio_data));
199}
200
201inline
202void
203set_eventfd_notification(linux_abi::iocb& iocb, int eventfd) {
204 iocb.aio_flags |= linux_abi::IOCB_FLAG_RESFD;
205 iocb.aio_resfd = eventfd;
206}
207
208inline
209linux_abi::iocb*
210get_iocb(const linux_abi::io_event& ev) {
211 return reinterpret_cast<linux_abi::iocb*>(uintptr_t(ev.obj));
212}
213
214inline
215void
216set_nowait(linux_abi::iocb& iocb, bool nowait) {
217#ifdef RWF_NOWAIT
218 if (nowait) {
219 iocb.aio_rw_flags |= RWF_NOWAIT;
220 } else {
221 iocb.aio_rw_flags &= ~RWF_NOWAIT;
222 }
223#endif
224}
225
226}
227
228
229}
230