io_uring/rw.c
Source file repositories/reference/linux-study-clean/io_uring/rw.c
File Facts
- System
- Linux kernel
- Corpus path
io_uring/rw.c- Extension
.c- Size
- 36678 bytes
- Lines
- 1398
- Domain
- Kernel Services
- Bucket
- io_uring
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/errno.hlinux/fs.hlinux/file.hlinux/blk-mq.hlinux/mm.hlinux/slab.hlinux/fsnotify.hlinux/poll.hlinux/nospec.hlinux/compat.hlinux/io_uring/cmd.hlinux/indirect_call_wrapper.huapi/linux/io_uring.hfiletable.hio_uring.hopdef.hkbuf.halloc_cache.hrsrc.hpoll.hrw.h
Detected Declarations
struct io_rwfunction io_file_supports_nowaitfunction io_iov_compat_buffer_select_prepfunction io_iov_buffer_select_prepfunction io_import_vecfunction __io_import_rw_bufferfunction io_import_rw_bufferfunction io_rw_recyclefunction io_req_rw_cleanupfunction io_rw_alloc_asyncfunction io_meta_save_statefunction io_meta_restorefunction io_prep_rw_pifunction __io_prep_rwfunction io_rw_do_importfunction io_prep_rwfunction io_prep_readfunction io_prep_writefunction io_prep_rwvfunction io_prep_readvfunction io_prep_writevfunction io_init_rw_fixedfunction io_prep_read_fixedfunction io_prep_write_fixedfunction io_rw_import_reg_vecfunction io_rw_prep_reg_vecfunction io_prep_readv_fixedfunction io_prep_writev_fixedfunction io_read_mshot_prepfunction io_readv_writev_cleanupfunction io_rw_should_reissuefunction io_req_end_writefunction io_req_io_endfunction __io_complete_rw_commonfunction io_fixup_rw_resfunction io_req_rw_completefunction io_complete_rwfunction io_complete_rw_iopollfunction io_rw_donefunction kiocb_donefunction loop_rw_iterfunction io_async_buf_funcfunction io_rw_should_retryfunction io_iter_do_readfunction need_complete_iofunction io_rw_init_filefunction __io_readfunction io_read
Annotated Snippet
struct io_rw {
/* NOTE: kiocb has the file as the first member, so don't do it here */
struct kiocb kiocb;
u64 addr;
u32 len;
rwf_t flags;
};
static bool io_file_supports_nowait(struct io_kiocb *req, __poll_t mask)
{
/* If FMODE_NOWAIT is set for a file, we're golden */
if (req->flags & REQ_F_SUPPORT_NOWAIT)
return true;
/* No FMODE_NOWAIT, if we can poll, check the status */
if (io_file_can_poll(req)) {
struct poll_table_struct pt = { ._key = mask };
return vfs_poll(req->file, &pt) & mask;
}
/* No FMODE_NOWAIT support, and file isn't pollable. Tough luck. */
return false;
}
static int io_iov_compat_buffer_select_prep(struct io_rw *rw)
{
struct compat_iovec __user *uiov = u64_to_user_ptr(rw->addr);
struct compat_iovec iov;
if (copy_from_user(&iov, uiov, sizeof(iov)))
return -EFAULT;
rw->len = iov.iov_len;
return 0;
}
static int io_iov_buffer_select_prep(struct io_kiocb *req)
{
struct iovec __user *uiov;
struct iovec iov;
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
if (rw->len != 1)
return -EINVAL;
if (io_is_compat(req->ctx))
return io_iov_compat_buffer_select_prep(rw);
uiov = u64_to_user_ptr(rw->addr);
if (copy_from_user(&iov, uiov, sizeof(*uiov)))
return -EFAULT;
rw->len = iov.iov_len;
return 0;
}
static int io_import_vec(int ddir, struct io_kiocb *req,
struct io_async_rw *io,
const struct iovec __user *uvec,
size_t uvec_segs)
{
int ret, nr_segs;
struct iovec *iov;
if (io->vec.iovec) {
nr_segs = io->vec.nr;
iov = io->vec.iovec;
} else {
nr_segs = 1;
iov = &io->fast_iov;
}
ret = __import_iovec(ddir, uvec, uvec_segs, nr_segs, &iov, &io->iter,
io_is_compat(req->ctx));
if (unlikely(ret < 0))
return ret;
if (iov) {
req->flags |= REQ_F_NEED_CLEANUP;
io_vec_reset_iovec(&io->vec, iov, io->iter.nr_segs);
}
return 0;
}
static int __io_import_rw_buffer(int ddir, struct io_kiocb *req,
struct io_async_rw *io, struct io_br_sel *sel,
unsigned int issue_flags)
{
const struct io_issue_def *def = &io_issue_defs[req->opcode];
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
size_t sqe_len = rw->len;
sel->addr = u64_to_user_ptr(rw->addr);
if (def->vectored && !(req->flags & REQ_F_BUFFER_SELECT))
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/errno.h`, `linux/fs.h`, `linux/file.h`, `linux/blk-mq.h`, `linux/mm.h`, `linux/slab.h`, `linux/fsnotify.h`.
- Detected declarations: `struct io_rw`, `function io_file_supports_nowait`, `function io_iov_compat_buffer_select_prep`, `function io_iov_buffer_select_prep`, `function io_import_vec`, `function __io_import_rw_buffer`, `function io_import_rw_buffer`, `function io_rw_recycle`, `function io_req_rw_cleanup`, `function io_rw_alloc_async`.
- Atlas domain: Kernel Services / io_uring.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.