1*d9b57aa3SJens Axboe // SPDX-License-Identifier: GPL-2.0 2*d9b57aa3SJens Axboe /* 3*d9b57aa3SJens Axboe * io_uring opcode handling table 4*d9b57aa3SJens Axboe */ 5*d9b57aa3SJens Axboe #include <linux/kernel.h> 6*d9b57aa3SJens Axboe #include <linux/errno.h> 7*d9b57aa3SJens Axboe #include <linux/fs.h> 8*d9b57aa3SJens Axboe #include <linux/file.h> 9*d9b57aa3SJens Axboe #include <linux/io_uring.h> 10*d9b57aa3SJens Axboe 11*d9b57aa3SJens Axboe #include "io_uring_types.h" 12*d9b57aa3SJens Axboe #include "io_uring.h" 13*d9b57aa3SJens Axboe #include "opdef.h" 14*d9b57aa3SJens Axboe #include "refs.h" 15*d9b57aa3SJens Axboe #include "tctx.h" 16*d9b57aa3SJens Axboe #include "sqpoll.h" 17*d9b57aa3SJens Axboe #include "fdinfo.h" 18*d9b57aa3SJens Axboe #include "kbuf.h" 19*d9b57aa3SJens Axboe #include "rsrc.h" 20*d9b57aa3SJens Axboe 21*d9b57aa3SJens Axboe #include "xattr.h" 22*d9b57aa3SJens Axboe #include "nop.h" 23*d9b57aa3SJens Axboe #include "fs.h" 24*d9b57aa3SJens Axboe #include "splice.h" 25*d9b57aa3SJens Axboe #include "sync.h" 26*d9b57aa3SJens Axboe #include "advise.h" 27*d9b57aa3SJens Axboe #include "openclose.h" 28*d9b57aa3SJens Axboe #include "uring_cmd.h" 29*d9b57aa3SJens Axboe #include "epoll.h" 30*d9b57aa3SJens Axboe #include "statx.h" 31*d9b57aa3SJens Axboe #include "net.h" 32*d9b57aa3SJens Axboe #include "msg_ring.h" 33*d9b57aa3SJens Axboe #include "timeout.h" 34*d9b57aa3SJens Axboe #include "poll.h" 35*d9b57aa3SJens Axboe #include "cancel.h" 36*d9b57aa3SJens Axboe #include "rw.h" 37*d9b57aa3SJens Axboe 38*d9b57aa3SJens Axboe static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags) 39*d9b57aa3SJens Axboe { 40*d9b57aa3SJens Axboe WARN_ON_ONCE(1); 41*d9b57aa3SJens Axboe return -ECANCELED; 42*d9b57aa3SJens Axboe } 43*d9b57aa3SJens Axboe 44*d9b57aa3SJens Axboe static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb, 45*d9b57aa3SJens Axboe const struct io_uring_sqe *sqe) 46*d9b57aa3SJens Axboe { 47*d9b57aa3SJens Axboe return -EOPNOTSUPP; 48*d9b57aa3SJens Axboe } 49*d9b57aa3SJens Axboe 50*d9b57aa3SJens Axboe const struct io_op_def io_op_defs[] = { 51*d9b57aa3SJens Axboe [IORING_OP_NOP] = { 52*d9b57aa3SJens Axboe .audit_skip = 1, 53*d9b57aa3SJens Axboe .iopoll = 1, 54*d9b57aa3SJens Axboe .name = "NOP", 55*d9b57aa3SJens Axboe .prep = io_nop_prep, 56*d9b57aa3SJens Axboe .issue = io_nop, 57*d9b57aa3SJens Axboe }, 58*d9b57aa3SJens Axboe [IORING_OP_READV] = { 59*d9b57aa3SJens Axboe .needs_file = 1, 60*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 61*d9b57aa3SJens Axboe .pollin = 1, 62*d9b57aa3SJens Axboe .buffer_select = 1, 63*d9b57aa3SJens Axboe .plug = 1, 64*d9b57aa3SJens Axboe .audit_skip = 1, 65*d9b57aa3SJens Axboe .ioprio = 1, 66*d9b57aa3SJens Axboe .iopoll = 1, 67*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 68*d9b57aa3SJens Axboe .name = "READV", 69*d9b57aa3SJens Axboe .prep = io_prep_rw, 70*d9b57aa3SJens Axboe .issue = io_read, 71*d9b57aa3SJens Axboe .prep_async = io_readv_prep_async, 72*d9b57aa3SJens Axboe .cleanup = io_readv_writev_cleanup, 73*d9b57aa3SJens Axboe }, 74*d9b57aa3SJens Axboe [IORING_OP_WRITEV] = { 75*d9b57aa3SJens Axboe .needs_file = 1, 76*d9b57aa3SJens Axboe .hash_reg_file = 1, 77*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 78*d9b57aa3SJens Axboe .pollout = 1, 79*d9b57aa3SJens Axboe .plug = 1, 80*d9b57aa3SJens Axboe .audit_skip = 1, 81*d9b57aa3SJens Axboe .ioprio = 1, 82*d9b57aa3SJens Axboe .iopoll = 1, 83*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 84*d9b57aa3SJens Axboe .name = "WRITEV", 85*d9b57aa3SJens Axboe .prep = io_prep_rw, 86*d9b57aa3SJens Axboe .issue = io_write, 87*d9b57aa3SJens Axboe .prep_async = io_writev_prep_async, 88*d9b57aa3SJens Axboe .cleanup = io_readv_writev_cleanup, 89*d9b57aa3SJens Axboe }, 90*d9b57aa3SJens Axboe [IORING_OP_FSYNC] = { 91*d9b57aa3SJens Axboe .needs_file = 1, 92*d9b57aa3SJens Axboe .audit_skip = 1, 93*d9b57aa3SJens Axboe .name = "FSYNC", 94*d9b57aa3SJens Axboe .prep = io_fsync_prep, 95*d9b57aa3SJens Axboe .issue = io_fsync, 96*d9b57aa3SJens Axboe }, 97*d9b57aa3SJens Axboe [IORING_OP_READ_FIXED] = { 98*d9b57aa3SJens Axboe .needs_file = 1, 99*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 100*d9b57aa3SJens Axboe .pollin = 1, 101*d9b57aa3SJens Axboe .plug = 1, 102*d9b57aa3SJens Axboe .audit_skip = 1, 103*d9b57aa3SJens Axboe .ioprio = 1, 104*d9b57aa3SJens Axboe .iopoll = 1, 105*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 106*d9b57aa3SJens Axboe .name = "READ_FIXED", 107*d9b57aa3SJens Axboe .prep = io_prep_rw, 108*d9b57aa3SJens Axboe .issue = io_read, 109*d9b57aa3SJens Axboe }, 110*d9b57aa3SJens Axboe [IORING_OP_WRITE_FIXED] = { 111*d9b57aa3SJens Axboe .needs_file = 1, 112*d9b57aa3SJens Axboe .hash_reg_file = 1, 113*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 114*d9b57aa3SJens Axboe .pollout = 1, 115*d9b57aa3SJens Axboe .plug = 1, 116*d9b57aa3SJens Axboe .audit_skip = 1, 117*d9b57aa3SJens Axboe .ioprio = 1, 118*d9b57aa3SJens Axboe .iopoll = 1, 119*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 120*d9b57aa3SJens Axboe .name = "WRITE_FIXED", 121*d9b57aa3SJens Axboe .prep = io_prep_rw, 122*d9b57aa3SJens Axboe .issue = io_write, 123*d9b57aa3SJens Axboe }, 124*d9b57aa3SJens Axboe [IORING_OP_POLL_ADD] = { 125*d9b57aa3SJens Axboe .needs_file = 1, 126*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 127*d9b57aa3SJens Axboe .audit_skip = 1, 128*d9b57aa3SJens Axboe .name = "POLL_ADD", 129*d9b57aa3SJens Axboe .prep = io_poll_add_prep, 130*d9b57aa3SJens Axboe .issue = io_poll_add, 131*d9b57aa3SJens Axboe }, 132*d9b57aa3SJens Axboe [IORING_OP_POLL_REMOVE] = { 133*d9b57aa3SJens Axboe .audit_skip = 1, 134*d9b57aa3SJens Axboe .name = "POLL_REMOVE", 135*d9b57aa3SJens Axboe .prep = io_poll_remove_prep, 136*d9b57aa3SJens Axboe .issue = io_poll_remove, 137*d9b57aa3SJens Axboe }, 138*d9b57aa3SJens Axboe [IORING_OP_SYNC_FILE_RANGE] = { 139*d9b57aa3SJens Axboe .needs_file = 1, 140*d9b57aa3SJens Axboe .audit_skip = 1, 141*d9b57aa3SJens Axboe .name = "SYNC_FILE_RANGE", 142*d9b57aa3SJens Axboe .prep = io_sfr_prep, 143*d9b57aa3SJens Axboe .issue = io_sync_file_range, 144*d9b57aa3SJens Axboe }, 145*d9b57aa3SJens Axboe [IORING_OP_SENDMSG] = { 146*d9b57aa3SJens Axboe .needs_file = 1, 147*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 148*d9b57aa3SJens Axboe .pollout = 1, 149*d9b57aa3SJens Axboe .ioprio = 1, 150*d9b57aa3SJens Axboe .name = "SENDMSG", 151*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 152*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_msghdr), 153*d9b57aa3SJens Axboe .prep = io_sendmsg_prep, 154*d9b57aa3SJens Axboe .issue = io_sendmsg, 155*d9b57aa3SJens Axboe .prep_async = io_sendmsg_prep_async, 156*d9b57aa3SJens Axboe .cleanup = io_sendmsg_recvmsg_cleanup, 157*d9b57aa3SJens Axboe #else 158*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 159*d9b57aa3SJens Axboe #endif 160*d9b57aa3SJens Axboe }, 161*d9b57aa3SJens Axboe [IORING_OP_RECVMSG] = { 162*d9b57aa3SJens Axboe .needs_file = 1, 163*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 164*d9b57aa3SJens Axboe .pollin = 1, 165*d9b57aa3SJens Axboe .buffer_select = 1, 166*d9b57aa3SJens Axboe .ioprio = 1, 167*d9b57aa3SJens Axboe .name = "RECVMSG", 168*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 169*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_msghdr), 170*d9b57aa3SJens Axboe .prep = io_recvmsg_prep, 171*d9b57aa3SJens Axboe .issue = io_recvmsg, 172*d9b57aa3SJens Axboe .prep_async = io_recvmsg_prep_async, 173*d9b57aa3SJens Axboe .cleanup = io_sendmsg_recvmsg_cleanup, 174*d9b57aa3SJens Axboe #else 175*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 176*d9b57aa3SJens Axboe #endif 177*d9b57aa3SJens Axboe }, 178*d9b57aa3SJens Axboe [IORING_OP_TIMEOUT] = { 179*d9b57aa3SJens Axboe .audit_skip = 1, 180*d9b57aa3SJens Axboe .async_size = sizeof(struct io_timeout_data), 181*d9b57aa3SJens Axboe .name = "TIMEOUT", 182*d9b57aa3SJens Axboe .prep = io_timeout_prep, 183*d9b57aa3SJens Axboe .issue = io_timeout, 184*d9b57aa3SJens Axboe }, 185*d9b57aa3SJens Axboe [IORING_OP_TIMEOUT_REMOVE] = { 186*d9b57aa3SJens Axboe /* used by timeout updates' prep() */ 187*d9b57aa3SJens Axboe .audit_skip = 1, 188*d9b57aa3SJens Axboe .name = "TIMEOUT_REMOVE", 189*d9b57aa3SJens Axboe .prep = io_timeout_remove_prep, 190*d9b57aa3SJens Axboe .issue = io_timeout_remove, 191*d9b57aa3SJens Axboe }, 192*d9b57aa3SJens Axboe [IORING_OP_ACCEPT] = { 193*d9b57aa3SJens Axboe .needs_file = 1, 194*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 195*d9b57aa3SJens Axboe .pollin = 1, 196*d9b57aa3SJens Axboe .poll_exclusive = 1, 197*d9b57aa3SJens Axboe .ioprio = 1, /* used for flags */ 198*d9b57aa3SJens Axboe .name = "ACCEPT", 199*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 200*d9b57aa3SJens Axboe .prep = io_accept_prep, 201*d9b57aa3SJens Axboe .issue = io_accept, 202*d9b57aa3SJens Axboe #else 203*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 204*d9b57aa3SJens Axboe #endif 205*d9b57aa3SJens Axboe }, 206*d9b57aa3SJens Axboe [IORING_OP_ASYNC_CANCEL] = { 207*d9b57aa3SJens Axboe .audit_skip = 1, 208*d9b57aa3SJens Axboe .name = "ASYNC_CANCEL", 209*d9b57aa3SJens Axboe .prep = io_async_cancel_prep, 210*d9b57aa3SJens Axboe .issue = io_async_cancel, 211*d9b57aa3SJens Axboe }, 212*d9b57aa3SJens Axboe [IORING_OP_LINK_TIMEOUT] = { 213*d9b57aa3SJens Axboe .audit_skip = 1, 214*d9b57aa3SJens Axboe .async_size = sizeof(struct io_timeout_data), 215*d9b57aa3SJens Axboe .name = "LINK_TIMEOUT", 216*d9b57aa3SJens Axboe .prep = io_link_timeout_prep, 217*d9b57aa3SJens Axboe .issue = io_no_issue, 218*d9b57aa3SJens Axboe }, 219*d9b57aa3SJens Axboe [IORING_OP_CONNECT] = { 220*d9b57aa3SJens Axboe .needs_file = 1, 221*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 222*d9b57aa3SJens Axboe .pollout = 1, 223*d9b57aa3SJens Axboe .name = "CONNECT", 224*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 225*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_connect), 226*d9b57aa3SJens Axboe .prep = io_connect_prep, 227*d9b57aa3SJens Axboe .issue = io_connect, 228*d9b57aa3SJens Axboe .prep_async = io_connect_prep_async, 229*d9b57aa3SJens Axboe #else 230*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 231*d9b57aa3SJens Axboe #endif 232*d9b57aa3SJens Axboe }, 233*d9b57aa3SJens Axboe [IORING_OP_FALLOCATE] = { 234*d9b57aa3SJens Axboe .needs_file = 1, 235*d9b57aa3SJens Axboe .name = "FALLOCATE", 236*d9b57aa3SJens Axboe .prep = io_fallocate_prep, 237*d9b57aa3SJens Axboe .issue = io_fallocate, 238*d9b57aa3SJens Axboe }, 239*d9b57aa3SJens Axboe [IORING_OP_OPENAT] = { 240*d9b57aa3SJens Axboe .name = "OPENAT", 241*d9b57aa3SJens Axboe .prep = io_openat_prep, 242*d9b57aa3SJens Axboe .issue = io_openat, 243*d9b57aa3SJens Axboe .cleanup = io_open_cleanup, 244*d9b57aa3SJens Axboe }, 245*d9b57aa3SJens Axboe [IORING_OP_CLOSE] = { 246*d9b57aa3SJens Axboe .name = "CLOSE", 247*d9b57aa3SJens Axboe .prep = io_close_prep, 248*d9b57aa3SJens Axboe .issue = io_close, 249*d9b57aa3SJens Axboe }, 250*d9b57aa3SJens Axboe [IORING_OP_FILES_UPDATE] = { 251*d9b57aa3SJens Axboe .audit_skip = 1, 252*d9b57aa3SJens Axboe .iopoll = 1, 253*d9b57aa3SJens Axboe .name = "FILES_UPDATE", 254*d9b57aa3SJens Axboe .prep = io_files_update_prep, 255*d9b57aa3SJens Axboe .issue = io_files_update, 256*d9b57aa3SJens Axboe }, 257*d9b57aa3SJens Axboe [IORING_OP_STATX] = { 258*d9b57aa3SJens Axboe .audit_skip = 1, 259*d9b57aa3SJens Axboe .name = "STATX", 260*d9b57aa3SJens Axboe .prep = io_statx_prep, 261*d9b57aa3SJens Axboe .issue = io_statx, 262*d9b57aa3SJens Axboe .cleanup = io_statx_cleanup, 263*d9b57aa3SJens Axboe }, 264*d9b57aa3SJens Axboe [IORING_OP_READ] = { 265*d9b57aa3SJens Axboe .needs_file = 1, 266*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 267*d9b57aa3SJens Axboe .pollin = 1, 268*d9b57aa3SJens Axboe .buffer_select = 1, 269*d9b57aa3SJens Axboe .plug = 1, 270*d9b57aa3SJens Axboe .audit_skip = 1, 271*d9b57aa3SJens Axboe .ioprio = 1, 272*d9b57aa3SJens Axboe .iopoll = 1, 273*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 274*d9b57aa3SJens Axboe .name = "READ", 275*d9b57aa3SJens Axboe .prep = io_prep_rw, 276*d9b57aa3SJens Axboe .issue = io_read, 277*d9b57aa3SJens Axboe }, 278*d9b57aa3SJens Axboe [IORING_OP_WRITE] = { 279*d9b57aa3SJens Axboe .needs_file = 1, 280*d9b57aa3SJens Axboe .hash_reg_file = 1, 281*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 282*d9b57aa3SJens Axboe .pollout = 1, 283*d9b57aa3SJens Axboe .plug = 1, 284*d9b57aa3SJens Axboe .audit_skip = 1, 285*d9b57aa3SJens Axboe .ioprio = 1, 286*d9b57aa3SJens Axboe .iopoll = 1, 287*d9b57aa3SJens Axboe .async_size = sizeof(struct io_async_rw), 288*d9b57aa3SJens Axboe .name = "WRITE", 289*d9b57aa3SJens Axboe .prep = io_prep_rw, 290*d9b57aa3SJens Axboe .issue = io_write, 291*d9b57aa3SJens Axboe }, 292*d9b57aa3SJens Axboe [IORING_OP_FADVISE] = { 293*d9b57aa3SJens Axboe .needs_file = 1, 294*d9b57aa3SJens Axboe .audit_skip = 1, 295*d9b57aa3SJens Axboe .name = "FADVISE", 296*d9b57aa3SJens Axboe .prep = io_fadvise_prep, 297*d9b57aa3SJens Axboe .issue = io_fadvise, 298*d9b57aa3SJens Axboe }, 299*d9b57aa3SJens Axboe [IORING_OP_MADVISE] = { 300*d9b57aa3SJens Axboe .name = "MADVISE", 301*d9b57aa3SJens Axboe .prep = io_madvise_prep, 302*d9b57aa3SJens Axboe .issue = io_madvise, 303*d9b57aa3SJens Axboe }, 304*d9b57aa3SJens Axboe [IORING_OP_SEND] = { 305*d9b57aa3SJens Axboe .needs_file = 1, 306*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 307*d9b57aa3SJens Axboe .pollout = 1, 308*d9b57aa3SJens Axboe .audit_skip = 1, 309*d9b57aa3SJens Axboe .ioprio = 1, 310*d9b57aa3SJens Axboe .name = "SEND", 311*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 312*d9b57aa3SJens Axboe .prep = io_sendmsg_prep, 313*d9b57aa3SJens Axboe .issue = io_send, 314*d9b57aa3SJens Axboe #else 315*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 316*d9b57aa3SJens Axboe #endif 317*d9b57aa3SJens Axboe }, 318*d9b57aa3SJens Axboe [IORING_OP_RECV] = { 319*d9b57aa3SJens Axboe .needs_file = 1, 320*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 321*d9b57aa3SJens Axboe .pollin = 1, 322*d9b57aa3SJens Axboe .buffer_select = 1, 323*d9b57aa3SJens Axboe .audit_skip = 1, 324*d9b57aa3SJens Axboe .ioprio = 1, 325*d9b57aa3SJens Axboe .name = "RECV", 326*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 327*d9b57aa3SJens Axboe .prep = io_recvmsg_prep, 328*d9b57aa3SJens Axboe .issue = io_recv, 329*d9b57aa3SJens Axboe #else 330*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 331*d9b57aa3SJens Axboe #endif 332*d9b57aa3SJens Axboe }, 333*d9b57aa3SJens Axboe [IORING_OP_OPENAT2] = { 334*d9b57aa3SJens Axboe .name = "OPENAT2", 335*d9b57aa3SJens Axboe .prep = io_openat2_prep, 336*d9b57aa3SJens Axboe .issue = io_openat2, 337*d9b57aa3SJens Axboe .cleanup = io_open_cleanup, 338*d9b57aa3SJens Axboe }, 339*d9b57aa3SJens Axboe [IORING_OP_EPOLL_CTL] = { 340*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 341*d9b57aa3SJens Axboe .audit_skip = 1, 342*d9b57aa3SJens Axboe .name = "EPOLL", 343*d9b57aa3SJens Axboe #if defined(CONFIG_EPOLL) 344*d9b57aa3SJens Axboe .prep = io_epoll_ctl_prep, 345*d9b57aa3SJens Axboe .issue = io_epoll_ctl, 346*d9b57aa3SJens Axboe #else 347*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 348*d9b57aa3SJens Axboe #endif 349*d9b57aa3SJens Axboe }, 350*d9b57aa3SJens Axboe [IORING_OP_SPLICE] = { 351*d9b57aa3SJens Axboe .needs_file = 1, 352*d9b57aa3SJens Axboe .hash_reg_file = 1, 353*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 354*d9b57aa3SJens Axboe .audit_skip = 1, 355*d9b57aa3SJens Axboe .name = "SPLICE", 356*d9b57aa3SJens Axboe .prep = io_splice_prep, 357*d9b57aa3SJens Axboe .issue = io_splice, 358*d9b57aa3SJens Axboe }, 359*d9b57aa3SJens Axboe [IORING_OP_PROVIDE_BUFFERS] = { 360*d9b57aa3SJens Axboe .audit_skip = 1, 361*d9b57aa3SJens Axboe .iopoll = 1, 362*d9b57aa3SJens Axboe .name = "PROVIDE_BUFFERS", 363*d9b57aa3SJens Axboe .prep = io_provide_buffers_prep, 364*d9b57aa3SJens Axboe .issue = io_provide_buffers, 365*d9b57aa3SJens Axboe }, 366*d9b57aa3SJens Axboe [IORING_OP_REMOVE_BUFFERS] = { 367*d9b57aa3SJens Axboe .audit_skip = 1, 368*d9b57aa3SJens Axboe .iopoll = 1, 369*d9b57aa3SJens Axboe .name = "REMOVE_BUFFERS", 370*d9b57aa3SJens Axboe .prep = io_remove_buffers_prep, 371*d9b57aa3SJens Axboe .issue = io_remove_buffers, 372*d9b57aa3SJens Axboe }, 373*d9b57aa3SJens Axboe [IORING_OP_TEE] = { 374*d9b57aa3SJens Axboe .needs_file = 1, 375*d9b57aa3SJens Axboe .hash_reg_file = 1, 376*d9b57aa3SJens Axboe .unbound_nonreg_file = 1, 377*d9b57aa3SJens Axboe .audit_skip = 1, 378*d9b57aa3SJens Axboe .name = "TEE", 379*d9b57aa3SJens Axboe .prep = io_tee_prep, 380*d9b57aa3SJens Axboe .issue = io_tee, 381*d9b57aa3SJens Axboe }, 382*d9b57aa3SJens Axboe [IORING_OP_SHUTDOWN] = { 383*d9b57aa3SJens Axboe .needs_file = 1, 384*d9b57aa3SJens Axboe .name = "SHUTDOWN", 385*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 386*d9b57aa3SJens Axboe .prep = io_shutdown_prep, 387*d9b57aa3SJens Axboe .issue = io_shutdown, 388*d9b57aa3SJens Axboe #else 389*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 390*d9b57aa3SJens Axboe #endif 391*d9b57aa3SJens Axboe }, 392*d9b57aa3SJens Axboe [IORING_OP_RENAMEAT] = { 393*d9b57aa3SJens Axboe .name = "RENAMEAT", 394*d9b57aa3SJens Axboe .prep = io_renameat_prep, 395*d9b57aa3SJens Axboe .issue = io_renameat, 396*d9b57aa3SJens Axboe .cleanup = io_renameat_cleanup, 397*d9b57aa3SJens Axboe }, 398*d9b57aa3SJens Axboe [IORING_OP_UNLINKAT] = { 399*d9b57aa3SJens Axboe .name = "UNLINKAT", 400*d9b57aa3SJens Axboe .prep = io_unlinkat_prep, 401*d9b57aa3SJens Axboe .issue = io_unlinkat, 402*d9b57aa3SJens Axboe .cleanup = io_unlinkat_cleanup, 403*d9b57aa3SJens Axboe }, 404*d9b57aa3SJens Axboe [IORING_OP_MKDIRAT] = { 405*d9b57aa3SJens Axboe .name = "MKDIRAT", 406*d9b57aa3SJens Axboe .prep = io_mkdirat_prep, 407*d9b57aa3SJens Axboe .issue = io_mkdirat, 408*d9b57aa3SJens Axboe .cleanup = io_mkdirat_cleanup, 409*d9b57aa3SJens Axboe }, 410*d9b57aa3SJens Axboe [IORING_OP_SYMLINKAT] = { 411*d9b57aa3SJens Axboe .name = "SYMLINKAT", 412*d9b57aa3SJens Axboe .prep = io_symlinkat_prep, 413*d9b57aa3SJens Axboe .issue = io_symlinkat, 414*d9b57aa3SJens Axboe .cleanup = io_link_cleanup, 415*d9b57aa3SJens Axboe }, 416*d9b57aa3SJens Axboe [IORING_OP_LINKAT] = { 417*d9b57aa3SJens Axboe .name = "LINKAT", 418*d9b57aa3SJens Axboe .prep = io_linkat_prep, 419*d9b57aa3SJens Axboe .issue = io_linkat, 420*d9b57aa3SJens Axboe .cleanup = io_link_cleanup, 421*d9b57aa3SJens Axboe }, 422*d9b57aa3SJens Axboe [IORING_OP_MSG_RING] = { 423*d9b57aa3SJens Axboe .needs_file = 1, 424*d9b57aa3SJens Axboe .iopoll = 1, 425*d9b57aa3SJens Axboe .name = "MSG_RING", 426*d9b57aa3SJens Axboe .prep = io_msg_ring_prep, 427*d9b57aa3SJens Axboe .issue = io_msg_ring, 428*d9b57aa3SJens Axboe }, 429*d9b57aa3SJens Axboe [IORING_OP_FSETXATTR] = { 430*d9b57aa3SJens Axboe .needs_file = 1, 431*d9b57aa3SJens Axboe .name = "FSETXATTR", 432*d9b57aa3SJens Axboe .prep = io_fsetxattr_prep, 433*d9b57aa3SJens Axboe .issue = io_fsetxattr, 434*d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 435*d9b57aa3SJens Axboe }, 436*d9b57aa3SJens Axboe [IORING_OP_SETXATTR] = { 437*d9b57aa3SJens Axboe .name = "SETXATTR", 438*d9b57aa3SJens Axboe .prep = io_setxattr_prep, 439*d9b57aa3SJens Axboe .issue = io_setxattr, 440*d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 441*d9b57aa3SJens Axboe }, 442*d9b57aa3SJens Axboe [IORING_OP_FGETXATTR] = { 443*d9b57aa3SJens Axboe .needs_file = 1, 444*d9b57aa3SJens Axboe .name = "FGETXATTR", 445*d9b57aa3SJens Axboe .prep = io_fgetxattr_prep, 446*d9b57aa3SJens Axboe .issue = io_fgetxattr, 447*d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 448*d9b57aa3SJens Axboe }, 449*d9b57aa3SJens Axboe [IORING_OP_GETXATTR] = { 450*d9b57aa3SJens Axboe .name = "GETXATTR", 451*d9b57aa3SJens Axboe .prep = io_getxattr_prep, 452*d9b57aa3SJens Axboe .issue = io_getxattr, 453*d9b57aa3SJens Axboe .cleanup = io_xattr_cleanup, 454*d9b57aa3SJens Axboe }, 455*d9b57aa3SJens Axboe [IORING_OP_SOCKET] = { 456*d9b57aa3SJens Axboe .audit_skip = 1, 457*d9b57aa3SJens Axboe .name = "SOCKET", 458*d9b57aa3SJens Axboe #if defined(CONFIG_NET) 459*d9b57aa3SJens Axboe .prep = io_socket_prep, 460*d9b57aa3SJens Axboe .issue = io_socket, 461*d9b57aa3SJens Axboe #else 462*d9b57aa3SJens Axboe .prep = io_eopnotsupp_prep, 463*d9b57aa3SJens Axboe #endif 464*d9b57aa3SJens Axboe }, 465*d9b57aa3SJens Axboe [IORING_OP_URING_CMD] = { 466*d9b57aa3SJens Axboe .needs_file = 1, 467*d9b57aa3SJens Axboe .plug = 1, 468*d9b57aa3SJens Axboe .name = "URING_CMD", 469*d9b57aa3SJens Axboe .async_size = uring_cmd_pdu_size(1), 470*d9b57aa3SJens Axboe .prep = io_uring_cmd_prep, 471*d9b57aa3SJens Axboe .issue = io_uring_cmd, 472*d9b57aa3SJens Axboe .prep_async = io_uring_cmd_prep_async, 473*d9b57aa3SJens Axboe }, 474*d9b57aa3SJens Axboe }; 475*d9b57aa3SJens Axboe 476*d9b57aa3SJens Axboe const char *io_uring_get_opcode(u8 opcode) 477*d9b57aa3SJens Axboe { 478*d9b57aa3SJens Axboe if (opcode < IORING_OP_LAST) 479*d9b57aa3SJens Axboe return io_op_defs[opcode].name; 480*d9b57aa3SJens Axboe return "INVALID"; 481*d9b57aa3SJens Axboe } 482*d9b57aa3SJens Axboe 483*d9b57aa3SJens Axboe void __init io_uring_optable_init(void) 484*d9b57aa3SJens Axboe { 485*d9b57aa3SJens Axboe int i; 486*d9b57aa3SJens Axboe 487*d9b57aa3SJens Axboe BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST); 488*d9b57aa3SJens Axboe 489*d9b57aa3SJens Axboe for (i = 0; i < ARRAY_SIZE(io_op_defs); i++) { 490*d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].prep); 491*d9b57aa3SJens Axboe if (io_op_defs[i].prep != io_eopnotsupp_prep) 492*d9b57aa3SJens Axboe BUG_ON(!io_op_defs[i].issue); 493*d9b57aa3SJens Axboe WARN_ON_ONCE(!io_op_defs[i].name); 494*d9b57aa3SJens Axboe } 495*d9b57aa3SJens Axboe } 496