tools/testing/selftests/ublk/file_backed.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/ublk/file_backed.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/ublk/file_backed.c- Extension
.c- Size
- 8104 bytes
- Lines
- 283
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
kublk.h
Detected Declarations
function ublk_to_uring_opfunction loop_queue_flush_iofunction loop_queue_shmem_zc_iofunction loop_queue_tgt_rw_iofunction loop_queue_tgt_iofunction ublk_loop_queue_iofunction ublk_loop_io_donefunction ublk_loop_memset_filefunction ublk_loop_tgt_init
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
#include "kublk.h"
static enum io_uring_op ublk_to_uring_op(const struct ublksrv_io_desc *iod, int zc)
{
unsigned ublk_op = ublksrv_get_op(iod);
if (ublk_op == UBLK_IO_OP_READ)
return zc ? IORING_OP_READ_FIXED : IORING_OP_READ;
else if (ublk_op == UBLK_IO_OP_WRITE)
return zc ? IORING_OP_WRITE_FIXED : IORING_OP_WRITE;
ublk_assert(0);
}
static int loop_queue_flush_io(struct ublk_thread *t, struct ublk_queue *q,
const struct ublksrv_io_desc *iod, int tag)
{
unsigned ublk_op = ublksrv_get_op(iod);
struct io_uring_sqe *sqe[1];
ublk_io_alloc_sqes(t, sqe, 1);
io_uring_prep_fsync(sqe[0], ublk_get_registered_fd(q, 1) /*fds[1]*/, IORING_FSYNC_DATASYNC);
io_uring_sqe_set_flags(sqe[0], IOSQE_FIXED_FILE);
/* bit63 marks us as tgt io */
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1);
return 1;
}
/*
* Shared memory zero-copy I/O: when UBLK_IO_F_SHMEM_ZC is set, the
* request's data lives in a registered shared memory buffer. Decode
* index + offset from iod->addr and use the server's mmap of that
* buffer as the I/O buffer for the backing file.
*/
static int loop_queue_shmem_zc_io(struct ublk_thread *t, struct ublk_queue *q,
const struct ublksrv_io_desc *iod, int tag)
{
unsigned ublk_op = ublksrv_get_op(iod);
enum io_uring_op op = ublk_to_uring_op(iod, 0);
__u64 file_offset = iod->start_sector << 9;
__u32 len = iod->nr_sectors << 9;
__u32 shmem_idx = ublk_shmem_zc_index(iod->addr);
__u32 shmem_off = ublk_shmem_zc_offset(iod->addr);
struct io_uring_sqe *sqe[1];
void *addr;
if (shmem_idx >= UBLK_BUF_MAX || !shmem_table[shmem_idx].mmap_base)
return -EINVAL;
addr = shmem_table[shmem_idx].mmap_base + shmem_off;
ublk_io_alloc_sqes(t, sqe, 1);
if (!sqe[0])
return -ENOMEM;
io_uring_prep_rw(op, sqe[0], ublk_get_registered_fd(q, 1),
addr, len, file_offset);
io_uring_sqe_set_flags(sqe[0], IOSQE_FIXED_FILE);
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1);
return 1;
}
static int loop_queue_tgt_rw_io(struct ublk_thread *t, struct ublk_queue *q,
const struct ublksrv_io_desc *iod, int tag)
{
unsigned ublk_op = ublksrv_get_op(iod);
unsigned zc = ublk_queue_use_zc(q);
unsigned auto_zc = ublk_queue_use_auto_zc(q);
enum io_uring_op op = ublk_to_uring_op(iod, zc | auto_zc);
struct ublk_io *io = ublk_get_io(q, tag);
__u64 offset = iod->start_sector << 9;
__u32 len = iod->nr_sectors << 9;
struct io_uring_sqe *sqe[3];
void *addr = io->buf_addr;
unsigned short buf_index = ublk_io_buf_idx(t, q, tag);
/* shared memory zero-copy path */
if (iod->op_flags & UBLK_IO_F_SHMEM_ZC)
return loop_queue_shmem_zc_io(t, q, iod, tag);
if (iod->op_flags & UBLK_IO_F_INTEGRITY) {
ublk_io_alloc_sqes(t, sqe, 1);
/* Use second backing file for integrity data */
io_uring_prep_rw(op, sqe[0], ublk_get_registered_fd(q, 2),
io->integrity_buf,
ublk_integrity_len(q, len),
ublk_integrity_len(q, offset));
sqe[0]->flags = IOSQE_FIXED_FILE;
/* tgt_data = 1 indicates integrity I/O */
Annotation
- Immediate include surface: `kublk.h`.
- Detected declarations: `function ublk_to_uring_op`, `function loop_queue_flush_io`, `function loop_queue_shmem_zc_io`, `function loop_queue_tgt_rw_io`, `function loop_queue_tgt_io`, `function ublk_loop_queue_io`, `function ublk_loop_io_done`, `function ublk_loop_memset_file`, `function ublk_loop_tgt_init`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
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.