@nxtedition/rocksdb 5.2.36 → 5.2.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/binding.cc +66 -91
  2. package/deps/liburing/liburing/COPYING +502 -0
  3. package/deps/liburing/liburing/COPYING.GPL +339 -0
  4. package/deps/liburing/liburing/LICENSE +7 -0
  5. package/deps/liburing/liburing/Makefile +84 -0
  6. package/deps/liburing/liburing/Makefile.quiet +11 -0
  7. package/deps/liburing/liburing/README +46 -0
  8. package/deps/liburing/liburing/configure +420 -0
  9. package/deps/liburing/liburing/debian/README.Debian +7 -0
  10. package/deps/liburing/liburing/debian/changelog +27 -0
  11. package/deps/liburing/liburing/debian/compat +1 -0
  12. package/deps/liburing/liburing/debian/control +48 -0
  13. package/deps/liburing/liburing/debian/copyright +49 -0
  14. package/deps/liburing/liburing/debian/liburing-dev.install +4 -0
  15. package/deps/liburing/liburing/debian/liburing-dev.manpages +6 -0
  16. package/deps/liburing/liburing/debian/liburing1-udeb.install +1 -0
  17. package/deps/liburing/liburing/debian/liburing1.install +1 -0
  18. package/deps/liburing/liburing/debian/liburing1.symbols +32 -0
  19. package/deps/liburing/liburing/debian/patches/series +1 -0
  20. package/deps/liburing/liburing/debian/rules +81 -0
  21. package/deps/liburing/liburing/debian/source/format +1 -0
  22. package/deps/liburing/liburing/debian/source/local-options +2 -0
  23. package/deps/liburing/liburing/debian/source/options +1 -0
  24. package/deps/liburing/liburing/debian/watch +3 -0
  25. package/deps/liburing/liburing/examples/Makefile +29 -0
  26. package/deps/liburing/liburing/examples/io_uring-cp.c +279 -0
  27. package/deps/liburing/liburing/examples/io_uring-test.c +112 -0
  28. package/deps/liburing/liburing/examples/link-cp.c +193 -0
  29. package/deps/liburing/liburing/examples/ucontext-cp.c +273 -0
  30. package/deps/liburing/liburing/liburing.pc.in +12 -0
  31. package/deps/liburing/liburing/liburing.spec +66 -0
  32. package/deps/liburing/liburing/make-debs.sh +53 -0
  33. package/deps/liburing/liburing/man/io_uring.7 +736 -0
  34. package/deps/liburing/liburing/man/io_uring_enter.2 +1403 -0
  35. package/deps/liburing/liburing/man/io_uring_get_sqe.3 +37 -0
  36. package/deps/liburing/liburing/man/io_uring_queue_exit.3 +27 -0
  37. package/deps/liburing/liburing/man/io_uring_queue_init.3 +44 -0
  38. package/deps/liburing/liburing/man/io_uring_register.2 +605 -0
  39. package/deps/liburing/liburing/man/io_uring_setup.2 +515 -0
  40. package/deps/liburing/liburing/src/Makefile +76 -0
  41. package/deps/liburing/liburing/src/include/liburing/barrier.h +73 -0
  42. package/deps/liburing/liburing/src/include/liburing/io_uring.h +422 -0
  43. package/deps/liburing/liburing/src/include/liburing.h +775 -0
  44. package/deps/liburing/liburing/src/liburing.map +46 -0
  45. package/deps/liburing/liburing/src/queue.c +403 -0
  46. package/deps/liburing/liburing/src/register.c +299 -0
  47. package/deps/liburing/liburing/src/setup.c +356 -0
  48. package/deps/liburing/liburing/src/syscall.c +73 -0
  49. package/deps/liburing/liburing/src/syscall.h +20 -0
  50. package/deps/liburing/liburing/test/232c93d07b74-test.c +305 -0
  51. package/deps/liburing/liburing/test/35fa71a030ca-test.c +329 -0
  52. package/deps/liburing/liburing/test/500f9fbadef8-test.c +89 -0
  53. package/deps/liburing/liburing/test/7ad0e4b2f83c-test.c +93 -0
  54. package/deps/liburing/liburing/test/8a9973408177-test.c +106 -0
  55. package/deps/liburing/liburing/test/917257daa0fe-test.c +53 -0
  56. package/deps/liburing/liburing/test/Makefile +312 -0
  57. package/deps/liburing/liburing/test/a0908ae19763-test.c +58 -0
  58. package/deps/liburing/liburing/test/a4c0b3decb33-test.c +180 -0
  59. package/deps/liburing/liburing/test/accept-link.c +251 -0
  60. package/deps/liburing/liburing/test/accept-reuse.c +164 -0
  61. package/deps/liburing/liburing/test/accept-test.c +79 -0
  62. package/deps/liburing/liburing/test/accept.c +476 -0
  63. package/deps/liburing/liburing/test/across-fork.c +283 -0
  64. package/deps/liburing/liburing/test/b19062a56726-test.c +53 -0
  65. package/deps/liburing/liburing/test/b5837bd5311d-test.c +77 -0
  66. package/deps/liburing/liburing/test/ce593a6c480a-test.c +135 -0
  67. package/deps/liburing/liburing/test/close-opath.c +122 -0
  68. package/deps/liburing/liburing/test/config +10 -0
  69. package/deps/liburing/liburing/test/connect.c +398 -0
  70. package/deps/liburing/liburing/test/cq-full.c +96 -0
  71. package/deps/liburing/liburing/test/cq-overflow.c +294 -0
  72. package/deps/liburing/liburing/test/cq-peek-batch.c +102 -0
  73. package/deps/liburing/liburing/test/cq-ready.c +94 -0
  74. package/deps/liburing/liburing/test/cq-size.c +58 -0
  75. package/deps/liburing/liburing/test/d4ae271dfaae-test.c +96 -0
  76. package/deps/liburing/liburing/test/d77a67ed5f27-test.c +65 -0
  77. package/deps/liburing/liburing/test/defer.c +307 -0
  78. package/deps/liburing/liburing/test/double-poll-crash.c +186 -0
  79. package/deps/liburing/liburing/test/eeed8b54e0df-test.c +114 -0
  80. package/deps/liburing/liburing/test/empty-eownerdead.c +42 -0
  81. package/deps/liburing/liburing/test/eventfd-disable.c +151 -0
  82. package/deps/liburing/liburing/test/eventfd-ring.c +97 -0
  83. package/deps/liburing/liburing/test/eventfd.c +112 -0
  84. package/deps/liburing/liburing/test/fadvise.c +202 -0
  85. package/deps/liburing/liburing/test/fallocate.c +249 -0
  86. package/deps/liburing/liburing/test/fc2a85cb02ef-test.c +138 -0
  87. package/deps/liburing/liburing/test/file-register.c +843 -0
  88. package/deps/liburing/liburing/test/file-update.c +173 -0
  89. package/deps/liburing/liburing/test/files-exit-hang-poll.c +128 -0
  90. package/deps/liburing/liburing/test/files-exit-hang-timeout.c +134 -0
  91. package/deps/liburing/liburing/test/fixed-link.c +90 -0
  92. package/deps/liburing/liburing/test/fsync.c +224 -0
  93. package/deps/liburing/liburing/test/hardlink.c +136 -0
  94. package/deps/liburing/liburing/test/helpers.c +135 -0
  95. package/deps/liburing/liburing/test/helpers.h +67 -0
  96. package/deps/liburing/liburing/test/io-cancel.c +537 -0
  97. package/deps/liburing/liburing/test/io_uring_enter.c +296 -0
  98. package/deps/liburing/liburing/test/io_uring_register.c +664 -0
  99. package/deps/liburing/liburing/test/io_uring_setup.c +192 -0
  100. package/deps/liburing/liburing/test/iopoll.c +366 -0
  101. package/deps/liburing/liburing/test/lfs-openat-write.c +117 -0
  102. package/deps/liburing/liburing/test/lfs-openat.c +273 -0
  103. package/deps/liburing/liburing/test/link-timeout.c +1107 -0
  104. package/deps/liburing/liburing/test/link.c +496 -0
  105. package/deps/liburing/liburing/test/link_drain.c +229 -0
  106. package/deps/liburing/liburing/test/madvise.c +195 -0
  107. package/deps/liburing/liburing/test/mkdir.c +108 -0
  108. package/deps/liburing/liburing/test/multicqes_drain.c +383 -0
  109. package/deps/liburing/liburing/test/nop-all-sizes.c +107 -0
  110. package/deps/liburing/liburing/test/nop.c +115 -0
  111. package/deps/liburing/liburing/test/open-close.c +146 -0
  112. package/deps/liburing/liburing/test/openat2.c +240 -0
  113. package/deps/liburing/liburing/test/personality.c +204 -0
  114. package/deps/liburing/liburing/test/pipe-eof.c +81 -0
  115. package/deps/liburing/liburing/test/pipe-reuse.c +105 -0
  116. package/deps/liburing/liburing/test/poll-cancel-ton.c +139 -0
  117. package/deps/liburing/liburing/test/poll-cancel.c +135 -0
  118. package/deps/liburing/liburing/test/poll-link.c +227 -0
  119. package/deps/liburing/liburing/test/poll-many.c +208 -0
  120. package/deps/liburing/liburing/test/poll-mshot-update.c +273 -0
  121. package/deps/liburing/liburing/test/poll-ring.c +48 -0
  122. package/deps/liburing/liburing/test/poll-v-poll.c +353 -0
  123. package/deps/liburing/liburing/test/poll.c +109 -0
  124. package/deps/liburing/liburing/test/probe.c +137 -0
  125. package/deps/liburing/liburing/test/read-write.c +876 -0
  126. package/deps/liburing/liburing/test/register-restrictions.c +633 -0
  127. package/deps/liburing/liburing/test/rename.c +134 -0
  128. package/deps/liburing/liburing/test/ring-leak.c +173 -0
  129. package/deps/liburing/liburing/test/ring-leak2.c +249 -0
  130. package/deps/liburing/liburing/test/rsrc_tags.c +449 -0
  131. package/deps/liburing/liburing/test/runtests-loop.sh +16 -0
  132. package/deps/liburing/liburing/test/runtests.sh +170 -0
  133. package/deps/liburing/liburing/test/rw_merge_test.c +97 -0
  134. package/deps/liburing/liburing/test/self.c +91 -0
  135. package/deps/liburing/liburing/test/send_recv.c +291 -0
  136. package/deps/liburing/liburing/test/send_recvmsg.c +345 -0
  137. package/deps/liburing/liburing/test/sendmsg_fs_cve.c +198 -0
  138. package/deps/liburing/liburing/test/shared-wq.c +84 -0
  139. package/deps/liburing/liburing/test/short-read.c +75 -0
  140. package/deps/liburing/liburing/test/shutdown.c +163 -0
  141. package/deps/liburing/liburing/test/sigfd-deadlock.c +74 -0
  142. package/deps/liburing/liburing/test/socket-rw-eagain.c +156 -0
  143. package/deps/liburing/liburing/test/socket-rw.c +147 -0
  144. package/deps/liburing/liburing/test/splice.c +511 -0
  145. package/deps/liburing/liburing/test/sq-full-cpp.cc +45 -0
  146. package/deps/liburing/liburing/test/sq-full.c +45 -0
  147. package/deps/liburing/liburing/test/sq-poll-dup.c +200 -0
  148. package/deps/liburing/liburing/test/sq-poll-kthread.c +168 -0
  149. package/deps/liburing/liburing/test/sq-poll-share.c +137 -0
  150. package/deps/liburing/liburing/test/sq-space_left.c +159 -0
  151. package/deps/liburing/liburing/test/sqpoll-cancel-hang.c +159 -0
  152. package/deps/liburing/liburing/test/sqpoll-disable-exit.c +195 -0
  153. package/deps/liburing/liburing/test/sqpoll-exit-hang.c +77 -0
  154. package/deps/liburing/liburing/test/sqpoll-sleep.c +68 -0
  155. package/deps/liburing/liburing/test/statx.c +172 -0
  156. package/deps/liburing/liburing/test/stdout.c +232 -0
  157. package/deps/liburing/liburing/test/submit-link-fail.c +154 -0
  158. package/deps/liburing/liburing/test/submit-reuse.c +239 -0
  159. package/deps/liburing/liburing/test/symlink.c +116 -0
  160. package/deps/liburing/liburing/test/teardowns.c +58 -0
  161. package/deps/liburing/liburing/test/thread-exit.c +131 -0
  162. package/deps/liburing/liburing/test/timeout-new.c +246 -0
  163. package/deps/liburing/liburing/test/timeout-overflow.c +204 -0
  164. package/deps/liburing/liburing/test/timeout.c +1354 -0
  165. package/deps/liburing/liburing/test/unlink.c +111 -0
  166. package/deps/liburing/liburing/test/wakeup-hang.c +162 -0
  167. package/deps/liburing/liburing.gyp +20 -0
  168. package/deps/rocksdb/rocksdb/db/corruption_test.cc +62 -0
  169. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +7 -62
  170. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +25 -11
  171. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +74 -155
  172. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +1 -2
  173. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +2 -2
  174. package/deps/rocksdb/rocksdb/env/fs_posix.cc +13 -0
  175. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +4 -2
  176. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +22 -4
  177. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +5 -0
  178. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +15 -0
  179. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
  180. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  181. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -0
  182. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +3 -7
  183. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +2 -1
  184. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +44 -29
  185. package/deps/rocksdb/rocksdb.gyp +4 -3
  186. package/package.json +1 -1
  187. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  188. package/prebuilds/darwin-x64/node.napi.node +0 -0
  189. package/prebuilds/linux-x64/node.napi.node +0 -0
  190. package/prebuilds/prebuilds/linux-x64/node.napi.node +0 -0
@@ -0,0 +1,46 @@
1
+ LIBURING_2.0 {
2
+ global:
3
+ io_uring_get_probe;
4
+ io_uring_get_probe_ring;
5
+ io_uring_free_probe;
6
+ io_uring_get_sqe;
7
+ io_uring_peek_batch_cqe;
8
+ io_uring_queue_exit;
9
+ io_uring_queue_init;
10
+ io_uring_queue_init_params;
11
+ io_uring_queue_mmap;
12
+ io_uring_register_buffers;
13
+ io_uring_register_eventfd;
14
+ io_uring_register_eventfd_async;
15
+ io_uring_register_files;
16
+ io_uring_register_files_update;
17
+ io_uring_register_personality;
18
+ io_uring_register_probe;
19
+ io_uring_ring_dontfork;
20
+ io_uring_submit;
21
+ io_uring_submit_and_wait;
22
+ io_uring_unregister_buffers;
23
+ io_uring_unregister_eventfd;
24
+ io_uring_unregister_files;
25
+ io_uring_unregister_personality;
26
+ io_uring_wait_cqe_timeout;
27
+ io_uring_wait_cqes;
28
+
29
+ __io_uring_get_cqe;
30
+ __io_uring_sqring_wait;
31
+ local:
32
+ *;
33
+ };
34
+
35
+ LIBURING_2.1 {
36
+ global:
37
+ io_uring_mlock_size_params;
38
+ io_uring_mlock_size;
39
+ io_uring_register_buffers_tags;
40
+ io_uring_register_buffers_update_tag;
41
+ io_uring_register_files_tags;
42
+ io_uring_register_files_update_tag;
43
+ io_uring_register_iowq_aff;
44
+ io_uring_unregister_iowq_aff;
45
+ io_uring_register_iowq_max_workers;
46
+ } LIBURING_2.0;
@@ -0,0 +1,403 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #define _POSIX_C_SOURCE 200112L
3
+
4
+ #include <sys/types.h>
5
+ #include <sys/stat.h>
6
+ #include <sys/mman.h>
7
+ #include <unistd.h>
8
+ #include <errno.h>
9
+ #include <string.h>
10
+ #include <stdbool.h>
11
+
12
+ #include "liburing/compat.h"
13
+ #include "liburing/io_uring.h"
14
+ #include "liburing.h"
15
+ #include "liburing/barrier.h"
16
+
17
+ #include "syscall.h"
18
+
19
+ /*
20
+ * Returns true if we're not using SQ thread (thus nobody submits but us)
21
+ * or if IORING_SQ_NEED_WAKEUP is set, so submit thread must be explicitly
22
+ * awakened. For the latter case, we set the thread wakeup flag.
23
+ */
24
+ static inline bool sq_ring_needs_enter(struct io_uring *ring, unsigned *flags)
25
+ {
26
+ if (!(ring->flags & IORING_SETUP_SQPOLL))
27
+ return true;
28
+
29
+ if (uring_unlikely(IO_URING_READ_ONCE(*ring->sq.kflags) &
30
+ IORING_SQ_NEED_WAKEUP)) {
31
+ *flags |= IORING_ENTER_SQ_WAKEUP;
32
+ return true;
33
+ }
34
+
35
+ return false;
36
+ }
37
+
38
+ static inline bool cq_ring_needs_flush(struct io_uring *ring)
39
+ {
40
+ return IO_URING_READ_ONCE(*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW;
41
+ }
42
+
43
+ static int __io_uring_peek_cqe(struct io_uring *ring,
44
+ struct io_uring_cqe **cqe_ptr,
45
+ unsigned *nr_available)
46
+ {
47
+ struct io_uring_cqe *cqe;
48
+ int err = 0;
49
+ unsigned available;
50
+ unsigned mask = *ring->cq.kring_mask;
51
+
52
+ do {
53
+ unsigned tail = io_uring_smp_load_acquire(ring->cq.ktail);
54
+ unsigned head = *ring->cq.khead;
55
+
56
+ cqe = NULL;
57
+ available = tail - head;
58
+ if (!available)
59
+ break;
60
+
61
+ cqe = &ring->cq.cqes[head & mask];
62
+ if (!(ring->features & IORING_FEAT_EXT_ARG) &&
63
+ cqe->user_data == LIBURING_UDATA_TIMEOUT) {
64
+ if (cqe->res < 0)
65
+ err = cqe->res;
66
+ io_uring_cq_advance(ring, 1);
67
+ if (!err)
68
+ continue;
69
+ cqe = NULL;
70
+ }
71
+
72
+ break;
73
+ } while (1);
74
+
75
+ *cqe_ptr = cqe;
76
+ *nr_available = available;
77
+ return err;
78
+ }
79
+
80
+ struct get_data {
81
+ unsigned submit;
82
+ unsigned wait_nr;
83
+ unsigned get_flags;
84
+ int sz;
85
+ void *arg;
86
+ };
87
+
88
+ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
89
+ struct get_data *data)
90
+ {
91
+ struct io_uring_cqe *cqe = NULL;
92
+ int err;
93
+
94
+ do {
95
+ bool need_enter = false;
96
+ bool cq_overflow_flush = false;
97
+ unsigned flags = 0;
98
+ unsigned nr_available;
99
+ int ret;
100
+
101
+ err = __io_uring_peek_cqe(ring, &cqe, &nr_available);
102
+ if (err)
103
+ break;
104
+ if (!cqe && !data->wait_nr && !data->submit) {
105
+ if (!cq_ring_needs_flush(ring)) {
106
+ err = -EAGAIN;
107
+ break;
108
+ }
109
+ cq_overflow_flush = true;
110
+ }
111
+ if (data->wait_nr > nr_available || cq_overflow_flush) {
112
+ flags = IORING_ENTER_GETEVENTS | data->get_flags;
113
+ need_enter = true;
114
+ }
115
+ if (data->submit) {
116
+ sq_ring_needs_enter(ring, &flags);
117
+ need_enter = true;
118
+ }
119
+ if (!need_enter)
120
+ break;
121
+
122
+ ret = __sys_io_uring_enter2(ring->ring_fd, data->submit,
123
+ data->wait_nr, flags, data->arg,
124
+ data->sz);
125
+ if (ret < 0) {
126
+ err = -errno;
127
+ break;
128
+ }
129
+
130
+ data->submit -= ret;
131
+ if (cqe)
132
+ break;
133
+ } while (1);
134
+
135
+ *cqe_ptr = cqe;
136
+ return err;
137
+ }
138
+
139
+ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
140
+ unsigned submit, unsigned wait_nr, sigset_t *sigmask)
141
+ {
142
+ struct get_data data = {
143
+ .submit = submit,
144
+ .wait_nr = wait_nr,
145
+ .get_flags = 0,
146
+ .sz = _NSIG / 8,
147
+ .arg = sigmask,
148
+ };
149
+
150
+ return _io_uring_get_cqe(ring, cqe_ptr, &data);
151
+ }
152
+
153
+ /*
154
+ * Fill in an array of IO completions up to count, if any are available.
155
+ * Returns the amount of IO completions filled.
156
+ */
157
+ unsigned io_uring_peek_batch_cqe(struct io_uring *ring,
158
+ struct io_uring_cqe **cqes, unsigned count)
159
+ {
160
+ unsigned ready;
161
+ bool overflow_checked = false;
162
+
163
+ again:
164
+ ready = io_uring_cq_ready(ring);
165
+ if (ready) {
166
+ unsigned head = *ring->cq.khead;
167
+ unsigned mask = *ring->cq.kring_mask;
168
+ unsigned last;
169
+ int i = 0;
170
+
171
+ count = count > ready ? ready : count;
172
+ last = head + count;
173
+ for (;head != last; head++, i++)
174
+ cqes[i] = &ring->cq.cqes[head & mask];
175
+
176
+ return count;
177
+ }
178
+
179
+ if (overflow_checked)
180
+ goto done;
181
+
182
+ if (cq_ring_needs_flush(ring)) {
183
+ __sys_io_uring_enter(ring->ring_fd, 0, 0,
184
+ IORING_ENTER_GETEVENTS, NULL);
185
+ overflow_checked = true;
186
+ goto again;
187
+ }
188
+
189
+ done:
190
+ return 0;
191
+ }
192
+
193
+ /*
194
+ * Sync internal state with kernel ring state on the SQ side. Returns the
195
+ * number of pending items in the SQ ring, for the shared ring.
196
+ */
197
+ int __io_uring_flush_sq(struct io_uring *ring)
198
+ {
199
+ struct io_uring_sq *sq = &ring->sq;
200
+ const unsigned mask = *sq->kring_mask;
201
+ unsigned ktail = *sq->ktail;
202
+ unsigned to_submit = sq->sqe_tail - sq->sqe_head;
203
+
204
+ if (!to_submit)
205
+ goto out;
206
+
207
+ /*
208
+ * Fill in sqes that we have queued up, adding them to the kernel ring
209
+ */
210
+ do {
211
+ sq->array[ktail & mask] = sq->sqe_head & mask;
212
+ ktail++;
213
+ sq->sqe_head++;
214
+ } while (--to_submit);
215
+
216
+ /*
217
+ * Ensure that the kernel sees the SQE updates before it sees the tail
218
+ * update.
219
+ */
220
+ io_uring_smp_store_release(sq->ktail, ktail);
221
+ out:
222
+ /*
223
+ * This _may_ look problematic, as we're not supposed to be reading
224
+ * SQ->head without acquire semantics. When we're in SQPOLL mode, the
225
+ * kernel submitter could be updating this right now. For non-SQPOLL,
226
+ * task itself does it, and there's no potential race. But even for
227
+ * SQPOLL, the load is going to be potentially out-of-date the very
228
+ * instant it's done, regardless or whether or not it's done
229
+ * atomically. Worst case, we're going to be over-estimating what
230
+ * we can submit. The point is, we need to be able to deal with this
231
+ * situation regardless of any perceived atomicity.
232
+ */
233
+ return ktail - *sq->khead;
234
+ }
235
+
236
+ /*
237
+ * If we have kernel support for IORING_ENTER_EXT_ARG, then we can use that
238
+ * more efficiently than queueing an internal timeout command.
239
+ */
240
+ static int io_uring_wait_cqes_new(struct io_uring *ring,
241
+ struct io_uring_cqe **cqe_ptr,
242
+ unsigned wait_nr, struct __kernel_timespec *ts,
243
+ sigset_t *sigmask)
244
+ {
245
+ struct io_uring_getevents_arg arg = {
246
+ .sigmask = (unsigned long) sigmask,
247
+ .sigmask_sz = _NSIG / 8,
248
+ .ts = (unsigned long) ts
249
+ };
250
+ struct get_data data = {
251
+ .wait_nr = wait_nr,
252
+ .get_flags = IORING_ENTER_EXT_ARG,
253
+ .sz = sizeof(arg),
254
+ .arg = &arg
255
+ };
256
+
257
+ return _io_uring_get_cqe(ring, cqe_ptr, &data);
258
+ }
259
+
260
+ /*
261
+ * Like io_uring_wait_cqe(), except it accepts a timeout value as well. Note
262
+ * that an sqe is used internally to handle the timeout. For kernel doesn't
263
+ * support IORING_FEAT_EXT_ARG, applications using this function must never
264
+ * set sqe->user_data to LIBURING_UDATA_TIMEOUT!
265
+ *
266
+ * For kernels without IORING_FEAT_EXT_ARG (5.10 and older), if 'ts' is
267
+ * specified, the application need not call io_uring_submit() before
268
+ * calling this function, as we will do that on its behalf. From this it also
269
+ * follows that this function isn't safe to use for applications that split SQ
270
+ * and CQ handling between two threads and expect that to work without
271
+ * synchronization, as this function manipulates both the SQ and CQ side.
272
+ *
273
+ * For kernels with IORING_FEAT_EXT_ARG, no implicit submission is done and
274
+ * hence this function is safe to use for applications that split SQ and CQ
275
+ * handling between two threads.
276
+ */
277
+ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr,
278
+ unsigned wait_nr, struct __kernel_timespec *ts,
279
+ sigset_t *sigmask)
280
+ {
281
+ unsigned to_submit = 0;
282
+
283
+ if (ts) {
284
+ struct io_uring_sqe *sqe;
285
+ int ret;
286
+
287
+ if (ring->features & IORING_FEAT_EXT_ARG)
288
+ return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr,
289
+ ts, sigmask);
290
+
291
+ /*
292
+ * If the SQ ring is full, we may need to submit IO first
293
+ */
294
+ sqe = io_uring_get_sqe(ring);
295
+ if (!sqe) {
296
+ ret = io_uring_submit(ring);
297
+ if (ret < 0)
298
+ return ret;
299
+ sqe = io_uring_get_sqe(ring);
300
+ if (!sqe)
301
+ return -EAGAIN;
302
+ }
303
+ io_uring_prep_timeout(sqe, ts, wait_nr, 0);
304
+ sqe->user_data = LIBURING_UDATA_TIMEOUT;
305
+ to_submit = __io_uring_flush_sq(ring);
306
+ }
307
+
308
+ return __io_uring_get_cqe(ring, cqe_ptr, to_submit, wait_nr, sigmask);
309
+ }
310
+
311
+ /*
312
+ * See io_uring_wait_cqes() - this function is the same, it just always uses
313
+ * '1' as the wait_nr.
314
+ */
315
+ int io_uring_wait_cqe_timeout(struct io_uring *ring,
316
+ struct io_uring_cqe **cqe_ptr,
317
+ struct __kernel_timespec *ts)
318
+ {
319
+ return io_uring_wait_cqes(ring, cqe_ptr, 1, ts, NULL);
320
+ }
321
+
322
+ /*
323
+ * Submit sqes acquired from io_uring_get_sqe() to the kernel.
324
+ *
325
+ * Returns number of sqes submitted
326
+ */
327
+ static int __io_uring_submit(struct io_uring *ring, unsigned submitted,
328
+ unsigned wait_nr)
329
+ {
330
+ unsigned flags;
331
+ int ret;
332
+
333
+ flags = 0;
334
+ if (sq_ring_needs_enter(ring, &flags) || wait_nr) {
335
+ if (wait_nr || (ring->flags & IORING_SETUP_IOPOLL))
336
+ flags |= IORING_ENTER_GETEVENTS;
337
+
338
+ ret = __sys_io_uring_enter(ring->ring_fd, submitted, wait_nr,
339
+ flags, NULL);
340
+ if (ret < 0)
341
+ return -errno;
342
+ } else
343
+ ret = submitted;
344
+
345
+ return ret;
346
+ }
347
+
348
+ static int __io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr)
349
+ {
350
+ return __io_uring_submit(ring, __io_uring_flush_sq(ring), wait_nr);
351
+ }
352
+
353
+ /*
354
+ * Submit sqes acquired from io_uring_get_sqe() to the kernel.
355
+ *
356
+ * Returns number of sqes submitted
357
+ */
358
+ int io_uring_submit(struct io_uring *ring)
359
+ {
360
+ return __io_uring_submit_and_wait(ring, 0);
361
+ }
362
+
363
+ /*
364
+ * Like io_uring_submit(), but allows waiting for events as well.
365
+ *
366
+ * Returns number of sqes submitted
367
+ */
368
+ int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr)
369
+ {
370
+ return __io_uring_submit_and_wait(ring, wait_nr);
371
+ }
372
+
373
+ /*
374
+ * Return an sqe to fill. Application must later call io_uring_submit()
375
+ * when it's ready to tell the kernel about it. The caller may call this
376
+ * function multiple times before calling io_uring_submit().
377
+ *
378
+ * Returns a vacant sqe, or NULL if we're full.
379
+ */
380
+ struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring)
381
+ {
382
+ struct io_uring_sq *sq = &ring->sq;
383
+ unsigned int head = io_uring_smp_load_acquire(sq->khead);
384
+ unsigned int next = sq->sqe_tail + 1;
385
+ struct io_uring_sqe *sqe = NULL;
386
+
387
+ if (next - head <= *sq->kring_entries) {
388
+ sqe = &sq->sqes[sq->sqe_tail & *sq->kring_mask];
389
+ sq->sqe_tail = next;
390
+ }
391
+ return sqe;
392
+ }
393
+
394
+ int __io_uring_sqring_wait(struct io_uring *ring)
395
+ {
396
+ int ret;
397
+
398
+ ret = __sys_io_uring_enter(ring->ring_fd, 0, 0, IORING_ENTER_SQ_WAIT,
399
+ NULL);
400
+ if (ret < 0)
401
+ ret = -errno;
402
+ return ret;
403
+ }