Menu

One row per item in the kernel’s include/uapi/linux/ublk_cmd.h. Filter by kind or by go-ublk status, or search by name. Every row has a stable anchor, so /reference/uapi/#ublk_f_user_recovery links straight to a flag. Expand Details for semantics, dependencies, the introducing commit and go-ublk notes.

Since is the first mainline release whose header defines the item. A few items were defined before the kernel implemented them (UBLK_F_SUPPORT_ZERO_COPY was reserved in 6.0 but only works from 6.15), and the ioctl-encoded UBLK_U_* commands date from 6.4 even where the legacy opcode is older; the details say so where it matters. The kernel version history tells the same story release by release.

go-ublk status: supported means the library uses or exposes the item today; partial means some of its semantics; missing means not yet; n/a means there is nothing for a server to do.

Generated from include/uapi/linux/ublk_cmd.h at Linux v7.3-rc5 on 2026-10-04. 259 items.

Kind
go-ublk
NameValueSinceSummarygo-ublk
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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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.
Details

Same 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).
Details

Inputs: 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.
Details

Same 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.
Details

Inputs: 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).
Details

Inputs: 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.
Details

Behaviour (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.
Details

Inputs: 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.
Details

Inputs: 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.
Details

SQE: 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.
Details

Accepted 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.
Details

SQE: 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.
Details

Accepted 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.
Details

Used 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.
Details

Accepted 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.
Details

SQE: {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).
Details

SQE: {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).
Details

SQE 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).
Details

Same 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.
Details

SQE: 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).
Details

Reserved 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().
Details

v6.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.
Details

For 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.
Details

When 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.
Details

ADD_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.
Details

Set 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.
Details

The 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.
Details

Requires 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.
Details

After 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).
Details

Purely 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.
Details

FETCH/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).
Details

Must 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.
Details

Capability 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.
Details

Capability 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.
Details

The 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.
Details

Requires 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.
Details

Always 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.
Details

START_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.
Details

The 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).
Details

With 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.
Details

Set 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.
Details

Entered 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.
Details

Recovery 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.
Details

Only 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.
Details

Result: 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.
Details

Result: 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.
Details

Sent 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.
Details

Sent 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.
Details

ublk_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).
Details

Sent 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.
Details

Zoned 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.
Details

Zoned 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.
Details

Zoned 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.
Details

Data 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.
Details

Zoned 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.
Details

Zoned 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.
Details

Carried 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.
Details

Set 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.
Details

Set 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.
Details

Set 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).
Details

Set 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.
Details

Only 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.
Details

Set 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).
Details

Set 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.
Details

Set 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.
Details

Set 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).
Details

Set 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).
Details

Bit 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).
Details

Bit 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.
Details

Bit 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).
Details

Bit 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).
Details

Bit 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.
Details

Bit 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).
Details

Bit 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).
Details

Bit 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.
Details

Bit 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.
Details

Bit 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).
Details

Bit 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.
Details

Read 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).
Details

64 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.
Details

Queue 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).
Details

Fits 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.
Details

Packing: 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_elem_headerStructures sizeof=8 7.0 Mandatory 8-byte head of each BATCH_IO element.
Details

Element = header [+ __u64 buf_addr if HAS_BUF_ADDR] [+ __u64 zone_lba if HAS_ZONE_LBA].

Commit
e86f89ab24f5
go-ublk
Modeled only. Used by batch I/O.
supported
ublk_elem_header.tagStructure fields offset=0 size=2 __u16 7.0 I/O tag (< queue_depth).
Details
Commit
e86f89ab24f5
go-ublk
UblkElemHeader.Tag. Used by batch I/O.
supported
ublk_elem_header.buf_indexStructure fields offset=2 size=2 __u16 7.0 AUTO_BUF_REG buffer index.
Details
Commit
e86f89ab24f5
go-ublk
BufIndex. Used by batch I/O.
supported
ublk_elem_header.resultStructure fields offset=4 size=4 __s32 7.0 Completion result (COMMIT_IO_CMDS only).
Details
Commit
e86f89ab24f5
go-ublk
Result. Used by batch I/O.
supported
struct ublk_batch_ioStructures sizeof=16 7.0 BATCH_IO command header in the SQE command area; elements live at sqe->addr.
Details

nr_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.
Details

All 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.
Details

Validated: 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.
Details

Validated (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.
Details

alignment 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.
Details

seg_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.
Details

Validated: 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.
Details

sizeof 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).
Details

len 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