UBLK_U_CMD_GET_QUEUE_AFFINITYControl commands |
nr=0x01 ioctl=0x80207501 (_IOR('u', 0x01, 32 bytes)) |
6.4 |
Read the CPU set blk-mq maps to one hardware queue.
DetailsInputs: data[0] = queue id; addr/len = output buffer. len must be a multiple of
sizeof(unsigned long) and len * 8 >= nr_cpu_ids (ublk_ctrl_get_queue_affinity).
Output: a kernel cpumask (array of unsigned long, bit n = CPU n) of every possible CPU whose
tag_set.map[HCTX_TYPE_DEFAULT].mq_map[cpu] == queue; bytes past cpumask_size() are zeroed.
Errors: EINVAL (bad len, addr == 0, queue >= nr_hw_queues), EFAULT, ENOMEM, ENODEV (no such device).
Does not sleep, so since v6.19 (87213b0d847c) it is handled inline under IO_URING_F_NONBLOCK.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission). Permission mask for unprivileged devices: MAY_READ.
Legacy raw opcode: UBLK_CMD_GET_QUEUE_AFFINITY (0x01, since v6.0).
- Notes
- Valid any time after ADD_DEV (the tag set exists from ADD_DEV). The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
- Used by default to pin each queue’s I/O threads to the CPUs the kernel routes to it (when DeviceParams.CPUAffinity is empty); ctrl.Controller.GetQueueAffinity.
|
supported |
UBLK_CMD_GET_QUEUE_AFFINITYControl commands |
0x01 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_GET_QUEUE_AFFINITY.
DetailsSame handler as UBLK_U_CMD_GET_QUEUE_AFFINITY. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_GET_DEV_INFOControl commands |
nr=0x02 ioctl=0x80207502 (_IOR('u', 0x02, 32 bytes)) |
6.4 |
Read a device’s struct ublksrv_ctrl_dev_info.
DetailsInputs: dev_id; addr/len (len >= 64) receives the 64-byte ublksrv_ctrl_dev_info.
Output: the device’s current info: negotiated flags, state (UBLK_S_DEV_*), queues, depth,
max_io_buf_bytes, owner_uid/gid, the opaque ublksrv_flags, and ublksrv_pid translated into the
caller’s pid namespace (-1 if the server is gone or not visible; translation since v6.19-rc7, 47bdf1d29cae,
backported to 6.18.8).
Errors: ENODEV (no device with that id), EINVAL (len < 64, addr 0, or — for an unprivileged
device — no dev_path_len), EFAULT.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_GET_DEV_INFO (0x02, since v6.0).
- Notes
- There is no list command: enumerate devices by probing ids or by reading
/sys/class/ublk-char/. On an unprivileged device GET_DEV_INFO also needs the path prefix, which is how a client can tell the two apart. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works. - Commit
2d786e66c966- go-ublk
ctrl.Controller.GetDevInfo; public ublk.GetDeviceInfo, Device.KernelInfo, ListDevices (probes ids 0..63 only).
|
supported |
UBLK_CMD_GET_DEV_INFOControl commands |
0x02 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_GET_DEV_INFO.
DetailsSame handler as UBLK_U_CMD_GET_DEV_INFO. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_ADD_DEVControl commands |
nr=0x04 ioctl=0xc0207504 (_IOWR('u', 0x04, 32 bytes)) |
6.4 |
Create a device (/dev/ublkcN) and negotiate queues, depth, buffer size and features.
DetailsInputs: header queue_id must be 0xffff; header dev_id must equal info.dev_id (U32_MAX =
auto-assign, else < 2^20 since v6.7); addr/len (len >= 64) points at ublksrv_ctrl_dev_info with
nr_hw_queues (1..4096), queue_depth (1..4096), max_io_buf_bytes, flags, ublksrv_flags, and
io_desc_size (only with UBLK_F_IO_DESC_SIZE).
Output (written back to addr): assigned dev_id; nr_hw_queues clamped to nr_cpu_ids;
max_io_buf_bytes rounded down to PAGE_SIZE; flags &= UBLK_F_ALL, then forced on:
CMD_IOCTL_ENCODE | URING_CMD_COMP_IN_TASK | PER_IO_DAEMON | BUF_REG_OFF_DAEMON | SAFE_STOP_DEV
(PER_IO_DAEMON removed again with BATCH_IO; NEED_GET_DATA removed with USER_COPY / ZERO_COPY /
AUTO_BUF_REG / BATCH_IO; UNPRIVILEGED_DEV removed for a CAP_SYS_ADMIN caller; USER_RECOVERY and
REISSUE removed for an unprivileged device); owner_uid/gid = caller (init_user_ns ids);
io_desc_size = 24 unless IO_DESC_SIZE; state = DEAD and ublksrv_pid = -1 (reset since
e65848e4ce35, v7.2-rc6, backported to 6.1.183/6.6.151/6.12.103/6.18.44/7.1.8).
Errors: EINVAL (len/addr/queue_id, depth or queue count 0 or > 4096 [checked since v6.16,
8c8472855884, backported 6.6.95/6.12.35/6.15.4], dev_id mismatch or >= 2^20, bad recovery-flag
combination [v6.13+], QUIESCE without USER_RECOVERY, unprivileged with USER_COPY/ZERO_COPY/AUTO_BUF_REG,
INTEGRITY without USER_COPY, ZONED without USER_COPY/ZERO_COPY or without CONFIG_BLK_DEV_ZONED, bad
io_desc_size), EPERM (no CAP_SYS_ADMIN and no UNPRIVILEGED_DEV), EACCES (unprivileged device count
= ublks_max), EEXIST (requested id in use), EFAULT, ENOMEM, EINTR (killable ublk_ctl_mutex).
Privileges: CAP_SYS_ADMIN, or UBLK_F_UNPRIVILEGED_DEV (v6.3+) by any user who can open
/dev/ublk-control. ADD_DEV never takes a path prefix.
Legacy raw opcode: UBLK_CMD_ADD_DEV (0x04, since v6.0).
- Notes
- Unknown flag bits are silently cleared, so the written-back
flags is the negotiation result; compare it with what you asked for. Before v6.16 a zero or oversized depth/queue count was not rejected. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works. - Commit
2d786e66c966- go-ublk
ctrl.Controller.AddDev / AddDevice; public ublk.Create, CreateAndServe. Flags are pre-validated against the 7.3-rc5 rules (ctrl.ValidateFeatures, ctrl.Negotiate).
|
supported |
UBLK_CMD_ADD_DEVControl commands |
0x04 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_ADD_DEV.
DetailsSame handler as UBLK_U_CMD_ADD_DEV. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_DEL_DEVControl commands |
nr=0x05 ioctl=0xc0207505 (_IOWR('u', 0x05, 32 bytes)) |
6.4 |
Remove a device and wait until its id is free.
DetailsInputs: dev_id; no buffer.
Behaviour: ublk_ctrl_del_dev(wait=true): stops the device if it is still started
(ublk_stop_dev), deletes /dev/ublkcN, drops the creation reference, then waits interruptibly until
the device number is released — i.e. until the last reference (open /dev/ublkcN, its mmaps, the
release work) is gone. Calling it from a process that still holds /dev/ublkcN open blocks until that
process closes it or a signal arrives.
Errors: ENODEV, EINTR (interrupted wait; the device is still deleted, v6.5+ 3e9dce80dbf9),
EINTR/killed on the ublk_ctl_mutex.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_DEL_DEV (0x05, since v6.0).
- Notes
- Close and munmap everything on
/dev/ublkcN before DEL_DEV, or use DEL_DEV_ASYNC. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works. - Commit
2d786e66c966- go-ublk
ctrl.Controller.DelDev; used by Device.Close (after STOP_DEV and queue teardown) and ublk.DeleteDevice.
|
supported |
UBLK_CMD_DEL_DEVControl commands |
0x05 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_DEL_DEV.
DetailsSame handler as UBLK_U_CMD_DEL_DEV. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_START_DEVControl commands |
nr=0x06 ioctl=0xc0207506 (_IOWR('u', 0x06, 32 bytes)) |
6.4 |
Expose /dev/ublkbN once every queue has fetched all of its tags.
DetailsInputs: data[0] = the ublk server’s pid (> 0). Since v6.17 (c2c8089f325e) it must equal the tgid
of the process that opened /dev/ublkcN; since v6.19-rc7 (47bdf1d29cae, 6.18.8) the comparison is done
in the init pid namespace so servers in a pid namespace work.
Behaviour: requires UBLK_PARAM_TYPE_BASIC from SET_PARAMS; builds queue_limits from the params;
waits interruptibly until every queue has every tag fetched (ublk_wait_dev_ready_and_lock, v7.2-rc5
432a9b2780c0; earlier wait_for_completion_interruptible(&ub->completion)); allocates the gendisk
ublkbN, applies capacity/read-only, sets state LIVE, add_disk(). Partition scanning is deferred to a
work item since v6.19 (7fc4da6a304b, backported 6.18.4) and skipped entirely for unprivileged daemons or
with UBLK_F_NO_AUTO_PART_SCAN.
Errors: EINVAL (pid <= 0, no BASIC params, pid mismatch), EEXIST (already LIVE or disk still in
use), EINTR, EOPNOTSUPP (zoned params without CONFIG_BLK_DEV_ZONED), ENOMEM, add_disk errors.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_START_DEV (0x06, since v6.0).
- Notes
- START_DEV blocks until the FETCHes arrive, so issue it from a thread other than the queue threads (or asynchronously). Before v6.5 (53e7d08f6d6e, backported 6.1.43) an interrupted wait was ignored. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
ctrl.Controller.StartDev with os.Getpid(); called by Device.Start after the queue engines have primed their FETCHes.
|
supported |
UBLK_CMD_START_DEVControl commands |
0x06 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_START_DEV.
DetailsSame handler as UBLK_U_CMD_START_DEV. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_STOP_DEVControl commands |
nr=0x07 ioctl=0xc0207507 (_IOWR('u', 0x07, 32 bytes)) |
6.4 |
Remove /dev/ublkbN and abort the server’s pending fetches.
DetailsInputs: dev_id; no buffer.
Behaviour: ublk_stop_dev: with a queueing recovery mode first force-aborts requeued requests
(ublk_force_abort_dev); del_gendisk() (waits for in-flight requests, so the server must keep serving
until STOP_DEV returns); state -> DEAD, ublksrv_pid -> -1; cancels the partition-scan work; then
completes every still-pending FETCH/COMMIT uring_cmd with UBLK_IO_RES_ABORT (ublk_cancel_dev).
Result: always 0 for an existing device (ENODEV otherwise).
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_STOP_DEV (0x07, since v6.0).
- Notes
- Not reversible in practice: ublksrv and go-ublk delete the device after stopping it. TRY_STOP_DEV is the variant that refuses while the disk is open. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
ctrl.Controller.StopDev; Device.Stop/Close (or TRY_STOP_DEV when DeviceParams.SafeStop).
|
supported |
UBLK_CMD_STOP_DEVControl commands |
0x07 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_STOP_DEV.
DetailsSame handler as UBLK_U_CMD_STOP_DEV. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_SET_PARAMSControl commands |
nr=0x08 ioctl=0xc0207508 (_IOWR('u', 0x08, 32 bytes)) |
6.4 |
Set the device’s struct ublk_params (block limits) before START_DEV.
DetailsInputs: addr/len -> struct ublk_params; the leading len field must be non-zero and <= header
len; types non-zero. The kernel copies min(params.len, sizeof(kernel ublk_params)) bytes and masks
types with UBLK_PARAM_TYPE_ALL (unknown types silently dropped).
Validation (ublk_validate_params): BASIC mandatory: 9 <= logical_bs_shift <= PAGE_SHIFT (lower
bound since v6.3-rc6 1d1665279a84), physical_bs_shift, io_min_shift, io_opt_shift <= 28 (v7.1-rc3
86f33ca9bea3), logical <= physical, max_sectors <= max_io_buf_bytes >> 9, max_sectors >= PAGE_SIZE/512
(v7.1-rc4 1860c2f85922; 6.12.92/6.18.34/7.0.11), zoned => chunk_sectors power of two (v7.3-rc1
2707acf1856d; 6.12.110/6.18.52/7.2.6). DISCARD: max_discard_segments == 1 when max_discard_sectors,
discard_granularity != 0. DEVT is read-only (EINVAL). ZONED only with UBLK_F_ZONED and vice versa.
DMA_ALIGN, SEGMENT and INTEGRITY rules: see their entries. On any failure the stored params are zeroed.
Errors: EINVAL, EACCES (device already started: UB_STATE_USED since v6.14-rc6 5ac60242b017,
backported 6.1.131/6.6.83/6.12.19; before that only a LIVE device was refused, so SET_PARAMS during
recovery “succeeded” without effect), EFAULT.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_SET_PARAMS (0x08, since v6.0).
- Notes
- Params are applied only by START_DEV. A newer server sending a longer
ublk_params to an older kernel is fine (truncated); unknown types are dropped, so check GET_PARAMS if it matters. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works. - Commit
2d786e66c966- go-ublk
ctrl.Controller.SetParams / SetDeviceParams (BASIC, DISCARD, DMA_ALIGN, SEGMENT). ZONED and INTEGRITY are modeled in uapi.UblkParams but no public parameter sets them.
|
supported |
UBLK_CMD_SET_PARAMSControl commands |
0x08 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_SET_PARAMS.
DetailsSame handler as UBLK_U_CMD_SET_PARAMS. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
0aa73170eba5- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_GET_PARAMSControl commands |
nr=0x09 ioctl=0x80207509 (_IOR('u', 0x09, 32 bytes)) |
6.4 |
Read back the device’s struct ublk_params, with the read-only DEVT block filled in.
DetailsInputs: addr/len; the caller must store the buffer size in the leading len field
(0 < params.len <= header len).
Output: ublk_ctrl_fill_params_devt sets UBLK_PARAM_TYPE_DEVT (char major/minor always; disk
major/minor once started, else 0), then copies min(params.len, sizeof(ublk_params)) bytes of the stored
params (what SET_PARAMS stored, including its len/types).
Errors: EINVAL, EFAULT, ENODEV.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_GET_PARAMS (0x09, since v6.0).
- Notes
- DEVT exists since v6.3 (abb864d38085); on older kernels the block device numbers must come from sysfs. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
ctrl.Controller.GetParams (256-byte buffer; decodes every known type). Used by ublk.Recover to rebuild geometry.
|
supported |
UBLK_CMD_GET_PARAMSControl commands |
0x09 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_GET_PARAMS.
DetailsSame handler as UBLK_U_CMD_GET_PARAMS. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
0aa73170eba5- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_START_USER_RECOVERYControl commands |
nr=0x10 ioctl=0xc0207510 (_IOWR('u', 0x10, 32 bytes)) |
6.4 |
Begin taking over a recoverable device whose previous server has exited.
DetailsInputs: dev_id; no buffer, no data.
Preconditions (ublk_ctrl_start_recovery): created with UBLK_F_USER_RECOVERY (else EINVAL);
/dev/ublkcN no longer open (UB_STATE_OPEN clear — cleared at the end of the asynchronous release
work after the old server’s fds and io_uring are gone) and state QUIESCED or FAIL_IO (else EBUSY).
Version differences: v6.1–v6.14: this command also reset every tag (ublk_queue_reinit), cleared
ub->mm (so the new process can mmap) and re-armed the readiness completion — it was mandatory.
v6.11-rc7 (e58f5142f883, 6.1.110/6.6.51) returns EINVAL instead of oopsing when no queue was ever ready.
Since v6.15 (728cbac5fe21) the reset happens in ublk_ch_release_work_fn and START_USER_RECOVERY is only
a precondition check; END_USER_RECOVERY no longer depends on it since v7.2-rc5 (432a9b2780c0).
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_START_USER_RECOVERY (0x10, since v6.1).
- Requires
UBLK_F_USER_RECOVERY- Notes
- Poll: EBUSY is expected for a short while after the old server dies (release is asynchronous). The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
ctrl.Controller.StartUserRecovery; ublk.Recover retries EBUSY for up to 30 s.
|
supported |
UBLK_CMD_START_USER_RECOVERYControl commands |
0x10 (raw cmd_op) |
6.1 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_START_USER_RECOVERY.
DetailsSame handler as UBLK_U_CMD_START_USER_RECOVERY. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
c732a852b419- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_END_USER_RECOVERYControl commands |
nr=0x11 ioctl=0xc0207511 (_IOWR('u', 0x11, 32 bytes)) |
6.4 |
Finish recovery: wait for the new server’s fetches and put the device back to LIVE.
DetailsInputs: data[0] = new server pid (validated like START_DEV since v6.17).
Behaviour (ublk_ctrl_end_recovery): waits interruptibly until every queue has fetched every tag,
then requires a recoverable state (EBUSY otherwise) and UBLK_F_USER_RECOVERY (EINVAL), stores the
pid, sets state LIVE and kicks the requeue list so requests held during the outage are dispatched to the
new server. v6.1–v6.14 unquiesced the block queue / cleared fail_io here instead.
Errors: EINVAL (pid mismatch, no recovery), EBUSY, EINTR.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
Legacy raw opcode: UBLK_CMD_END_USER_RECOVERY (0x11, since v6.1).
- Requires
UBLK_F_USER_RECOVERY- Notes
- Before v7.2-rc5 the wait used a completion re-armed only by a successful START_USER_RECOVERY; skipping START could strand a requeued request (432a9b2780c0, backported 6.18.42/7.1.6). The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
ctrl.Controller.EndUserRecovery; ublk.Recover after the new queues have primed.
|
supported |
UBLK_CMD_END_USER_RECOVERYControl commands |
0x11 (raw cmd_op) |
6.1 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_END_USER_RECOVERY.
DetailsSame handler as UBLK_U_CMD_END_USER_RECOVERY. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
c732a852b419- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_GET_DEV_INFO2Control commands |
nr=0x12 ioctl=0x80207512 (_IOR('u', 0x12, 32 bytes)) |
6.4 |
GET_DEV_INFO that always carries the char-device path, so it works for unprivileged devices.
DetailsInputs: addr points at a buffer whose first dev_path_len bytes are the NUL-terminated path of
/dev/ublkcN (dev_path_len includes the NUL, <= PATH_MAX, <= len), followed by room for the 64-byte
info. The kernel checks the path names the device’s char node (ublk_char_dev_permission: same rdev,
character device, inode_permission(MAY_READ)), then advances addr/len past the path.
Privileged devices: the caller still needs CAP_SYS_ADMIN and must supply the path (the only
command that requires a path on a privileged device).
Errors: as GET_DEV_INFO, plus EINVAL (missing/oversized path), EPERM/ENOENT/EACCES from the
path check.
Legacy raw opcode: UBLK_CMD_GET_DEV_INFO2 (0x12, since v6.3).
- Notes
- ublk.rst recommends: try GET_DEV_INFO2 first, fall back to GET_DEV_INFO on kernels that lack it. The ioctl-encoded form exists since v6.4; on v6.0–v6.3 only the raw opcode works.
- Commit
2d786e66c966- go-ublk
- ctrl.Controller.GetDevInfo2 (always sends the char-device path). The public GetDeviceInfo uses GET_DEV_INFO and adds the path automatically for unprivileged devices.
|
supported |
UBLK_CMD_GET_DEV_INFO2Control commands |
0x12 (raw cmd_op) |
6.3 |
Legacy (non-ioctl) opcode for UBLK_U_CMD_GET_DEV_INFO2.
DetailsSame handler as UBLK_U_CMD_GET_DEV_INFO2. The driver accepts a raw opcode (_IOC_TYPE == 0) only when built with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y (ublk_check_cmd_op, v6.4+; check fixed in v6.4-rc2 e485bd9e2c41); without it the command fails with EOPNOTSUPP. On v6.0–v6.3 it is the only encoding. The number is also _IOC_NR of the ioctl form, which is what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy command definition, don’t use in new application”. Ubuntu and the AL2023 6.18 kernel build with the legacy option off (see distro-kernels.md).
- Commit
4093cb5a0634- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_CMD_GET_FEATURESControl commands |
nr=0x13 ioctl=0x80207513 (_IOR('u', 0x13, 32 bytes)) |
6.5 |
Read the kernel’s supported UBLK_F_* mask (UBLK_F_ALL).
DetailsInputs: addr/len with len == UBLK_FEATURES_LEN (8) exactly. dev_id is ignored: the command
is handled before any device lookup and before permission checks.
Output: the 64-bit UBLK_F_ALL of the running kernel (UBLK_F_INTEGRITY only when built with
CONFIG_BLK_DEV_INTEGRITY).
Encoding gotcha: ublk_ctrl_uring_cmd compares the full opcode (cmd_op == UBLK_U_CMD_GET_FEATURES), unlike every other control command which is matched on _IOC_NR. An
_IOWR-encoded 0x13 therefore falls through to the device path and fails with ENODEV (or EOPNOTSUPP).
Errors: EINVAL (len != 8 or addr 0), EFAULT. Kernels before v6.5 do not know the command; with
dev_id = -1 they fail it (ENODEV on v6.4).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_GET_FEATURES).
- Notes
- Any user who can open
/dev/ublk-control may call it. kublk refuses to run without it (requires UBLK_F_CMD_IOCTL_ENCODE). - Commit
b5bbc52fd012- go-ublk
ctrl.Controller.GetFeatures (exact _IOR encoding); public ublk.Probe. Pre-6.5 kernels are treated as the v6.0 base set.
|
supported |
UBLK_U_CMD_DEL_DEV_ASYNCControl commands |
nr=0x14 ioctl=0x80207514 (_IOR('u', 0x14, 32 bytes)) |
6.9 |
Remove a device without waiting for its id to be freed.
DetailsSame as DEL_DEV (ublk_ctrl_del_dev(wait=false)): stop if needed, delete /dev/ublkcN, drop the
reference — but return immediately; the id becomes reusable when the last reference goes. Avoids the
close/munmap/unregister ordering problem of DEL_DEV.
Broken dispatch in v6.9 and v6.10: the switch compared _IOC_NR(cmd_op) with the full ioctl value,
so the command never matched and failed with -ENOTSUPP (524). Fixed in v6.11-rc1 (55fbb9a5d64e,
no stable backport). Usable from v6.11.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_DEL_DEV_ASYNC).
- Notes
- Header encodes it
_IOR although it carries no output; the driver only checks _IOC_NR. - Commit
13fe8e6825e4- go-ublk
- ublk.DeleteDeviceAsync (6.11+).
|
supported |
UBLK_U_CMD_UPDATE_SIZEControl commands |
nr=0x15 ioctl=0xc0207515 (_IOWR('u', 0x15, 32 bytes)) |
6.16 |
Change a started device’s capacity.
DetailsInputs: data[0] = new size in 512-byte sectors.
Behaviour (ublk_ctrl_set_size): stores it in params.basic.dev_sectors and calls
set_capacity_and_notify() (uevent with RESIZE=1; partitions are not rescanned). The driver does not
check UBLK_F_UPDATE_SIZE; the flag only advertises the command. No validation of the value.
Errors: ENODEV if the device has no disk (never started or stopped) — since v7.0-rc4
(25966fc09769, backported 6.18.20/6.19.9); v6.16–v6.19 kernels without it dereference NULL instead.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_UPDATE_SIZE).
- Requires
UBLK_F_UPDATE_SIZE- Notes
- The backend must already serve the new size when growing, and must stop accepting I/O beyond it only after shrinking.
- Commit
98b995660bff- go-ublk
ctrl.Controller.UpdateSize (refuses a DEAD device to dodge the pre-7.0 NULL deref); public Device.Resize.
|
supported |
UBLK_U_CMD_QUIESCE_DEVControl commands |
nr=0x16 ioctl=0xc0207516 (_IOWR('u', 0x16, 32 bytes)) |
6.16 |
Drain a LIVE device and abort the server’s fetches so the server can hand over (live upgrade).
DetailsInputs: data[0] = timeout in milliseconds (0 = wait forever; the value is passed to an
unsigned int parameter, so it is truncated to 32 bits).
Behaviour (ublk_ctrl_quiesce_dev): EOPNOTSUPP without UBLK_F_QUIESCE; ENODEV if no disk or
DEAD; returns 0 at once if not LIVE. Otherwise marks the device canceling (new requests are requeued),
waits until every queue has at least one idle tag whose FETCH can be cancelled (ublk_wait_for_idle_io;
skipped for BATCH_IO), then cancels all pending FETCH/COMMIT uring_cmds with UBLK_IO_RES_ABORT. The
server then exits/closes /dev/ublkcN; the release work moves the device to QUIESCED (or FAIL_IO),
ready for START/END_USER_RECOVERY by the next server.
Errors: EOPNOTSUPP, ENODEV, EBUSY (timeout: all I/O stayed with the server), EINTR.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_QUIESCE_DEV).
- Requires
UBLK_F_QUIESCE- Notes
- Requires UBLK_F_QUIESCE, which itself requires UBLK_F_USER_RECOVERY at ADD_DEV.
- Commit
b465ae7b2524- go-ublk
ctrl.Controller.QuiesceDev; used by Device.Detach when the device has QUIESCE (30 s timeout).
|
supported |
UBLK_U_CMD_TRY_STOP_DEVControl commands |
nr=0x17 ioctl=0xc0207517 (_IOWR('u', 0x17, 32 bytes)) |
7.0 |
STOP_DEV only if nobody has the block device open.
DetailsBehaviour (ublk_ctrl_try_stop_dev): ENODEV if there is no disk; under disk->open_mutex,
EBUSY if disk_openers() > 0; otherwise sets block_open (further opens of /dev/ublkbN fail with
ENXIO) and performs STOP_DEV.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_TRY_STOP_DEV).
- Requires
UBLK_F_SAFE_STOP_DEV- Notes
- Advertised by
UBLK_F_SAFE_STOP_DEV, which every v7.0+ kernel reports. - Commit
93ada1b3da39- go-ublk
ctrl.Controller.TryStopDev; Device.Stop uses it when DeviceParams.SafeStop (EBUSY -> ErrDeviceBusy).
|
supported |
UBLK_U_CMD_REG_BUFControl commands |
nr=0x18 ioctl=0xc0207518 (_IOWR('u', 0x18, 32 bytes)) |
7.1 |
Register a shared-memory buffer for UBLK_F_SHMEM_ZC zero copy; returns its index.
DetailsInputs: addr -> struct ublk_shmem_buf_reg (up to len bytes, max 24, copied; missing tail is
zero). flags may only be UBLK_SHMEM_BUF_READ_ONLY; reserved must be 0; len non-zero, page-aligned,
<= 4 GiB; addr page-aligned.
Behaviour (ublk_ctrl_reg_buf): long-term pins the pages (FOLL_WRITE unless READ_ONLY), freezes the
queue if started, allocates an index 0..65535 (IDA), inserts the PFN ranges into the device’s maple tree.
Allowed before START_DEV (365ea7cc6244, same release).
Result: the buffer index (>= 0). Errors: EOPNOTSUPP (no SHMEM_ZC), EINVAL, EFAULT (partial
pin), ENOMEM, ENOSPC (indexes exhausted), EEXIST (pages already registered).
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_REG_BUF).
- Requires
UBLK_F_SHMEM_ZC- Notes
- The registration struct is out of line precisely so an unprivileged caller can prefix the path at
addr. - Commit
2fb0ded237bb- go-ublk
- Device.RegisterSharedMemory (with DeviceParams.SharedMemoryZeroCopy).
|
supported |
UBLK_U_CMD_UNREG_BUFControl commands |
nr=0x19 ioctl=0xc0207519 (_IOWR('u', 0x19, 32 bytes)) |
7.1 |
Unregister a REG_BUF buffer.
DetailsInputs: data[0] = index from REG_BUF. Errors: EOPNOTSUPP (no SHMEM_ZC), EINVAL (index >
65535), ENOENT (not registered). Unpins the pages after freezing the queue. All buffers are released
automatically when the device is freed.
Privileges: CAP_SYS_ADMIN for a privileged device; for a UBLK_F_UNPRIVILEGED_DEV device the caller must prefix the char-device path at addr and pass dev_path_len (see ublk_ctrl_uring_cmd_permission).
No raw/legacy opcode exists (the driver mirrors the number privately as UBLK_CMD_UNREG_BUF).
- Requires
UBLK_F_SHMEM_ZC- Commit
2fb0ded237bb- go-ublk
- Device.UnregisterSharedMemory.
|
supported |
UBLK_U_IO_FETCH_REQI/O commands |
nr=0x20 ioctl=0xc0107520 (_IOWR('u', 0x20, 16 bytes)) |
6.4 |
Arm a tag: hand the kernel one uring_cmd per (queue, tag) to complete when a request arrives.
DetailsSQE: struct ublksrv_io_cmd {q_id, tag, result (unused), addr} in the SQE command area of
/dev/ublkcN’s io_uring. addr = server data buffer for this tag; required in copy mode unless
UBLK_F_NEED_GET_DATA; must be 0 with USER_COPY / SUPPORT_ZERO_COPY / AUTO_BUF_REG (EINVAL). With
UBLK_F_AUTO_BUF_REG, sqe->addr carries a ublk_auto_buf_reg (buffer index + flags).
Rules: only before the device is ready (EBUSY once every queue has fetched all tags); once per tag
(EINVAL if already active); serialized by ub->mutex. The issuing task becomes the tag’s daemon
(io->task); all later commands for the tag must come from it (per-queue daemon on v6.0–v6.15: the task
that issued the queue’s last FETCH; per-I/O since v6.16). Not valid on a BATCH_IO device (EOPNOTSUPP).
On v6.0–v6.2 the I/O ring must use SQE128 too.
CQE (when a request is dispatched to this tag): UBLK_IO_RES_OK (descriptor at io_cmd_buf[tag] is
valid; for WRITE the data is already in addr), UBLK_IO_RES_NEED_GET_DATA (WRITE with NEED_GET_DATA),
UBLK_IO_RES_ABORT (device stopping / quiescing / server exiting: do not re-fetch), or a negative errno for
a rejected command.
Legacy raw opcode: UBLK_IO_FETCH_REQ (0x20, since v6.0).
- Notes
- Ioctl form since v6.4.
- Commit
2d786e66c966- go-ublk
internal/queue engine: one locked OS thread + io_uring per tag range primes every tag at start.
|
supported |
UBLK_IO_FETCH_REQI/O commands |
0x20 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_IO_FETCH_REQ.
DetailsAccepted only with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y on v6.4+; the only form on v6.0–v6.3. The I/O path matches _IOC_NR(cmd_op), so this number is also what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy IO command definition, don’t use in new application”.
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_IO_COMMIT_AND_FETCH_REQI/O commands |
nr=0x21 ioctl=0xc0107521 (_IOWR('u', 0x21, 16 bytes)) |
6.4 |
Complete the tag’s current request with a result and re-arm the tag in one command.
DetailsSQE: ublksrv_io_cmd {q_id, tag, result, addr}. result = bytes transferred (READ/WRITE) or 0, or a
negative errno; addr = buffer for the next request (copy mode; may be 0 with NEED_GET_DATA except for
READ) — for UBLK_IO_OP_ZONE_APPEND it is instead zone_append_lba (the sector written). With
AUTO_BUF_REG, sqe->addr carries the next ublk_auto_buf_reg; the previous auto-registered buffer is
unregistered automatically if this SQE goes to the same io_uring.
Rules: must come from the tag’s daemon task (EINVAL otherwise); the tag must be owned by the server
(EBUSY if a command is already pending); a stray COMMIT while NEED_GET_DATA is pending is EINVAL.
Completion semantics: see semantics.md §3 — negative results map through errno_to_blk_status(),
a 0-byte READ becomes EIO, short READ/WRITE results behave differently before and after v7.3-rc1.
The CQE for this SQE arrives with the next request (or ABORT).
Legacy raw opcode: UBLK_IO_COMMIT_AND_FETCH_REQ (0x21, since v6.0).
- Notes
- Ioctl form since v6.4.
- Commit
2d786e66c966- go-ublk
- Engine commits with full length on success, negative errno on failure (
Request.Complete/CompleteN).
|
supported |
UBLK_IO_COMMIT_AND_FETCH_REQI/O commands |
0x21 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_IO_COMMIT_AND_FETCH_REQ.
DetailsAccepted only with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y on v6.4+; the only form on v6.0–v6.3. The I/O path matches _IOC_NR(cmd_op), so this number is also what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy IO command definition, don’t use in new application”.
- Commit
71f28f3136af- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_IO_NEED_GET_DATAI/O commands |
nr=0x22 ioctl=0xc0107522 (_IOWR('u', 0x22, 16 bytes)) |
6.4 |
Second step of a two-phase WRITE: supply the buffer and let the kernel copy the payload into it.
DetailsUsed only with UBLK_F_NEED_GET_DATA after a FETCH/COMMIT completed with UBLK_IO_RES_NEED_GET_DATA.
SQE: {q_id, tag, addr = destination buffer}. The kernel copies the WRITE data into addr and
completes this SQE with UBLK_IO_RES_OK (synchronously since v6.16; via task work before), after
which the descriptor is valid and the server handles the WRITE and later sends COMMIT_AND_FETCH_REQ.
Issuing it when not expected, or anything else when it is expected, is EINVAL. Must come from the
daemon task.
Legacy raw opcode: UBLK_IO_NEED_GET_DATA (0x22, since v6.0).
- Requires
UBLK_F_NEED_GET_DATA- Notes
- Costs an extra round trip; only for servers that cannot pre-allocate per-tag buffers. Unavailable with USER_COPY/ZERO_COPY/AUTO_BUF_REG/BATCH_IO (flag cleared at ADD_DEV). Ioctl form since v6.4.
- Commit
2d786e66c966- go-ublk
- Engine handles
UBLK_IO_RES_NEED_GET_DATA (DeviceParams.NeedGetData).
|
supported |
UBLK_IO_NEED_GET_DATAI/O commands |
0x22 (raw cmd_op) |
6.0 |
Legacy (non-ioctl) opcode for UBLK_U_IO_NEED_GET_DATA.
DetailsAccepted only with CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y on v6.4+; the only form on v6.0–v6.3. The I/O path matches _IOC_NR(cmd_op), so this number is also what the driver switches on.
- Requires
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES- Notes
- Header: “Legacy IO command definition, don’t use in new application”.
- Commit
4e18403d9485- go-ublk
- go-ublk sends only the ioctl-encoded
UBLK_U_* form (minimum kernel 6.8), so the raw opcode is never used. The number is modeled in internal/uapi.
|
n/a |
UBLK_U_IO_REGISTER_IO_BUFI/O commands |
nr=0x23 ioctl=0xc0107523 (_IOWR('u', 0x23, 16 bytes)) |
6.15 |
Zero copy: install an in-flight request’s pages into the issuing io_uring’s fixed-buffer table.
DetailsSQE: {q_id, tag, addr = buffer-table index} sent on any io_uring that has a (sparse) registered
buffer table. The request’s bvec becomes a kernel fixed buffer at that index
(io_buffer_register_request, named io_buffer_register_bvec before v7.3); the server then uses
IORING_OP_READ_FIXED/WRITE_FIXED or IORING_URING_CMD_FIXED against it. The ublk request cannot
complete until every registration is dropped (refcount, see ublk_io comments).
Rules: UBLK_F_SUPPORT_ZERO_COPY required (EINVAL); request must be started and carry data.
On the daemon task it uses a cheap counter; off the daemon task it is allowed since v6.17
(UBLK_F_BUF_REG_OFF_DAEMON), on v6.15–v6.16 only the daemon may issue it. Also valid on BATCH_IO devices.
No raw opcode. On a BATCH_IO device the driver compares the full opcode value.
- Requires
UBLK_F_SUPPORT_ZERO_COPY- Notes
- Not available to unprivileged devices (kernel memory could leak if the server does not fill a READ).
- Commit
1f6540e2aabb- go-ublk
- Zero-copy engine (
EnableZeroCopy) when AUTO_BUF_REG is unavailable or falls back.
|
supported |
UBLK_U_IO_UNREGISTER_IO_BUFI/O commands |
nr=0x24 ioctl=0xc0107524 (_IOWR('u', 0x24, 16 bytes)) |
6.15 |
Zero copy: remove a buffer installed by REGISTER_IO_BUF (or AUTO_BUF_REG).
DetailsSQE: {addr = buffer-table index}; since v6.17 q_id/tag are ignored and any task may issue it
(UBLK_F_BUF_REG_OFF_DAEMON); on v6.15–v6.16 the q_id/tag of the registered request and the daemon task
were required. Calls io_buffer_unregister(); the request completes once its last registration is gone
and the server has committed it.
No raw opcode. On a BATCH_IO device the driver compares the full opcode value.
- Requires
UBLK_F_SUPPORT_ZERO_COPY- Commit
1f6540e2aabb- go-ublk
- Linked after the file I/O in the zero-copy engine.
|
supported |
UBLK_U_IO_PREP_IO_CMDSI/O commands |
nr=0x25 ioctl=0xc0107525 (_IOWR('u', 0x25, 16 bytes)) |
7.0 |
BATCH_IO: arm many tags of one queue at once (batch FETCH_REQ).
DetailsSQE cmd area: struct ublk_batch_io {q_id, flags, nr_elem, elem_bytes}; sqe->addr -> user buffer
of nr_elem * elem_bytes bytes of elements (ublk_elem_header {tag, buf_index, result} + optional
__u64 buf_addr if UBLK_BATCH_F_HAS_BUF_ADDR + optional __u64 zone_lba if HAS_ZONE_LBA).
elem_bytes must equal 8 + 8·HAS_BUF_ADDR + 8·HAS_ZONE_LBA; nr_elem <= queue_depth (E2BIG).
Flag rules (ublk_check_batch_cmd): HAS_ZONE_LBA needs ZONED; HAS_BUF_ADDR needs copy mode;
AUTO_BUF_REG_FALLBACK needs AUTO_BUF_REG and excludes HAS_BUF_ADDR.
Behaviour: the buffer is snapshotted (v7.2-rc3 f01f5275feb7) and each tag is fetched as by FETCH_REQ
(no daemon task is recorded — any task may serve any tag). All-or-nothing: on an error the already
prepared tags are reverted. Returns 0 or a negative errno.
No raw opcode. On a BATCH_IO device the driver compares the full opcode value.
- Requires
UBLK_F_BATCH_IO- Notes
- Only on a device created with UBLK_F_BATCH_IO (its
/dev/ublkcN uses ublk_ch_batch_io_fops). - Commit
e86f89ab24f5- go-ublk
- DeviceParams.BatchIO: one PREP_IO_CMDS per queue registers every tag.
|
supported |
UBLK_U_IO_COMMIT_IO_CMDSI/O commands |
nr=0x26 ioctl=0xc0107526 (_IOWR('u', 0x26, 16 bytes)) |
7.0 |
BATCH_IO: commit results for many tags (and re-arm them).
DetailsSame header and element format as PREP_IO_CMDS. Per element: result = completion result, buf_addr =
buffer for the next request (copy mode), zone_lba for zone append, buf_index for AUTO_BUF_REG.
Result: number of bytes of the element buffer processed (iter.done); elements after the first
failing one are not committed — divide by elem_bytes and retry the remainder. A negative errno only if
nothing was processed. Completions are batched through blk_mq_end_request_batch().
No raw opcode. On a BATCH_IO device the driver compares the full opcode value.
- Requires
UBLK_F_BATCH_IO- Commit
e86f89ab24f5- go-ublk
- DeviceParams.BatchIO: each I/O thread commits a round’s completions in one command, resubmitting unconsumed elements.
|
supported |
UBLK_U_IO_FETCH_IO_CMDSI/O commands |
nr=0x27 ioctl=0xc0107527 (_IOWR('u', 0x27, 16 bytes)) |
7.0 |
BATCH_IO: multishot fetch that delivers ready tags in provided buffers.
DetailsSQE: must set IORING_URING_CMD_MULTISHOT (uring_cmd multishot exists since v6.18, 620a50c92700) and
use a provided-buffer ring (sqe->buf_index = buffer group); header elem_bytes == 2, flags == 0.
CQEs: each CQE consumes one provided buffer filled with __u16 tags of requests now owned by the
server (res = byte count); read each tag’s descriptor from the mmapped io_cmd_buf. Several FETCH_IO_CMDS
may be queued on a queue (load balancing across tasks) but only one is active at a time. The command
terminates with an error CQE (e.g. -ENOBUFS when no buffer can be selected, UBLK_IO_RES_ABORT on
cancel / quiesce, -ENODEV if the queue is canceling when attached).
No raw opcode. On a BATCH_IO device the driver compares the full opcode value.
- Requires
UBLK_F_BATCH_IO- Commit
a4d883755399- go-ublk
- DeviceParams.BatchIO: multishot fetch into a 16 x 256-byte provided-buffer ring.
|
supported |
UBLK_F_SUPPORT_ZERO_COPYFeature flags |
1ULL<<0 (0x1) |
6.0 |
Zero copy via io_uring kernel fixed buffers (REGISTER/UNREGISTER_IO_BUF).
DetailsReserved in v6.0 but stripped by ADD_DEV (flags &= ~UBLK_F_SUPPORT_ZERO_COPY, “We are not ready to support zero copy”) on every kernel through v6.14. Functional since v6.15 (1f6540e2aabb): the kernel no longer copies data to/from the server buffer (ublk_need_map_io() false), FETCH/COMMIT must pass addr = 0, and the server reaches request pages only through REGISTER_IO_BUF + fixed-buffer io_uring ops. Decoupled from USER_COPY in v6.15-rc5 (69edf98be844). The server should align ublk_param_dma_align and ublk_param_segment with its backend. Clears NEED_GET_DATA.
- Conflicts with
UBLK_F_UNPRIVILEGED_DEV- Notes
- On 6.0–6.14 the bit is silently dropped from the negotiated flags, so check the written-back flags.
- Commit
71f28f3136af- go-ublk
DeviceParams.EnableZeroCopy with a ZeroCopyBackend (a backing file): the engine registers each request buffer (AUTO_BUF_REG when the kernel lists it, otherwise REGISTER_IO_BUF + linked UNREGISTER_IO_BUF) and reads/writes the file with fixed-buffer ops, fdatasync and fallocate on the queue’s ring. Not offered to Handlers; excludes user copy, NEED_GET_DATA and unprivileged.
|
supported |
UBLK_F_URING_CMD_COMP_IN_TASKFeature flags |
1ULL<<1 (0x2) |
6.0 |
Always dispatch requests to the server via io_uring_cmd_complete_in_task().
Detailsv6.0–v6.4: selected io_uring_cmd_complete_in_task() instead of task_work_add() for dispatch (task_work_add was only usable when ublk_drv was built in; for a module the flag was forced on since v6.1-rc4, 224e858f215a). v6.5 removed the task_work_add path (29dc5d06613f) and forces the flag on in every ADD_DEV reply; it has no effect since.
- Notes
- Informational only on v6.5+.
- Commit
0edb3696c171- go-ublk
- Not requested; the kernel forces it on and ignores it since 6.5.
|
n/a |
UBLK_F_NEED_GET_DATAFeature flags |
1ULL<<2 (0x4) |
6.0 |
Two-phase WRITE: deliver WRITEs without data, server supplies the buffer with UBLK_U_IO_NEED_GET_DATA.
DetailsFor WRITE requests (v6.0–v6.3 also FLUSH) the FETCH/COMMIT CQE returns UBLK_IO_RES_NEED_GET_DATA; the server allocates a buffer and issues NEED_GET_DATA, the kernel copies the payload and completes it with UBLK_IO_RES_OK. FETCH may pass addr = 0; COMMIT may pass addr = 0 unless the request is a READ. Cleared by ADD_DEV when combined with USER_COPY (v6.5+), SUPPORT_ZERO_COPY or AUTO_BUF_REG (v6.15/6.16+) or BATCH_IO (v7.0+).
- Conflicts with
UBLK_F_USER_COPY, UBLK_F_SUPPORT_ZERO_COPY, UBLK_F_AUTO_BUF_REG, UBLK_F_BATCH_IO- Notes
- Added for servers with existing buffer management; costs an extra round trip per WRITE.
- Commit
4e18403d9485- go-ublk
DeviceParams.NeedGetData; the engine issues NEED_GET_DATA.
|
supported |
UBLK_F_USER_RECOVERYFeature flags |
1ULL<<3 (0x8) |
6.1 |
Keep the device (and /dev/ublkbN) when the server dies so a new server can recover it.
DetailsWhen the server exits, ublk_ch_release_work_fn aborts what the server held and moves the device to UBLK_S_DEV_QUIESCED (or FAIL_IO with RECOVERY_FAIL_IO) instead of stopping it. Requests issued to the server are failed with EIO (default), requeued (REISSUE) or failed (FAIL_IO); new requests are requeued (default/REISSUE) or failed with BLK_STS_TARGET (FAIL_IO). A new server recovers with START_USER_RECOVERY, re-opens/mmaps /dev/ublkcN, fetches every tag, then END_USER_RECOVERY. Silently cleared for unprivileged devices. Full protocol and version history: semantics.md §9.
- Conflicts with
UBLK_F_UNPRIVILEGED_DEV- Notes
- Recovery was reworked in v6.15 (detection moved to char-device release; reset moved out of START_USER_RECOVERY). Known unfixed-before-v7.1 UAF on the recovery reset path: f7700a4415af.
- Commit
77a440e2cbb4- go-ublk
DeviceParams.Recovery (RecoveryQueue / RecoveryReissue / RecoveryFailIO), Device.Detach, ublk.Recover.
|
supported |
UBLK_F_USER_RECOVERY_REISSUEFeature flags |
1ULL<<4 (0x10) |
6.1 |
With USER_RECOVERY: requeue (re-issue) requests that were with the dead server.
Details__ublk_fail_req requeues instead of failing outstanding requests (ublk_nosrv_should_reissue_outstanding), so the new server sees them again after END_USER_RECOVERY. The backend must tolerate a write being applied twice. Silently cleared for unprivileged devices. Only valid together with USER_RECOVERY and not with FAIL_IO (EINVAL since v6.13, d00c0ea17955).
- Requires
UBLK_F_USER_RECOVERY- Conflicts with
UBLK_F_USER_RECOVERY_FAIL_IO- Commit
a0d41dc11374- go-ublk
RecoveryReissue.
|
supported |
UBLK_F_UNPRIVILEGED_DEVFeature flags |
1ULL<<5 (0x20) |
6.3 |
Let a non-root user create and own a device.
DetailsADD_DEV without CAP_SYS_ADMIN requires this flag (else EPERM); with CAP_SYS_ADMIN the flag is cleared. The kernel records the caller’s uid/gid; every later control command must carry the /dev/ublkcN path prefix (dev_path_len) and pass an inode permission check; only the owner may open /dev/ublkbN (v6.3, 48a905198024); partitions are never scanned; an I/O timeout SIGKILLs the server (v6.4, c0b79b0ff53b); at most ublks_max (default 64) such devices exist. USER_RECOVERY/REISSUE are silently dropped; USER_COPY (v6.12, 42aafd8b48ad, 6.6.58), SUPPORT_ZERO_COPY (v6.15) and AUTO_BUF_REG (v6.16) are rejected. Needs a udev rule making /dev/ublk-control accessible and chowning ublkc*/ublkb* to owner_uid/gid.
- Conflicts with
UBLK_F_USER_COPY, UBLK_F_SUPPORT_ZERO_COPY, UBLK_F_AUTO_BUF_REG, UBLK_F_USER_RECOVERY- Notes
- Before v6.12 an unprivileged USER_COPY server could leak uninitialized kernel memory by under-filling READs.
- Commit
4093cb5a0634- go-ublk
DeviceParams.EnableUnprivileged; every control command gets the path prefix automatically (ctrl.devRequest).
|
supported |
UBLK_F_CMD_IOCTL_ENCODEFeature flags |
1ULL<<6 (0x40) |
6.4 |
Advertises that the kernel accepts ioctl-encoded (UBLK_U_*) opcodes.
DetailsSet in every ADD_DEV reply since v6.4 (flags |= UBLK_F_CMD_IOCTL_ENCODE); the driver never reads the bit from the request. Its presence in GET_FEATURES / the ADD_DEV reply is how a server knows UBLK_U_* opcodes work.
- Commit
2d786e66c966- go-ublk
- Always requested; go-ublk sends only ioctl-encoded opcodes.
|
supported |
UBLK_F_USER_COPYFeature flags |
1ULL<<7 (0x80) |
6.5 |
Move data with pread()/pwrite() on /dev/ublkcN instead of kernel copies into a server buffer.
DetailsThe kernel never touches the server buffer; FETCH/COMMIT pass addr = 0 (except ZONE_APPEND’s LBA). The server copies with pread/pwrite (or io_uring READ/WRITE) at offset UBLKSRV_IO_BUF_OFFSET + (q_id << UBLK_QID_OFF) + (tag << UBLK_TAG_OFF) + byte_offset (+ UBLKSRV_IO_INTEGRITY_FLAG for the integrity buffer): read() copies a WRITE/ZONE_APPEND payload out, write() fills a READ/REPORT_ZONES. Allowed only while the server owns the request. Required by ZONED (or ZERO_COPY) and INTEGRITY. Rejected for unprivileged devices since v6.12. Details: semantics.md §5.
- Conflicts with
UBLK_F_UNPRIVILEGED_DEV, UBLK_F_NEED_GET_DATA- Notes
- Per-request data is limited to 32 MiB by the 25-bit offset field.
- Commit
1172d5b8beca- go-ublk
DeviceParams.EnableUserCopy; the engine pread/pwrites on the char fd.
|
supported |
UBLK_F_ZONEDFeature flags |
1ULL<<8 (0x100) |
6.6 |
Zoned block device (host-managed) support.
DetailsRequires CONFIG_BLK_DEV_ZONED and USER_COPY or SUPPORT_ZERO_COPY (ADD_DEV EINVAL otherwise) and UBLK_PARAM_TYPE_ZONED params (with chunk_sectors = zone size, a power of two). Adds the zone operations, UBLK_IO_OP_REPORT_ZONES (server fills a struct blk_zone array), and zone append, whose written sector is returned in COMMIT’s zone_append_lba.
- Requires
UBLK_F_USER_COPY- Notes
- UBLK_F_SUPPORT_ZERO_COPY also satisfies the requirement (v6.15+).
- Commit
29802d7ca33b- go-ublk
DeviceParams.EnableZoned + Zoned (zone size, open/active limits, max append); Handler-only (zone ops, Request.ReportZones, CompleteZoneAppend); user copy is turned on automatically.
|
supported |
UBLK_F_USER_RECOVERY_FAIL_IOFeature flags |
1ULL<<9 (0x200) |
6.13 |
With USER_RECOVERY: fail all I/O while no server is attached, instead of queueing it.
DetailsAfter the server dies the device goes to UBLK_S_DEV_FAIL_IO: outstanding requests fail with EIO, new requests fail immediately with BLK_STS_TARGET (ublk_prep_req), until a new server completes recovery. Valid only with USER_RECOVERY and not with REISSUE.
- Requires
UBLK_F_USER_RECOVERY- Conflicts with
UBLK_F_USER_RECOVERY_REISSUE- Commit
59eaa01ce7a6- go-ublk
RecoveryFailIO.
|
supported |
UBLK_F_UPDATE_SIZEFeature flags |
1ULL<<10 (0x400) |
6.16 |
Advertises UBLK_U_CMD_UPDATE_SIZE (online resize).
DetailsPurely informational: the driver does not check the bit when handling UPDATE_SIZE.
- Commit
98b995660bff- go-ublk
- Requested when the kernel lists it;
Device.Resize.
|
supported |
UBLK_F_AUTO_BUF_REGFeature flags |
1ULL<<11 (0x800) |
6.16 |
Zero copy without explicit commands: register each request buffer automatically before dispatch.
DetailsFETCH/COMMIT pass a ublk_auto_buf_reg in sqe->addr (index + flags, reserved fields 0, else EINVAL). Before completing the fetch CQE the kernel registers the request bvec at that index in the same io_uring’s sparse buffer table and unregisters it at COMMIT (if COMMIT goes to the same ring; otherwise the server must UNREGISTER_IO_BUF). If registration fails: with UBLK_AUTO_BUF_REG_FALLBACK the CQE is delivered with UBLK_IO_F_NEED_REG_BUF set in the descriptor; without it the request is failed with EIO and the uring_cmd stays pending. Compatible with SUPPORT_ZERO_COPY; clears NEED_GET_DATA; rejected for unprivileged devices.
- Conflicts with
UBLK_F_UNPRIVILEGED_DEV, UBLK_F_NEED_GET_DATA- Notes
- Buffer table max 16K entries per io_uring.
- Commit
99c1e4eb6a3f- go-ublk
- Requested automatically with
EnableZeroCopy when the kernel lists it; FETCH/COMMIT carry {Index: tag, Flags: UBLK_AUTO_BUF_REG_FALLBACK} and a request arriving with UBLK_IO_F_NEED_REG_BUF is registered manually.
|
supported |
UBLK_F_QUIESCEFeature flags |
1ULL<<12 (0x1000) |
6.16 |
Enables UBLK_U_CMD_QUIESCE_DEV (drain for live server upgrade).
DetailsMust be combined with USER_RECOVERY (ADD_DEV EINVAL otherwise). QUIESCE_DEV returns EOPNOTSUPP without it.
- Requires
UBLK_F_USER_RECOVERY- Commit
b465ae7b2524- go-ublk
- Requested with any RecoveryMode when the kernel lists it; used by
Device.Detach.
|
supported |
UBLK_F_PER_IO_DAEMONFeature flags |
1ULL<<13 (0x2000) |
6.16 |
Each (queue, tag) may have its own daemon task instead of one task per queue.
DetailsCapability flag: v6.16+ always report it (except with BATCH_IO, where the kernel clears it since there is no daemon at all). The task that issues a tag’s FETCH_REQ owns that tag; other tags of the same queue can be served by other tasks, so a server can spread one hot queue over several threads. On older kernels all tags of a queue must be served by one task.
- Conflicts with
UBLK_F_BATCH_IO- Commit
ab03a61c6614- go-ublk
DeviceParams.ThreadsPerQueue > 1 splits a queue’s tags across engines (requires the flag).
|
supported |
UBLK_F_BUF_REG_OFF_DAEMONFeature flags |
1ULL<<14 (0x4000) |
6.17 |
REGISTER/UNREGISTER_IO_BUF may be issued from any task.
DetailsCapability flag always reported since v6.17. UNREGISTER_IO_BUF also ignores q_id/tag.
- Requires
UBLK_F_SUPPORT_ZERO_COPY- Commit
763ff02ce287- go-ublk
- go-ublk issues REGISTER/UNREGISTER_IO_BUF on the tag’s own engine thread, so it never needs off-daemon registration.
|
n/a |
UBLK_F_BATCH_IOFeature flags |
1ULL<<15 (0x8000) |
7.0 |
Per-queue batch I/O commands (PREP/COMMIT/FETCH_IO_CMDS) replace per-tag FETCH/COMMIT.
DetailsThe device’s char node uses ublk_ch_batch_io_fops; per-tag FETCH_REQ/COMMIT_AND_FETCH_REQ/NEED_GET_DATA are rejected; REGISTER/UNREGISTER_IO_BUF still work. No daemon task: any task can serve any tag. Clears PER_IO_DAEMON and NEED_GET_DATA. FETCH_IO_CMDS needs multishot uring_cmd (v6.18+ io_uring) and provided buffer rings. Protocol: semantics.md §8.
- Conflicts with
UBLK_F_NEED_GET_DATA, UBLK_F_PER_IO_DAEMON- Notes
- Several recovery fixes landed after 7.0 (e4c4bfec2bb8, 8a14be55bdc6 [7.2.7]).
- Commit
e2723e6ce602- go-ublk
- DeviceParams.BatchIO (copy and user-copy modes; not with zero copy).
|
supported |
UBLK_F_INTEGRITYFeature flags |
1ULL<<16 (0x10000) |
7.0 |
Requests may carry an integrity/metadata (PI) buffer.
DetailsRequires USER_COPY (ADD_DEV EINVAL) and a kernel with CONFIG_BLK_DEV_INTEGRITY (otherwise absent from UBLK_F_ALL). Configure with UBLK_PARAM_TYPE_INTEGRITY; requests with metadata have UBLK_IO_F_INTEGRITY set and the server reads/writes the metadata with pread/pwrite at the user-copy offset OR’ed with UBLKSRV_IO_INTEGRITY_FLAG (bit 62).
- Requires
UBLK_F_USER_COPY- Commit
98bf2256855e- go-ublk
DeviceParams.Integrity (IntegrityParams: metadata size, interval, checksum, reftag, PI offset, tag size); user copy forced on; Backends implement IntegrityBackend, Handlers get Request.Integrity.
|
supported |
UBLK_F_SAFE_STOP_DEVFeature flags |
1ULL<<17 (0x20000) |
7.0 |
Advertises UBLK_U_CMD_TRY_STOP_DEV.
DetailsAlways reported since v7.0.
- Commit
93ada1b3da39- go-ublk
DeviceParams.SafeStop -> TRY_STOP_DEV.
|
supported |
UBLK_F_NO_AUTO_PART_SCANFeature flags |
1ULL<<18 (0x40000) |
7.0 |
Do not scan partitions when the device starts.
DetailsSTART_DEV skips the async partition scan and clears GD_SUPPRESS_PART_SCAN (only for trusted daemons; v7.0-rc4 155a3bedccaf) so a later BLKRRPART works.
- Commit
8443e2087e70- go-ublk
DeviceParams.NoPartitionScan.
|
supported |
UBLK_F_SHMEM_ZCFeature flags |
1ULL<<19 (0x80000) |
7.1 |
Shared-memory zero copy: requests whose pages lie in a registered buffer arrive by reference.
DetailsThe server registers memfd/hugetlbfs memory it shares with clients via UBLK_U_CMD_REG_BUF. When a request’s pages all fall contiguously inside one registered buffer (PFN maple-tree match, ublk_try_buf_match) the descriptor gets UBLK_IO_F_SHMEM_ZC and addr = ublk_shmem_zc_addr(index, offset); no copy happens in either direction. Non-matching requests use the normal path. A READ_ONLY buffer only matches WRITEs. Only O_DIRECT client I/O can match.
- Commit
08677040a911- go-ublk
- DeviceParams.SharedMemoryZeroCopy; requests in registered regions arrive with FlagSharedMemory and Data pointing into the region.
|
supported |
UBLK_F_IO_DESC_SIZEFeature flags |
1ULL<<20 (0x100000) |
7.3-rc1 |
Server chooses the per-tag descriptor stride (ublksrv_ctrl_dev_info.io_desc_size).
DetailsWith the flag, ADD_DEV takes io_desc_size (24..256, multiple of 8) from dev_info (former pad0); otherwise it is set to 24. The mmapped descriptor array uses that stride: descriptor of tag t at t * io_desc_size, mmap length round_up(depth * io_desc_size, PAGE_SIZE), and queue q at offset q * round_up(4096 * io_desc_size, PAGE_SIZE). Bytes past the 24-byte ublksrv_io_desc are reserved for future kernel fields.
- Notes
- Unreleased as of 2026-10-04 (v7.3-rc).
- Commit
5c0958d80190- go-ublk
- DeviceParams.IODescSize; the engine honors the stride and exposes the extra bytes as Request.DescriptorExtra.
|
supported |
UBLK_S_DEV_DEADDevice states |
0 |
6.0 |
No block device: just added, or stopped.
DetailsSet at ADD_DEV (forced since e65848e4ce35) and by ublk_detach_disk on STOP_DEV / DEL_DEV / server exit without recovery. SET_PARAMS works only before the first START_DEV.
- Commit
71f28f3136af- go-ublk
KernelStateDead.
|
supported |
UBLK_S_DEV_LIVEDevice states |
1 |
6.0 |
Started and served.
DetailsEntered by START_DEV (before add_disk) and END_USER_RECOVERY.
- Commit
71f28f3136af- go-ublk
KernelStateLive.
|
supported |
UBLK_S_DEV_QUIESCEDDevice states |
2 |
6.1 |
Server gone (or QUIESCE_DEV), requests held for a recovering server.
DetailsRecovery mode without FAIL_IO. Since v6.15 the block queue is not quiesced; requests are requeued via the canceling flag until END_USER_RECOVERY kicks the requeue list (v6.1–v6.14: blk_mq_quiesce_queue).
- Commit
77a440e2cbb4- go-ublk
KernelStateQuiesced; Recover accepts it.
|
supported |
UBLK_S_DEV_FAIL_IODevice states |
3 |
6.13 |
Server gone, all I/O failing until a server recovers the device.
DetailsOnly with UBLK_F_USER_RECOVERY_FAIL_IO. New requests get BLK_STS_TARGET (-EREMOTEIO in userspace).
- Commit
59eaa01ce7a6- go-ublk
KernelStateFailIO.
|
supported |
UBLK_IO_OP_READI/O operations |
0 |
6.0 |
Read nr_sectors at start_sector into the request.
DetailsResult: bytes read (>0). A 0 result is turned into EIO. Copy mode: the kernel copies result bytes from the server buffer; a short result completes that many bytes and requeues the rest (all versions). With USER_COPY/zero copy a short positive result completed only that part before v7.3-rc1 but completes the whole request since a8a79eba22dc.
- Commit
71f28f3136af- go-ublk
- Dispatched to the Backend/Handler (
Request.Op).
|
supported |
UBLK_IO_OP_WRITEI/O operations |
1 |
6.0 |
Write nr_sectors at start_sector from the request.
DetailsResult: bytes written. v6.0–v7.2: a short result completes that many bytes and requeues the remainder (a 0 result requeues the whole request); v7.3-rc1+ (a8a79eba22dc): any non-negative result completes the entire request — return the full length or an errno.
- Commit
71f28f3136af- go-ublk
- Dispatched to the Backend/Handler (
Request.Op).
|
supported |
UBLK_IO_OP_FLUSHI/O operations |
2 |
6.0 |
Flush the volatile write cache.
DetailsSent only if the device advertises UBLK_ATTR_VOLATILE_CACHE. No data, nr_sectors 0. Result 0 or errno. Preflush/FUA on writes are turned into separate FLUSH requests by the block layer unless UBLK_ATTR_FUA is also set.
- Commit
71f28f3136af- go-ublk
- Dispatched to the Backend/Handler (
Request.Op).
|
supported |
UBLK_IO_OP_DISCARDI/O operations |
3 |
6.0 |
Deallocate a range.
DetailsSent only if DISCARD params set max_discard_sectors. No data; may exceed max_io_buf_bytes (range ops are not bounded by the data buffer). Single segment only.
- Commit
71f28f3136af- go-ublk
- Dispatched to the Backend/Handler (
Request.Op).
|
supported |
UBLK_IO_OP_WRITE_SAMEI/O operations |
4 |
6.0 |
Defined but never generated.
Detailsublk_setup_iod has no mapping for it (REQ_OP_WRITE_SAME left the block layer in 5.18), so no kernel ever sends it.
- Commit
71f28f3136af- go-ublk
- Constant only; never sent by the kernel.
|
n/a |
UBLK_IO_OP_WRITE_ZEROESI/O operations |
5 |
6.0 |
Zero a range (optionally without deallocating).
DetailsSent only if max_write_zeroes_sectors is set. No data. UBLK_IO_F_NOUNMAP means the range must stay allocated.
- Commit
71f28f3136af- go-ublk
- Dispatched to the Backend/Handler (
Request.Op).
|
supported |
UBLK_IO_OP_ZONE_OPENI/O operations |
10 |
6.6 |
Explicitly open a zone.
DetailsZoned devices only.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_ZONE_CLOSEI/O operations |
11 |
6.6 |
Close a zone.
DetailsZoned devices only.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_ZONE_FINISHI/O operations |
12 |
6.6 |
Finish (fill) a zone.
DetailsZoned devices only.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_ZONE_APPENDI/O operations |
13 |
6.6 |
Append data to a zone; the server picks the sector.
DetailsData flows like WRITE (USER_COPY read()/zero copy). Return the sector actually written in COMMIT’s zone_append_lba (req->__sector = addr); in batch mode in the element’s zone_lba with UBLK_BATCH_F_HAS_ZONE_LBA.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_ZONE_RESET_ALLI/O operations |
14 |
6.6 |
Reset every zone.
DetailsZoned devices only.
- Commit
851e06297f20- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_ZONE_RESETI/O operations |
15 |
6.6 |
Reset a zone’s write pointer.
DetailsZoned devices only.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_OP_REPORT_ZONESI/O operations |
18 |
6.6 |
Report zone descriptors.
DetailsCarried as REQ_OP_DRV_IN: start_sector = first zone, nr_zones (union with nr_sectors) = max zones. The server fills a struct blk_zone array (linux/blkzoned.h) into the request buffer (write() in USER_COPY mode); a zero-length entry ends the report early. Result = bytes.
- Commit
29802d7ca33b- go-ublk
- Delivered to a Handler on a zoned device (
EnableZoned, ublk.Op*).
|
supported |
UBLK_IO_F_FAILFAST_DEVI/O flags |
1U<<8 (0x100) |
6.0 |
REQ_FAILFAST_DEV: don’t retry on device errors.
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers on Request.Flags (ublk.Flag*); a hint a Backend may ignore.
|
supported |
UBLK_IO_F_FAILFAST_TRANSPORTI/O flags |
1U<<9 (0x200) |
6.0 |
REQ_FAILFAST_TRANSPORT: don’t retry on transport errors.
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers on Request.Flags (ublk.Flag*); a hint a Backend may ignore.
|
supported |
UBLK_IO_F_FAILFAST_DRIVERI/O flags |
1U<<10 (0x400) |
6.0 |
REQ_FAILFAST_DRIVER: don’t retry on driver errors.
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers on Request.Flags (ublk.Flag*); a hint a Backend may ignore.
|
supported |
UBLK_IO_F_METAI/O flags |
1U<<11 (0x800) |
6.0 |
REQ_META: filesystem metadata I/O (priority hint).
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers on Request.Flags (ublk.Flag*); a hint a Backend may ignore.
|
supported |
UBLK_IO_F_FUAI/O flags |
1U<<13 (0x2000) |
6.0 |
REQ_FUA: the write must be durable before completion.
DetailsOnly appears if the device advertises UBLK_ATTR_VOLATILE_CACHE | UBLK_ATTR_FUA; otherwise the block layer emulates FUA with a post-flush and the bit is never set. A server that advertises FUA must make such writes durable before completing them.
- Commit
71f28f3136af- go-ublk
- FUA is advertised only when the server honors it (
FUABackend or a Handler); ublk.FlagFUA.
|
supported |
UBLK_IO_F_NOUNMAPI/O flags |
1U<<15 (0x8000) |
6.0 |
REQ_NOUNMAP: WRITE_ZEROES must not deallocate.
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers as FlagNoUnmap. WriteZeroesBackend does not see it; zero-copy write-zeroes always uses FALLOC_FL_ZERO_RANGE, which keeps the allocation.
|
supported |
UBLK_IO_F_SWAPI/O flags |
1U<<16 (0x10000) |
6.0 |
REQ_SWAP: swap I/O (avoid allocating memory).
DetailsSet from req->cmd_flags by ublk_req_build_flags. Advisory; a server may ignore it.
- Commit
71f28f3136af- go-ublk
- Passed to Handlers on Request.Flags (ublk.Flag*); a hint a Backend may ignore.
|
supported |
UBLK_IO_F_NEED_REG_BUFI/O flags |
1U<<17 (0x20000) |
6.16 |
AUTO_BUF_REG fallback: automatic registration failed, register manually.
DetailsSet only when the server passed UBLK_AUTO_BUF_REG_FALLBACK (or UBLK_BATCH_F_AUTO_BUF_REG_FALLBACK) and io_buffer_register_request failed; the CQE is delivered anyway and the server must register the buffer itself or use user copy.
- Commit
53f427e7944b- go-ublk
- Zero-copy engine registers the buffer manually when it sees it (
ublk.FlagNeedRegBuf).
|
supported |
UBLK_IO_F_INTEGRITYI/O flags |
1U<<18 (0x40000) |
7.0 |
Request has an integrity (metadata) buffer.
DetailsSet when blk_integrity_rq(req). Read/write the metadata through user copy with UBLKSRV_IO_INTEGRITY_FLAG. Bit 12 held an unrelated pre-release UBLK_IO_F_INTEGRITY removed before v6.0 (d276a22314c2).
- Commit
f82f0a16a827- go-ublk
- Engine copies the metadata into/out of
Request.Integrity (ublk.FlagIntegrity).
|
supported |
UBLK_IO_F_SHMEM_ZCI/O flags |
1U<<19 (0x80000) |
7.1 |
addr encodes a shared-memory buffer index + offset (UBLK_F_SHMEM_ZC).
DetailsSet by ublk_init_iod when ublk_try_buf_match succeeds; decode with ublk_shmem_zc_index/offset. No data copy happens for such requests.
- Commit
2fb0ded237bb- go-ublk
- ublk.FlagSharedMemory; the engine resolves the index/offset address into the registered region.
|
supported |
UBLK_ATTR_READ_ONLYAttributes |
1<<0 |
6.0 |
Make /dev/ublkbN read-only (set_disk_ro).
DetailsBit of ublk_param_basic.attrs, applied at START_DEV (ublk_ctrl_start_dev, ublk_dev_param_basic_apply).
- Commit
0aa73170eba5- go-ublk
DeviceParams.ReadOnly.
|
supported |
UBLK_ATTR_ROTATIONALAttributes |
1<<1 |
6.0 |
Report a rotational device (BLK_FEAT_ROTATIONAL; before 6.11 QUEUE_FLAG_NONROT cleared).
DetailsBit of ublk_param_basic.attrs, applied at START_DEV (ublk_ctrl_start_dev, ublk_dev_param_basic_apply).
- Commit
0aa73170eba5- go-ublk
DeviceParams.Rotational.
|
supported |
UBLK_ATTR_VOLATILE_CACHEAttributes |
1<<2 |
6.0 |
Device has a volatile write cache: the kernel sends FLUSH.
DetailsBit of ublk_param_basic.attrs, applied at START_DEV (ublk_ctrl_start_dev, ublk_dev_param_basic_apply).
- Commit
0aa73170eba5- go-ublk
DeviceParams.VolatileCache (default true).
|
supported |
UBLK_ATTR_FUAAttributes |
1<<3 |
6.0 |
Device supports FUA writes (only honored together with VOLATILE_CACHE).
DetailsBit of ublk_param_basic.attrs, applied at START_DEV (ublk_ctrl_start_dev, ublk_dev_param_basic_apply).
- Commit
0aa73170eba5- go-ublk
- Advertised only when the server honors
UBLK_IO_F_FUA.
|
supported |
UBLK_PARAM_TYPE_BASICParameter types |
1<<0 |
6.0 |
struct ublk_param_basic: block sizes, max_sectors, capacity (mandatory).
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Commit
0aa73170eba5- go-ublk
- Always sent.
|
supported |
UBLK_PARAM_TYPE_DISCARDParameter types |
1<<1 |
6.0 |
struct ublk_param_discard: discard and write-zeroes limits.
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Commit
0aa73170eba5- go-ublk
- Sent when the backend implements Discard/WriteZeroes.
|
supported |
UBLK_PARAM_TYPE_DEVTParameter types |
1<<2 |
6.3 |
struct ublk_param_devt: char/block device numbers (read-only, GET_PARAMS only).
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Commit
abb864d38085- go-ublk
- Decoded from GET_PARAMS.
|
supported |
UBLK_PARAM_TYPE_ZONEDParameter types |
1<<3 |
6.6 |
struct ublk_param_zoned: zone limits (needs UBLK_F_ZONED).
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Requires
UBLK_F_ZONED- Commit
29802d7ca33b- go-ublk
- Sent with
EnableZoned.
|
supported |
UBLK_PARAM_TYPE_DMA_ALIGNParameter types |
1<<4 |
6.15 |
struct ublk_param_dma_align: DMA alignment mask.
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Commit
e84025d2a9cb- go-ublk
DeviceParams.DMAAlignment.
|
supported |
UBLK_PARAM_TYPE_SEGMENTParameter types |
1<<5 |
6.15 |
struct ublk_param_segment: segment boundary/size/count limits.
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Commit
ebf695f12936- go-ublk
DeviceParams.SegmentBoundaryMask/MaxSegmentSize/MaxSegments.
|
supported |
UBLK_PARAM_TYPE_INTEGRITYParameter types |
1<<6 |
7.0 |
struct ublk_param_integrity: metadata/PI format (needs UBLK_F_INTEGRITY).
DetailsBit in ublk_params.types. SET_PARAMS silently drops types the kernel does not know (types &= UBLK_PARAM_TYPE_ALL). See the struct entry for validation.
- Requires
UBLK_F_INTEGRITY- Commit
98bf2256855e- go-ublk
- Sent with
DeviceParams.Integrity.
|
supported |
struct ublksrv_ctrl_cmdStructures |
sizeof=32 |
6.0 |
Control command payload, placed in the SQE128 command area of a /dev/ublk-control URING_CMD.
DetailsRead with READ_ONCE at offset 48 of a 128-byte SQE (io_uring_sqe128_cmd); the control ring must be created with IORING_SETUP_SQE128 (EINVAL otherwise, checked first since v7.0-rc1 da7e4b75e50c).
- Commit
71f28f3136af- go-ublk
uapi.UblksrvCtrlCmd (size-checked).
|
supported |
ublksrv_ctrl_cmd.dev_idStructure fields |
offset=0 size=4 __u32 |
6.0 |
Target device id (U32_MAX for ADD_DEV auto-assign; ignored by GET_FEATURES).
Details
- Commit
71f28f3136af- go-ublk
UblksrvCtrlCmd.DevID.
|
supported |
ublksrv_ctrl_cmd.queue_idStructure fields |
offset=4 size=2 __u16 |
6.0 |
Must be 0xffff for ADD_DEV; otherwise unused (queue commands use data[0]).
Details
- Commit
71f28f3136af- go-ublk
QueueID.
|
supported |
ublksrv_ctrl_cmd.lenStructure fields |
offset=6 size=2 __u16 |
6.0 |
Length of the buffer at addr (including the path prefix for unprivileged devices).
Details
- Commit
71f28f3136af- go-ublk
Len.
|
supported |
ublksrv_ctrl_cmd.addrStructure fields |
offset=8 size=8 __u64 |
6.0 |
Userspace buffer (input or output, command specific).
Details
- Commit
71f28f3136af- go-ublk
Addr (off-heap buffers).
|
supported |
ublksrv_ctrl_cmd.dataStructure fields |
offset=16 size=8 __u64[1] |
6.0 |
Inline argument (pid, queue id, size, timeout, buffer index).
Details
- Notes
- Was
__u64 data[2] (16 bytes) in v6.0–v6.2; split into data[1] + dev_path_len/pad/reserved in v6.3 (4093cb5a0634). Struct size unchanged. - Commit
71f28f3136af- go-ublk
Data.
|
supported |
ublksrv_ctrl_cmd.dev_path_lenStructure fields |
offset=24 size=2 __u16 |
6.3 |
Length of the NUL-terminated /dev/ublkcN path prefixed at addr (unprivileged devices, GET_DEV_INFO2).
Details
- Commit
4093cb5a0634- go-ublk
DevPathLen.
|
supported |
ublksrv_ctrl_cmd.padStructure fields |
offset=26 size=2 __u16 |
6.3 |
Padding.
Details
- Commit
4093cb5a0634- go-ublk
Pad.
|
supported |
ublksrv_ctrl_cmd.reservedStructure fields |
offset=28 size=4 __u32 |
6.3 |
Reserved (not read by the kernel).
Details
- Commit
4093cb5a0634- go-ublk
Reserved.
|
supported |
struct ublksrv_ctrl_dev_infoStructures |
sizeof=64 |
6.0 |
Device description exchanged by ADD_DEV and returned by GET_DEV_INFO(2).
Details64 bytes in every version (fields were renamed, never resized).
- Commit
71f28f3136af- go-ublk
uapi.UblksrvCtrlDevInfo.
|
supported |
ublksrv_ctrl_dev_info.nr_hw_queuesStructure fields |
offset=0 size=2 __u16 |
6.0 |
Queues requested (1..4096); clamped to nr_cpu_ids.
Details
- Commit
71f28f3136af- go-ublk
NrHwQueues.
|
supported |
ublksrv_ctrl_dev_info.queue_depthStructure fields |
offset=2 size=2 __u16 |
6.0 |
Tags per queue (1..4096).
Details
- Commit
71f28f3136af- go-ublk
QueueDepth.
|
supported |
ublksrv_ctrl_dev_info.stateStructure fields |
offset=4 size=2 __u16 |
6.0 |
UBLK_S_DEV_* (kernel-owned; reset to DEAD at ADD_DEV since e65848e4ce35).
Details
- Commit
71f28f3136af- go-ublk
State.
|
supported |
ublksrv_ctrl_dev_info.io_desc_sizeStructure fields |
offset=6 size=2 __u16 |
7.3-rc1 |
Descriptor stride with UBLK_F_IO_DESC_SIZE (24..256); was pad0 before v7.3.
Details
- Commit
5c0958d80190- go-ublk
- Read back and used as the descriptor stride; set from DeviceParams.IODescSize.
|
supported |
ublksrv_ctrl_dev_info.max_io_buf_bytesStructure fields |
offset=8 size=4 __u32 |
6.0 |
Largest data request; rounded down to PAGE_SIZE; bounds max_sectors.
Details
- Commit
71f28f3136af- go-ublk
MaxIOBufBytes.
|
supported |
ublksrv_ctrl_dev_info.dev_idStructure fields |
offset=12 size=4 __u32 |
6.0 |
Assigned device id.
Details
- Commit
71f28f3136af- go-ublk
DevID.
|
supported |
ublksrv_ctrl_dev_info.ublksrv_pidStructure fields |
offset=16 size=4 __s32 |
6.0 |
Server pid (set by START_DEV/END_USER_RECOVERY; -1 when none; namespace-translated on read since v6.19-rc7).
Details
- Commit
71f28f3136af- go-ublk
UblksrvPID.
|
supported |
ublksrv_ctrl_dev_info.pad1Structure fields |
offset=20 size=4 __u32 |
6.0 |
Padding.
Details
- Commit
71f28f3136af- go-ublk
Pad1.
|
supported |
ublksrv_ctrl_dev_info.flagsStructure fields |
offset=24 size=8 __u64 |
6.0 |
UBLK_F_* requested / negotiated.
Details
- Commit
71f28f3136af- go-ublk
Flags.
|
supported |
ublksrv_ctrl_dev_info.ublksrv_flagsStructure fields |
offset=32 size=8 __u64 |
6.0 |
Opaque to the kernel; stored at ADD_DEV and returned verbatim.
Details
- Commit
71f28f3136af- go-ublk
UblksrvFlags (public DeviceParams.Tag, used by FindDevices).
|
supported |
ublksrv_ctrl_dev_info.owner_uidStructure fields |
offset=40 size=4 __u32 |
6.3 |
Creator’s uid (kernel-set).
Details
- Notes
- Was the low half of
__u64 reserved0 in v6.0–v6.2. - Commit
4093cb5a0634- go-ublk
OwnerUID.
|
supported |
ublksrv_ctrl_dev_info.owner_gidStructure fields |
offset=44 size=4 __u32 |
6.3 |
Creator’s gid (kernel-set).
Details
- Commit
4093cb5a0634- go-ublk
OwnerGID.
|
supported |
ublksrv_ctrl_dev_info.reserved1Structure fields |
offset=48 size=8 __u64 |
6.0 |
Reserved.
Details
- Commit
71f28f3136af- go-ublk
Reserved1.
|
supported |
ublksrv_ctrl_dev_info.reserved2Structure fields |
offset=56 size=8 __u64 |
6.0 |
Reserved.
Details
- Commit
71f28f3136af- go-ublk
Reserved2.
|
supported |
struct ublksrv_io_descStructures |
sizeof=24 |
6.0 |
Per-tag request descriptor in the read-only mmapped command buffer of /dev/ublkcN.
DetailsQueue q’s array is mapped at offset q * round_up(UBLK_MAX_QUEUE_DEPTH * io_desc_size, PAGE_SIZE) with length exactly round_up(queue_depth * io_desc_size, PAGE_SIZE) (ublk_ch_mmap; EINVAL otherwise, EPERM for a writable mapping, and since v7.3-rc2 VM_MAYWRITE is cleared so mprotect cannot make it writable). Before v6.13 (d369735e02ef, 6.1.120/6.6.64/6.12.2) the queue stride was not page-rounded, which broke multi-queue on 64K-page kernels. Valid to read after the tag’s CQE returns OK; written by the kernel on the daemon task (v7.3).
- Commit
71f28f3136af- go-ublk
uapi.UblksrvIODesc; read with atomic loads.
|
supported |
ublksrv_io_desc.op_flagsStructure fields |
offset=0 size=4 __u32 |
6.0 |
Bits 0-7 UBLK_IO_OP_, bits 8-31 UBLK_IO_F_.
Details
- Commit
71f28f3136af- go-ublk
OpFlags.
|
supported |
ublksrv_io_desc.nr_sectorsStructure fields |
offset=4 size=4 __u32 |
6.0 |
Length in 512-byte sectors (union nr_zones for REPORT_ZONES since v6.6).
Details
- Commit
71f28f3136af- go-ublk
NrSectors.
|
supported |
ublksrv_io_desc.start_sectorStructure fields |
offset=8 size=8 __u64 |
6.0 |
Offset in 512-byte sectors.
Details
- Commit
71f28f3136af- go-ublk
StartSector.
|
supported |
ublksrv_io_desc.addrStructure fields |
offset=16 size=8 __u64 |
6.0 |
Server buffer address for this request (copy mode), or the SHMEM_ZC encoding.
Details
- Commit
71f28f3136af- go-ublk
Addr.
|
supported |
struct ublksrv_io_cmdStructures |
sizeof=16 |
6.0 |
Per-tag I/O command payload (FETCH/COMMIT/NEED_GET_DATA/REGISTER/UNREGISTER).
DetailsFits a normal 64-byte SQE command area (SQE128 not required since v6.3).
- Commit
71f28f3136af- go-ublk
uapi.UblksrvIOCmd.
|
supported |
ublksrv_io_cmd.q_idStructure fields |
offset=0 size=2 __u16 |
6.0 |
Queue id.
Details
- Commit
71f28f3136af- go-ublk
QID.
|
supported |
ublksrv_io_cmd.tagStructure fields |
offset=2 size=2 __u16 |
6.0 |
Tag (request index in the queue).
Details
- Commit
71f28f3136af- go-ublk
Tag.
|
supported |
ublksrv_io_cmd.resultStructure fields |
offset=4 size=4 __s32 |
6.0 |
COMMIT only: bytes or negative errno.
Details
- Commit
71f28f3136af- go-ublk
Result.
|
supported |
ublksrv_io_cmd.addrStructure fields |
offset=8 size=8 __u64 |
6.0 |
Buffer address (copy mode), buffer-table index (REGISTER/UNREGISTER), or zone_append_lba (union since v6.6).
Details
- Commit
71f28f3136af- go-ublk
Addr / SetZoneAppendLBA.
|
supported |
struct ublk_auto_buf_regStructures |
sizeof=8 |
6.16 |
AUTO_BUF_REG registration request, packed into sqe->addr of FETCH/COMMIT.
DetailsPacking: bits 0-15 index, 16-23 flags, 24-31 reserved0, 32-63 reserved1 (ublk_auto_buf_reg_to_sqe_addr). Reserved fields must be zero and flags within UBLK_AUTO_BUF_REG_F_MASK (EINVAL, validated before the uring_cmd is taken since v7.3-rc1 ca5a01eee34c).
- Commit
99c1e4eb6a3f- go-ublk
- Used by the zero-copy engine (
SQEAddr).
|
supported |
ublk_auto_buf_reg.indexStructure fields |
offset=0 size=2 __u16 |
6.16 |
Buffer-table slot for the request buffer.
Details
- Commit
99c1e4eb6a3f- go-ublk
UblkAutoBufReg.Index.
|
supported |
ublk_auto_buf_reg.flagsStructure fields |
offset=2 size=1 __u8 |
6.16 |
UBLK_AUTO_BUF_REG_FALLBACK.
Details
- Commit
99c1e4eb6a3f- go-ublk
Flags.
|
supported |
ublk_auto_buf_reg.reserved0Structure fields |
offset=3 size=1 __u8 |
6.16 |
Must be 0.
Details
- Commit
99c1e4eb6a3f- go-ublk
Reserved0.
|
supported |
ublk_auto_buf_reg.reserved1Structure fields |
offset=4 size=4 __u32 |
6.16 |
Must be 0 (future: external io_uring fd).
Details
- Commit
99c1e4eb6a3f- go-ublk
Reserved1.
|
supported |
struct ublk_batch_ioStructures |
sizeof=16 |
7.0 |
BATCH_IO command header in the SQE command area; elements live at sqe->addr.
Detailsnr_elem * elem_bytes bytes of elements; see UBLK_U_IO_PREP_IO_CMDS.
- Commit
e86f89ab24f5- go-ublk
- Modeled only. Used by batch I/O.
|
supported |
ublk_batch_io.q_idStructure fields |
offset=0 size=2 __u16 |
7.0 |
Queue id.
Details
- Commit
e86f89ab24f5- go-ublk
UblkBatchIO.QID. Used by batch I/O.
|
supported |
ublk_batch_io.flagsStructure fields |
offset=2 size=2 __u16 |
7.0 |
UBLK_BATCH_F_*.
Details
- Commit
e86f89ab24f5- go-ublk
Flags. Used by batch I/O.
|
supported |
ublk_batch_io.nr_elemStructure fields |
offset=4 size=2 __u16 |
7.0 |
Element count (<= queue_depth).
Details
- Commit
e86f89ab24f5- go-ublk
NrElem. Used by batch I/O.
|
supported |
ublk_batch_io.elem_bytesStructure fields |
offset=6 size=1 __u8 |
7.0 |
8/16/24 (2 for FETCH_IO_CMDS).
Details
- Commit
e86f89ab24f5- go-ublk
ElemBytes. Used by batch I/O.
|
supported |
ublk_batch_io.reservedStructure fields |
offset=7 size=1 __u8 |
7.0 |
Reserved.
Details
- Commit
e86f89ab24f5- go-ublk
Reserved. Used by batch I/O.
|
supported |
ublk_batch_io.reserved2Structure fields |
offset=8 size=8 __u64 |
7.0 |
Reserved.
Details
- Commit
e86f89ab24f5- go-ublk
Reserved2. Used by batch I/O.
|
supported |
struct ublk_param_basicStructures |
sizeof=32 |
6.0 |
UBLK_PARAM_TYPE_BASIC limits.
DetailsAll sector counts are 512-byte sectors regardless of logical block size.
- Commit
0aa73170eba5- go-ublk
uapi.UblkParamBasic.
|
supported |
ublk_param_basic.attrsStructure fields |
offset=0 size=4 __u32 |
6.0 |
UBLK_ATTR_*.
Details
- Commit
0aa73170eba5- go-ublk
Attrs.
|
supported |
ublk_param_basic.logical_bs_shiftStructure fields |
offset=4 size=1 __u8 |
6.0 |
log2 logical block size, 9..PAGE_SHIFT.
Details
- Commit
0aa73170eba5- go-ublk
LogicalBSShift.
|
supported |
ublk_param_basic.physical_bs_shiftStructure fields |
offset=5 size=1 __u8 |
6.0 |
log2 physical block size, >= logical, <= 28 (v7.1+).
Details
- Commit
0aa73170eba5- go-ublk
PhysicalBSShift (DeviceParams.PhysicalBlockSize).
|
supported |
ublk_param_basic.io_opt_shiftStructure fields |
offset=6 size=1 __u8 |
6.0 |
log2 optimal I/O size, <= 28 (v7.1+).
Details
- Commit
0aa73170eba5- go-ublk
IOOptShift (IOOptSize).
|
supported |
ublk_param_basic.io_min_shiftStructure fields |
offset=7 size=1 __u8 |
6.0 |
log2 minimum I/O size, <= 28 (v7.1+).
Details
- Commit
0aa73170eba5- go-ublk
IOMinShift (IOMinSize).
|
supported |
ublk_param_basic.max_sectorsStructure fields |
offset=8 size=4 __u32 |
6.0 |
Max request size in sectors; <= max_io_buf_bytes»9 and >= PAGE_SIZE»9 (v7.1+).
Details
- Commit
0aa73170eba5- go-ublk
MaxSectors.
|
supported |
ublk_param_basic.chunk_sectorsStructure fields |
offset=12 size=4 __u32 |
6.0 |
Chunk / zone size in sectors (power of two when zoned).
Details
- Commit
0aa73170eba5- go-ublk
ChunkSectors.
|
supported |
ublk_param_basic.dev_sectorsStructure fields |
offset=16 size=8 __u64 |
6.0 |
Capacity in sectors.
Details
- Commit
0aa73170eba5- go-ublk
DevSectors.
|
supported |
ublk_param_basic.virt_boundary_maskStructure fields |
offset=24 size=8 __u64 |
6.0 |
Virtual boundary (SG gap) mask.
Details
- Commit
0aa73170eba5- go-ublk
VirtBoundaryMask.
|
supported |
struct ublk_param_discardStructures |
sizeof=20 |
6.0 |
UBLK_PARAM_TYPE_DISCARD limits.
DetailsValidated: max_discard_segments == 1 when max_discard_sectors != 0; discard_granularity != 0.
- Commit
0aa73170eba5- go-ublk
uapi.UblkParamDiscard.
|
supported |
ublk_param_discard.discard_alignmentStructure fields |
offset=0 size=4 __u32 |
6.0 |
Discard alignment offset (bytes).
Details
- Commit
0aa73170eba5- go-ublk
DiscardAlignment.
|
supported |
ublk_param_discard.discard_granularityStructure fields |
offset=4 size=4 __u32 |
6.0 |
Granularity (bytes), must be non-zero.
Details
- Commit
0aa73170eba5- go-ublk
DiscardGranularity.
|
supported |
ublk_param_discard.max_discard_sectorsStructure fields |
offset=8 size=4 __u32 |
6.0 |
Max discard size; 0 disables DISCARD.
Details
- Commit
0aa73170eba5- go-ublk
MaxDiscardSectors.
|
supported |
ublk_param_discard.max_write_zeroes_sectorsStructure fields |
offset=12 size=4 __u32 |
6.0 |
Max write-zeroes size; 0 disables WRITE_ZEROES.
Details
- Commit
0aa73170eba5- go-ublk
MaxWriteZeroesSectors.
|
supported |
ublk_param_discard.max_discard_segmentsStructure fields |
offset=16 size=2 __u16 |
6.0 |
Must be 1.
Details
- Commit
0aa73170eba5- go-ublk
MaxDiscardSegments.
|
supported |
ublk_param_discard.reserved0Structure fields |
offset=18 size=2 __u16 |
6.0 |
Reserved.
Details
- Commit
0aa73170eba5- go-ublk
Reserved0.
|
supported |
struct ublk_param_devtStructures |
sizeof=16 |
6.3 |
UBLK_PARAM_TYPE_DEVT: device numbers, filled by GET_PARAMS (setting it is EINVAL).
Details
- Commit
abb864d38085- go-ublk
uapi.UblkParamDevt.
|
supported |
ublk_param_devt.char_majorStructure fields |
offset=0 size=4 __u32 |
6.3 |
Major of /dev/ublkcN.
Details
- Commit
abb864d38085- go-ublk
CharMajor.
|
supported |
ublk_param_devt.char_minorStructure fields |
offset=4 size=4 __u32 |
6.3 |
Minor of /dev/ublkcN (= dev id).
Details
- Commit
abb864d38085- go-ublk
CharMinor.
|
supported |
ublk_param_devt.disk_majorStructure fields |
offset=8 size=4 __u32 |
6.3 |
Major of /dev/ublkbN (0 before START_DEV).
Details
- Commit
abb864d38085- go-ublk
DiskMajor.
|
supported |
ublk_param_devt.disk_minorStructure fields |
offset=12 size=4 __u32 |
6.3 |
Minor of /dev/ublkbN (0 before START_DEV).
Details
- Commit
abb864d38085- go-ublk
DiskMinor.
|
supported |
struct ublk_param_zonedStructures |
sizeof=32 |
6.6 |
UBLK_PARAM_TYPE_ZONED limits.
DetailsValidated (ublk_dev_param_zoned_validate): device must be ZONED; max_zone_append_sectors != 0; open/active <= nr_zones (= dev_sectors / chunk_sectors).
- Commit
29802d7ca33b- go-ublk
- Set from
ZonedParams.
|
supported |
ublk_param_zoned.max_open_zonesStructure fields |
offset=0 size=4 __u32 |
6.6 |
Max open zones (0 = no limit).
Details
- Commit
29802d7ca33b- go-ublk
MaxOpenZones.
|
supported |
ublk_param_zoned.max_active_zonesStructure fields |
offset=4 size=4 __u32 |
6.6 |
Max active zones (0 = no limit).
Details
- Commit
29802d7ca33b- go-ublk
MaxActiveZones.
|
supported |
ublk_param_zoned.max_zone_append_sectorsStructure fields |
offset=8 size=4 __u32 |
6.6 |
Max zone-append size; must be non-zero.
Details
- Commit
29802d7ca33b- go-ublk
MaxZoneAppendSectors.
|
supported |
ublk_param_zoned.reservedStructure fields |
offset=12 size=20 __u8[20] |
6.6 |
Reserved.
Details
- Commit
29802d7ca33b- go-ublk
Reserved.
|
supported |
struct ublk_param_dma_alignStructures |
sizeof=8 |
6.15 |
UBLK_PARAM_TYPE_DMA_ALIGN.
Detailsalignment is a mask: alignment+1 must be a power of two and alignment < PAGE_SIZE. Default without it: 3 (since v6.10, 928b607d1a09).
- Commit
e84025d2a9cb- go-ublk
uapi.UblkParamDMAAlign; DeviceParams.DMAAlignment.
|
supported |
ublk_param_dma_align.alignmentStructure fields |
offset=0 size=4 __u32 |
6.15 |
DMA alignment mask (e.g. 4095 for page alignment).
Details
- Commit
e84025d2a9cb- go-ublk
UblkParamDMAAlign.Alignment.
|
supported |
ublk_param_dma_align.padStructure fields |
offset=4 size=4 __u8[4] |
6.15 |
Padding.
Details
- Commit
e84025d2a9cb- go-ublk
Pad.
|
supported |
struct ublk_param_segmentStructures |
sizeof=16 |
6.15 |
UBLK_PARAM_TYPE_SEGMENT.
Detailsseg_boundary_mask+1 power of two and >= 4096; max_segment_size >= 4096; a zero max_segments is undefined (header comment). Defaults without it: USHRT_MAX segments of UINT_MAX bytes (since v6.9-rc7, eaf4a9b19b99).
- Commit
ebf695f12936- go-ublk
uapi.UblkParamSegment.
|
supported |
ublk_param_segment.seg_boundary_maskStructure fields |
offset=0 size=8 __u64 |
6.15 |
Segment boundary mask.
Details
- Commit
ebf695f12936- go-ublk
SegBoundaryMask.
|
supported |
ublk_param_segment.max_segment_sizeStructure fields |
offset=8 size=4 __u32 |
6.15 |
Max segment size (>= 4096).
Details
- Commit
ebf695f12936- go-ublk
MaxSegmentSize.
|
supported |
ublk_param_segment.max_segmentsStructure fields |
offset=12 size=2 __u16 |
6.15 |
Max segments per request.
Details
- Commit
ebf695f12936- go-ublk
MaxSegments.
|
supported |
ublk_param_segment.padStructure fields |
offset=14 size=2 __u8[2] |
6.15 |
Padding.
Details
- Commit
ebf695f12936- go-ublk
Pad.
|
supported |
struct ublk_param_integrityStructures |
sizeof=16 |
7.0 |
UBLK_PARAM_TYPE_INTEGRITY: metadata / protection-information format.
DetailsValidated: UBLK_F_INTEGRITY set; flags only LBMD_PI_CAP_INTEGRITY|LBMD_PI_CAP_REFTAG; csum_type one of LBMD_PI_CSUM_NONE/IP/CRC16_T10DIF/CRC64_NVME (tuple 0/8/8/16 bytes); metadata_size != 0; REFTAG needs a checksum; pi_offset + tuple <= metadata_size; 9 <= interval_exp <= logical_bs_shift. Applied as queue_limits.integrity at START_DEV.
- Commit
98bf2256855e- go-ublk
- Set from
IntegrityParams.
|
supported |
ublk_param_integrity.flagsStructure fields |
offset=0 size=4 __u32 |
7.0 |
LBMD_PI_CAP_* (fs.h, v6.17+).
Details
- Commit
98bf2256855e- go-ublk
Flags.
|
supported |
ublk_param_integrity.max_integrity_segmentsStructure fields |
offset=4 size=2 __u16 |
7.0 |
0 = no limit (USHRT_MAX).
Details
- Commit
98bf2256855e- go-ublk
MaxIntegritySegments.
|
supported |
ublk_param_integrity.interval_expStructure fields |
offset=6 size=1 __u8 |
7.0 |
log2 protection interval.
Details
- Commit
98bf2256855e- go-ublk
IntervalExp.
|
supported |
ublk_param_integrity.metadata_sizeStructure fields |
offset=7 size=1 __u8 |
7.0 |
Metadata bytes per interval (non-zero).
Details
- Commit
98bf2256855e- go-ublk
MetadataSize.
|
supported |
ublk_param_integrity.pi_offsetStructure fields |
offset=8 size=1 __u8 |
7.0 |
Offset of the PI tuple in the metadata.
Details
- Commit
98bf2256855e- go-ublk
PIOffset.
|
supported |
ublk_param_integrity.csum_typeStructure fields |
offset=9 size=1 __u8 |
7.0 |
LBMD_PI_CSUM_*.
Details
- Commit
98bf2256855e- go-ublk
CsumType.
|
supported |
ublk_param_integrity.tag_sizeStructure fields |
offset=10 size=1 __u8 |
7.0 |
Application tag size.
Details
- Commit
98bf2256855e- go-ublk
TagSize.
|
supported |
ublk_param_integrity.padStructure fields |
offset=11 size=5 __u8[5] |
7.0 |
Padding.
Details
- Commit
98bf2256855e- go-ublk
Pad.
|
supported |
struct ublk_paramsStructures |
sizeof=152 |
6.0 |
SET_PARAMS/GET_PARAMS container: len, types, then every parameter block at a fixed offset.
Detailssizeof by version (8-byte aligned): 64 (v6.0–v6.2: basic, discard), 80 (v6.3: +devt), 112 (v6.6: +zoned), 136 (v6.15: +dma, seg; seg is 8-byte aligned so 4 bytes of padding precede it), 152 (v7.0: +integrity). The kernel copies min(len, sizeof) both ways, so mismatched userspace/kernel sizes interoperate.
- Commit
0aa73170eba5- go-ublk
uapi.UblkParams (marshal handles shorter kernel replies).
|
supported |
ublk_params.lenStructure fields |
offset=0 size=4 __u32 |
6.0 |
Byte length of the struct as sent/received; set by the caller for both SET and GET.
Details
- Commit
0aa73170eba5- go-ublk
Len.
|
supported |
ublk_params.typesStructure fields |
offset=4 size=4 __u32 |
6.0 |
UBLK_PARAM_TYPE_* present.
Details
- Commit
0aa73170eba5- go-ublk
Types.
|
supported |
ublk_params.basicStructure fields |
offset=8 size=32 struct ublk_param_basic |
6.0 |
BASIC block.
Details
- Commit
0aa73170eba5- go-ublk
Basic.
|
supported |
ublk_params.discardStructure fields |
offset=40 size=20 struct ublk_param_discard |
6.0 |
DISCARD block.
Details
- Commit
0aa73170eba5- go-ublk
Discard.
|
supported |
ublk_params.devtStructure fields |
offset=60 size=16 struct ublk_param_devt |
6.3 |
DEVT block.
Details
- Commit
abb864d38085- go-ublk
Devt.
|
supported |
ublk_params.zonedStructure fields |
offset=76 size=32 struct ublk_param_zoned |
6.6 |
ZONED block.
Details
- Commit
29802d7ca33b- go-ublk
Zoned.
|
supported |
ublk_params.dmaStructure fields |
offset=108 size=8 struct ublk_param_dma_align |
6.15 |
DMA_ALIGN block.
Details
- Commit
e84025d2a9cb- go-ublk
DMA.
|
supported |
ublk_params.segStructure fields |
offset=120 size=16 struct ublk_param_segment |
6.15 |
SEGMENT block.
Details
- Commit
ebf695f12936- go-ublk
Seg.
|
supported |
ublk_params.integrityStructure fields |
offset=136 size=16 struct ublk_param_integrity |
7.0 |
INTEGRITY block.
Details
- Commit
98bf2256855e- go-ublk
Integrity.
|
supported |
struct ublk_shmem_buf_regStructures |
sizeof=24 |
7.1 |
REG_BUF argument (pointed to by ctrl_cmd.addr).
Detailslen was widened from __u32 to __u64 within the v7.1 merge window (23b3b6f0b584), so every release has the 24-byte form.
- Commit
2fb0ded237bb- go-ublk
- Modeled; used by the internal RegBuf. Used by shared-memory zero copy.
|
supported |
ublk_shmem_buf_reg.addrStructure fields |
offset=0 size=8 __u64 |
7.1 |
Page-aligned VA of the shared mapping.
Details
- Commit
2fb0ded237bb- go-ublk
UblkShmemBufReg.Addr. Used by shared-memory zero copy.
|
supported |
ublk_shmem_buf_reg.lenStructure fields |
offset=8 size=8 __u64 |
7.1 |
Page-aligned length, 1 byte..4 GiB.
Details
- Commit
2fb0ded237bb- go-ublk
Len. Used by shared-memory zero copy.
|
supported |
ublk_shmem_buf_reg.flagsStructure fields |
offset=16 size=4 __u32 |
7.1 |
UBLK_SHMEM_BUF_READ_ONLY.
Details
- Commit
2fb0ded237bb- go-ublk
Flags. Used by shared-memory zero copy.
|
supported |
ublk_shmem_buf_reg.reservedStructure fields |
offset=20 size=4 __u32 |
7.1 |
Must be 0.
Details
- Commit
2fb0ded237bb- go-ublk
Reserved. Used by shared-memory zero copy.
|
supported |
UBLK_FEATURES_LENConstants |
8 |
6.5 |
Required len for GET_FEATURES.
Details
- Commit
b5bbc52fd012- go-ublk
uapi.UBLK_FEATURES_LEN.
|
supported |
UBLK_IO_RES_OKConstants |
0 |
6.0 |
Fetch CQE result: a request is ready in the descriptor.
Details
- Commit
71f28f3136af- go-ublk
- Engine dispatch.
|
supported |
UBLK_IO_RES_NEED_GET_DATAConstants |
1 |
6.0 |
Fetch CQE result: WRITE needs UBLK_U_IO_NEED_GET_DATA first.
Details
- Commit
4e18403d9485- go-ublk
- Engine issues NEED_GET_DATA.
|
supported |
UBLK_IO_RES_ABORTConstants |
-ENODEV (-19) |
6.0 |
Fetch CQE result: tag cancelled (stop, quiesce, exit); do not re-fetch.
Details
- Notes
- The header: “only ABORT means that no re-fetch”. Since v7.1-rc3 (845db023a8ae) a command issued from fallback task work can also complete with -ECANCELED.
- Commit
71f28f3136af- go-ublk
- Engine retires the tag (also on -ECANCELED).
|
supported |
UBLKSRV_CMD_BUF_OFFSETConstants |
0 |
6.0 |
mmap offset of queue 0’s descriptor array.
Details
- Commit
71f28f3136af- go-ublk
uapi.CmdBufMmapOffset.
|
supported |
UBLKSRV_IO_BUF_OFFSETConstants |
0x80000000 |
6.0 |
Base file offset for USER_COPY pread/pwrite.
Details
- Notes
- Defined in v6.0 but unused until USER_COPY (v6.5).
- Commit
71f28f3136af- go-ublk
uapi.UserCopyOffset.
|
supported |
UBLK_MAX_QUEUE_DEPTHConstants |
4096 |
6.0 |
Max tags per queue; also fixes the descriptor mmap stride.
Details
- Commit
71f28f3136af- go-ublk
- Validated.
|
supported |
UBLK_IO_BUF_OFFConstants |
0 |
6.5 |
Bit offset of the byte offset in a user-copy position.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_IO_BUF_BITSConstants |
25 |
6.5 |
Byte-offset width: 32 MiB per request in user copy.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_IO_BUF_BITS_MASKConstants |
(1ULL<<25)-1 |
6.5 |
Byte-offset mask.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_TAG_OFFConstants |
25 |
6.5 |
Bit offset of the tag in a user-copy position.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_TAG_BITSConstants |
16 |
6.5 |
Tag width.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_TAG_BITS_MASKConstants |
0xffff |
6.5 |
Tag mask.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_QID_OFFConstants |
41 |
6.5 |
Bit offset of the queue id in a user-copy position.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_QID_BITSConstants |
12 |
6.5 |
Queue-id width.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_QID_BITS_MASKConstants |
0xfff |
6.5 |
Queue-id mask.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_MAX_NR_QUEUESConstants |
4096 |
6.5 |
Max hardware queues (ADD_DEV enforces it since v6.16).
Details
- Commit
62fe99cef94a- go-ublk
- Validated.
|
supported |
UBLKSRV_IO_BUF_TOTAL_BITSConstants |
53 |
6.5 |
Total user-copy position bits.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLKSRV_IO_BUF_TOTAL_SIZEConstants |
1ULL<<53 |
6.5 |
Size of the user-copy position space.
Details
- Commit
62fe99cef94a- go-ublk
- Modeled.
|
supported |
UBLK_INTEGRITY_FLAG_OFFConstants |
62 |
7.0 |
Bit selecting the integrity buffer in a user-copy position.
Details
- Commit
be82a89066d5- go-ublk
- Used by the integrity user-copy path.
|
supported |
UBLKSRV_IO_INTEGRITY_FLAGConstants |
1ULL<<62 |
7.0 |
OR into the pread/pwrite offset to copy the integrity buffer.
Details
- Notes
- EINVAL without UBLK_F_INTEGRITY.
- Commit
be82a89066d5- go-ublk
- Integrity pread/pwrite position (
uapi.UserCopyIntegrityOffset).
|
supported |
UBLK_SHMEM_BUF_READ_ONLYConstants |
1U<<0 |
7.1 |
REG_BUF flag: pin without FOLL_WRITE (works with write-sealed memfds); buffer matches only WRITEs.
Details
- Commit
2fb0ded237bb- go-ublk
- Modeled. Used by shared-memory zero copy.
|
supported |
UBLK_AUTO_BUF_REG_FALLBACKConstants |
1<<0 |
6.16 |
auto_buf_reg flag: on registration failure deliver the request with UBLK_IO_F_NEED_REG_BUF instead of failing it.
Details
- Commit
53f427e7944b- go-ublk
- Always set by the zero-copy engine.
|
supported |
UBLK_AUTO_BUF_REG_F_MASKConstants |
UBLK_AUTO_BUF_REG_FALLBACK |
6.16 |
All valid auto_buf_reg flags.
Details
- Commit
53f427e7944b- go-ublk
- Always set by the zero-copy engine.
|
supported |
UBLK_BATCH_F_HAS_ZONE_LBAConstants |
1<<0 |
7.0 |
Batch elements carry a __u64 zone_lba (needs ZONED).
Details
- Commit
e86f89ab24f5- go-ublk
- Set for batch I/O on zoned devices.
|
supported |
UBLK_BATCH_F_HAS_BUF_ADDRConstants |
1<<1 |
7.0 |
Batch elements carry a __u64 buf_addr (copy mode only).
Details
- Commit
e86f89ab24f5- go-ublk
- Set for batch I/O in copy mode.
|
supported |
UBLK_BATCH_F_AUTO_BUF_REG_FALLBACKConstants |
1<<2 |
7.0 |
Batch equivalent of UBLK_AUTO_BUF_REG_FALLBACK (excludes HAS_BUF_ADDR).
Details
- Commit
e86f89ab24f5- go-ublk
- Set for batch I/O with zero copy: elements carry buf_index = tag, with the NEED_REG_BUF fallback handled by a manual REGISTER_IO_BUF.
|
supported |
UBLK_MIN_SEGMENT_SIZEConstants |
4096 |
6.15 |
Minimum seg_boundary_mask+1 and max_segment_size.
Details
- Commit
ebf695f12936- go-ublk
- Modeled.
|
supported |
UBLK_SHMEM_ZC_OFF_MASKConstants |
0xffffffff |
7.1 |
SHMEM_ZC addr bits 0-31: byte offset.
Details
- Commit
2fb0ded237bb- go-ublk
- Modeled. Used by shared-memory zero copy.
|
supported |
UBLK_SHMEM_ZC_IDX_OFFConstants |
32 |
7.1 |
SHMEM_ZC addr: index shift.
Details
- Commit
2fb0ded237bb- go-ublk
- Modeled. Used by shared-memory zero copy.
|
supported |
UBLK_SHMEM_ZC_IDX_MASKConstants |
0xffff |
7.1 |
SHMEM_ZC addr bits 32-47: buffer index (48-63 reserved).
Details
- Commit
2fb0ded237bb- go-ublk
- Modeled. Used by shared-memory zero copy.
|
supported |
ublksrv_get_op()Constants |
static inline |
6.0 |
Header helper: op_flags & 0xff.
Details
- Commit
71f28f3136af- go-ublk
UblksrvIODesc.GetOp.
|
supported |
ublksrv_get_flags()Constants |
static inline |
6.0 |
Header helper: op_flags >> 8 (note: shifted, so compare with UBLK_IO_F_* » 8).
Details
- Commit
71f28f3136af- go-ublk
GetFlags.
|
supported |
ublk_sqe_addr_to_auto_buf_reg()Constants |
static inline |
6.16 |
Header helper: unpack sqe->addr into ublk_auto_buf_reg.
Details
- Commit
99c1e4eb6a3f- go-ublk
AutoBufRegFromSQEAddr.
|
supported |
ublk_auto_buf_reg_to_sqe_addr()Constants |
static inline |
6.16 |
Header helper: pack ublk_auto_buf_reg into sqe->addr.
Details
- Commit
99c1e4eb6a3f- go-ublk
UblkAutoBufReg.SQEAddr.
|
supported |
ublk_shmem_zc_addr()Constants |
static inline |
7.1 |
Header helper: (index << 32) | offset.
Details
- Commit
2fb0ded237bb- go-ublk
ShmemZCAddr. Used by shared-memory zero copy.
|
supported |
ublk_shmem_zc_index()Constants |
static inline |
7.1 |
Header helper: buffer index from a SHMEM_ZC addr.
Details
- Commit
2fb0ded237bb- go-ublk
ShmemZCIndex. Used by shared-memory zero copy.
|
supported |
ublk_shmem_zc_offset()Constants |
static inline |
7.1 |
Header helper: byte offset from a SHMEM_ZC addr.
Details
- Commit
2fb0ded237bb- go-ublk
ShmemZCOffset. Used by shared-memory zero copy.
|
supported |
LBMD_PI_CAP_INTEGRITYConstants |
1<<0 |
6.17 |
linux/fs.h: device verifies/generates PI (maps to BLK_INTEGRITY_DEVICE_CAPABLE).
Details
- Notes
- Defined in include/uapi/linux/fs.h, not ublk_cmd.h; referenced by ublk_param_integrity.flags (v7.0+).
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams.
|
supported |
LBMD_PI_CAP_REFTAGConstants |
1<<1 |
6.17 |
linux/fs.h: PI includes a reference tag (BLK_INTEGRITY_REF_TAG); requires a checksum type.
Details
- Notes
- fs.h constant used by ublk_param_integrity.flags.
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams (IntegrityCsum*, RefTag).
|
supported |
LBMD_PI_CSUM_NONEConstants |
0 |
6.17 |
linux/fs.h: no PI checksum (metadata only; tuple size 0).
Details
- Notes
- fs.h constant used by ublk_param_integrity.csum_type.
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams (IntegrityCsum*, RefTag).
|
supported |
LBMD_PI_CSUM_IPConstants |
1 |
6.17 |
linux/fs.h: IP checksum guard (8-byte tuple).
Details
- Notes
- fs.h constant.
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams (IntegrityCsum*, RefTag).
|
supported |
LBMD_PI_CSUM_CRC16_T10DIFConstants |
2 |
6.17 |
linux/fs.h: T10-DIF CRC16 guard (8-byte tuple).
Details
- Notes
- fs.h constant.
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams (IntegrityCsum*, RefTag).
|
supported |
LBMD_PI_CSUM_CRC64_NVMEConstants |
4 |
6.17 |
linux/fs.h: NVMe CRC64 guard (16-byte tuple).
Details
- Notes
- fs.h constant.
- Commit
9eb22f7fedfc- go-ublk
- Mapped from
IntegrityParams (IntegrityCsum*, RefTag).
|
supported |
CONFIG_BLK_DEV_UBLKConstants |
tristate (m/y/n) |
6.0 |
Kconfig: builds ublk_drv (“Userspace block driver (Experimental)”, selects IO_URING).
Details
- Notes
- Not a header element. Module name ublk_drv; no devname alias, so
modprobe ublk_drv is needed before /dev/ublk-control exists. Distro status: distro-kernels.md. - Commit
71f28f3136af- go-ublk
- Runtime requirement;
Probe explains a missing module.
|
n/a |
CONFIG_BLKDEV_UBLK_LEGACY_OPCODESConstants |
bool, default y |
6.4 |
Kconfig: keep accepting the raw (pre-6.4) opcodes.
Details
- Notes
- Not a header element. With =n,
ublk_check_cmd_op rejects any opcode whose _IOC_TYPE is not ‘u’ with EOPNOTSUPP. Ubuntu (all kernels) and AL2023 kernel6.18 build it =n. - Commit
2d786e66c966- go-ublk
- Irrelevant: go-ublk only sends ioctl-encoded opcodes.
|
n/a |
ublks_max (module parameter)Constants |
default 64 |
6.3 |
Module parameter limiting how many devices may be added.
Details
- Notes
- Not a header element. v6.3–v6.6: read-only (0444), limits all devices; v6.7 (6eba24aeb5e2): writable at runtime, 0..2^20; v6.15 (80bdfbb3545b): limits only UBLK_F_UNPRIVILEGED_DEV devices (internally
unprivileged_ublks_max). Exceeding it: ADD_DEV EACCES. Device ids are allocated lowest-free from 0 up to 2^20-1 (bounded since v6.7, 56974c07f2c7). - Commit
403ebc877832- go-ublk
- ListDevices enumerates /sys/class/ublk-char, so device IDs beyond 63 are found; the 0..63 probe is only a fallback without sysfs.
|
supported |
UBLK_MAX_UBLKS (driver)Constants |
1<<20 (UBLK_MINORS) |
6.7 |
Driver-internal: device ids must be < 2^20 (char minor space).
Details
- Notes
- Not in the UAPI header.
- Commit
56974c07f2c7
|
n/a |
UBLK_MAX_IO_DESC_SIZE (driver)Constants |
256 |
7.3-rc1 |
Driver-internal: largest io_desc_size accepted with UBLK_F_IO_DESC_SIZE.
Details
- Notes
- Not in the UAPI header.
- Commit
5c0958d80190- go-ublk
- Validated by
ctrl.ValidateFeatures.
|
supported |
UBLK_SHMEM_BUF_SIZE_MAX (driver)Constants |
1ULL<<32 |
7.1 |
Driver-internal: largest REG_BUF length (4 GiB).
Details
- Notes
- Not in the UAPI header.
- Commit
23b3b6f0b584- go-ublk
- Documented on RegBuf. Used by shared-memory zero copy.
|
supported |
UBLK_IO_F_PREFLUSH (removed)Constants |
1U<<14 |
never released |
Pre-release flag removed in the v6.0 merge window.
Details
- Notes
- Present only in the initial commit 71f28f3136af; removed before v6.0 (5f8bcc837a96). Never in a released header.
- Commit
5f8bcc837a96
|
n/a |