sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/translations/zh_CN/block/ublkmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/zh_TW/block/ublkmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/it_IT/block/ublkmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ja_JP/block/ublkmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ko_KR/block/ublkmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/sp_SP/block/ublkmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh8/var/lib/git/docbuild/linux/Documentation/block/ublk.rsthKubhsection)}(hhh](htitle)}(h+Userspace block device driver (ublk driver)h]h+Userspace block device driver (ublk driver)}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hOverviewh]hOverview}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hXZublk is a generic framework for implementing block device logic from userspace. The motivation behind it is that moving virtual block drivers into userspace, such as loop, nbd and similar can be very helpful. It can help to implement new virtual block device such as ublk-qcow2 (there are several attempts of implementing qcow2 driver in kernel).h]hXZublk is a generic framework for implementing block device logic from userspace. The motivation behind it is that moving virtual block drivers into userspace, such as loop, nbd and similar can be very helpful. It can help to implement new virtual block device such as ublk-qcow2 (there are several attempts of implementing qcow2 driver in kernel).}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(h/Userspace block devices are attractive because:h]h/Userspace block devices are attractive because:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh bullet_list)}(hhh](h list_item)}(h/They can be written many programming languages.h]h)}(hjh]h/They can be written many programming languages.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(hThey can be installed and updated independently of the kernel.h]h)}(hjuh]h>They can be installed and updated independently of the kernel.}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjsubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(hoThey can be used to simulate block device easily with user specified parameters/setting for test/debug purpose h]h)}(hnThey can be used to simulate block device easily with user specified parameters/setting for test/debug purposeh]hnThey can be used to simulate block device easily with user specified parameters/setting for test/debug purpose}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhKhhhhubh)}(hXNublk block device (``/dev/ublkb*``) is added by ublk driver. Any IO request on the device will be forwarded to ublk userspace program. For convenience, in this document, ``ublk server`` refers to generic ublk userspace program. ``ublksrv`` [#userspace]_ is one of such implementation. It provides ``libublksrv`` [#userspace_lib]_ library for developing specific user block device conveniently, while also generic type block device is included, such as loop and null. Richard W.M. Jones wrote userspace nbd device ``nbdublk`` [#userspace_nbdublk]_ based on ``libublksrv`` [#userspace_lib]_.h](hublk block device (}(hjhhhNhNubhliteral)}(h``/dev/ublkb*``h]h /dev/ublkb*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) is added by ublk driver. Any IO request on the device will be forwarded to ublk userspace program. For convenience, in this document, }(hjhhhNhNubj)}(h``ublk server``h]h ublk server}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ refers to generic ublk userspace program. }(hjhhhNhNubj)}(h ``ublksrv``h]hublksrv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubhfootnote_reference)}(h [#userspace]_h]h1}(hjhhhNhNubah}(h]id1ah ]h"]h$]h&]autoKrefid userspacedocname block/ublkuh1jhjresolvedKubh, is one of such implementation. It provides }(hjhhhNhNubj)}(h``libublksrv``h]h libublksrv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }hjsbj)}(h[#userspace_lib]_h]h2}(hjhhhNhNubah}(h]id2ah ]h"]h$]h&]jKj userspace-libjjuh1jhjjKubh library for developing specific user block device conveniently, while also generic type block device is included, such as loop and null. Richard W.M. Jones wrote userspace nbd device }(hjhhhNhNubj)}(h ``nbdublk``h]hnbdublk}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }hjsbj)}(h[#userspace_nbdublk]_h]h3}(hj=hhhNhNubah}(h]id3ah ]h"]h$]h&]jKjuserspace-nbdublkjjuh1jhjjKubh based on }(hjhhhNhNubj)}(h``libublksrv``h]h libublksrv}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }hjsbj)}(h[#userspace_lib]_h]h2}(hjchhhNhNubah}(h]id4ah ]h"]h$]h&]jKjj&jjuh1jhjjKubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXAfter the IO is handled by userspace, the result is committed back to the driver, thus completing the request cycle. This way, any specific IO handling logic is totally done by userspace, such as loop's IO handling, NBD's IO communication, or qcow2's IO mapping.h]hX After the IO is handled by userspace, the result is committed back to the driver, thus completing the request cycle. This way, any specific IO handling logic is totally done by userspace, such as loop’s IO handling, NBD’s IO communication, or qcow2’s IO mapping.}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hhhhubh)}(h``/dev/ublkb*`` is driven by blk-mq request-based driver. Each request is assigned by one queue wide unique tag. ublk server assigns unique tag to each IO too, which is 1:1 mapped with IO of ``/dev/ublkb*``.h](j)}(h``/dev/ublkb*``h]h /dev/ublkb*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is driven by blk-mq request-based driver. Each request is assigned by one queue wide unique tag. ublk server assigns unique tag to each IO too, which is 1:1 mapped with IO of }(hjhhhNhNubj)}(h``/dev/ublkb*``h]h /dev/ublkb*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK*hhhhubh)}(hXBoth the IO request forward and IO handling result committing are done via ``io_uring`` passthrough command; that is why ublk is also one io_uring based block driver. It has been observed that using io_uring passthrough command can give better IOPS than block IO; which is why ublk is one of high performance implementation of userspace block device: not only IO request communication is done by io_uring, but also the preferred IO handling in ublk server is io_uring based approach too.h](hKBoth the IO request forward and IO handling result committing are done via }(hjhhhNhNubj)}(h ``io_uring``h]hio_uring}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX passthrough command; that is why ublk is also one io_uring based block driver. It has been observed that using io_uring passthrough command can give better IOPS than block IO; which is why ublk is one of high performance implementation of userspace block device: not only IO request communication is done by io_uring, but also the preferred IO handling in ublk server is io_uring based approach too.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK.hhhhubh)}(hXublk provides control interface to set/get ublk block device parameters. The interface is extendable and kabi compatible: basically any ublk request queue's parameter or ublk generic feature parameters can be set/get via the interface. Thus, ublk is generic userspace block device framework. For example, it is easy to setup a ublk device with specified block parameters from userspace.h]hXublk provides control interface to set/get ublk block device parameters. The interface is extendable and kabi compatible: basically any ublk request queue’s parameter or ublk generic feature parameters can be set/get via the interface. Thus, ublk is generic userspace block device framework. For example, it is easy to setup a ublk device with specified block parameters from userspace.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hhhhubeh}(h]overviewah ]h"]overviewah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Using ublkh]h Using ublk}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK>ubh)}(hFublk requires userspace ublk server to handle real block device logic.h]hFublk requires userspace ublk server to handle real block device logic.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hjhhubh)}(hHBelow is example of using ``ublksrv`` to provide ublk-based loop device.h](hBelow is example of using }(hj hhhNhNubj)}(h ``ublksrv``h]hublksrv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh# to provide ublk-based loop device.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKBhjhhubh)}(hhh](h)}(h5add a device:: ublk add -t loop -f ublk-loop.img h](h)}(hadd a device::h]h add a device:}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhj0ubh literal_block)}(h!ublk add -t loop -f ublk-loop.imgh]h!ublk add -t loop -f ublk-loop.img}hjDsbah}(h]h ]h"]h$]h&]hhuh1jBhhhKFhj0ubeh}(h]h ]h"]h$]h&]uh1hhj-hhhhhNubh)}(hformat with xfs, then use it:: mkfs.xfs /dev/ublkb0 mount /dev/ublkb0 /mnt # do anything. all IOs are handled by io_uring ... umount /mnt h](h)}(hformat with xfs, then use it::h]hformat with xfs, then use it:}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjXubjC)}(hjmkfs.xfs /dev/ublkb0 mount /dev/ublkb0 /mnt # do anything. all IOs are handled by io_uring ... umount /mnth]hjmkfs.xfs /dev/ublkb0 mount /dev/ublkb0 /mnt # do anything. all IOs are handled by io_uring ... umount /mnt}hjjsbah}(h]h ]h"]h$]h&]hhuh1jBhhhKJhjXubeh}(h]h ]h"]h$]h&]uh1hhj-hhhhhNubh)}(h1list the devices with their info:: ublk list h](h)}(h"list the devices with their info::h]h!list the devices with their info:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKPhj~ubjC)}(h ublk listh]h ublk list}hjsbah}(h]h ]h"]h$]h&]hhuh1jBhhhKRhj~ubeh}(h]h ]h"]h$]h&]uh1hhj-hhhhhNubh)}(h@delete the device:: ublk del -a ublk del -n $ublk_dev_id h](h)}(hdelete the device::h]hdelete the device:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKThjubjC)}(h$ublk del -a ublk del -n $ublk_dev_idh]h$ublk del -a ublk del -n $ublk_dev_id}hjsbah}(h]h ]h"]h$]h&]hhuh1jBhhhKVhjubeh}(h]h ]h"]h$]h&]uh1hhj-hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1hhhhKDhjhhubh)}(h@See usage details in README of ``ublksrv`` [#userspace_readme]_.h](hSee usage details in README of }(hjhhhNhNubj)}(h ``ublksrv``h]hublksrv}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh }(hjhhhNhNubj)}(h[#userspace_readme]_h]h4}(hjhhhNhNubah}(h]id5ah ]h"]h$]h&]jKjuserspace-readmejjuh1jhjjKubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKYhjhhubeh}(h] using-ublkah ]h"] using ublkah$]h&]uh1hhhhhhhhK>ubh)}(hhh](h)}(hDesignh]hDesign}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhK\ubh)}(hhh](h)}(h Control planeh]h Control plane}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK_ubh)}(hublk driver provides global misc device node (``/dev/ublk-control``) for managing and controlling ublk devices with help of several control commands:h](h.ublk driver provides global misc device node (}(hj.hhhNhNubj)}(h``/dev/ublk-control``h]h/dev/ublk-control}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj.ubhR) for managing and controlling ublk devices with help of several control commands:}(hj.hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKahjhhubh)}(hhh](h)}(hX``UBLK_CMD_ADD_DEV`` Add a ublk char device (``/dev/ublkc*``) which is talked with ublk server WRT IO command communication. Basic device info is sent together with this command. It sets UAPI structure of ``ublksrv_ctrl_dev_info``, such as ``nr_hw_queues``, ``queue_depth``, and max IO request buffer size, for which the info is negotiated with the driver and sent back to the server. When this command is completed, the basic device info is immutable. h](h)}(h``UBLK_CMD_ADD_DEV``h]j)}(hjWh]hUBLK_CMD_ADD_DEV}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjUubah}(h]h ]h"]h$]h&]uh1hhhhKdhjQubh)}(hXAdd a ublk char device (``/dev/ublkc*``) which is talked with ublk server WRT IO command communication. Basic device info is sent together with this command. It sets UAPI structure of ``ublksrv_ctrl_dev_info``, such as ``nr_hw_queues``, ``queue_depth``, and max IO request buffer size, for which the info is negotiated with the driver and sent back to the server. When this command is completed, the basic device info is immutable.h](hAdd a ublk char device (}(hjlhhhNhNubj)}(h``/dev/ublkc*``h]h /dev/ublkc*}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh) which is talked with ublk server WRT IO command communication. Basic device info is sent together with this command. It sets UAPI structure of }(hjlhhhNhNubj)}(h``ublksrv_ctrl_dev_info``h]hublksrv_ctrl_dev_info}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh , such as }(hjlhhhNhNubj)}(h``nr_hw_queues``h]h nr_hw_queues}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh, }(hjlhhhNhNubj)}(h``queue_depth``h]h queue_depth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjlubh, and max IO request buffer size, for which the info is negotiated with the driver and sent back to the server. When this command is completed, the basic device info is immutable.}(hjlhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKfhjQubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(hX9``UBLK_CMD_SET_PARAMS`` / ``UBLK_CMD_GET_PARAMS`` Set or get parameters of the device, which can be either generic feature related, or request queue limit related, but can't be IO logic specific, because the driver does not handle any IO logic. This command has to be sent before sending ``UBLK_CMD_START_DEV``. h](h)}(h1``UBLK_CMD_SET_PARAMS`` / ``UBLK_CMD_GET_PARAMS``h](j)}(h``UBLK_CMD_SET_PARAMS``h]hUBLK_CMD_SET_PARAMS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh / }(hjhhhNhNubj)}(h``UBLK_CMD_GET_PARAMS``h]hUBLK_CMD_GET_PARAMS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhKmhjubh)}(hXSet or get parameters of the device, which can be either generic feature related, or request queue limit related, but can't be IO logic specific, because the driver does not handle any IO logic. This command has to be sent before sending ``UBLK_CMD_START_DEV``.h](hSet or get parameters of the device, which can be either generic feature related, or request queue limit related, but can’t be IO logic specific, because the driver does not handle any IO logic. This command has to be sent before sending }(hjhhhNhNubj)}(h``UBLK_CMD_START_DEV``h]hUBLK_CMD_START_DEV}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKohjubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(hX*``UBLK_CMD_START_DEV`` After the server prepares userspace resources (such as creating per-queue pthread & io_uring for handling ublk IO), this command is sent to the driver for allocating & exposing ``/dev/ublkb*``. Parameters set via ``UBLK_CMD_SET_PARAMS`` are applied for creating the device. h](h)}(h``UBLK_CMD_START_DEV``h]j)}(hj"h]hUBLK_CMD_START_DEV}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1hhhhKthjubh)}(hXAfter the server prepares userspace resources (such as creating per-queue pthread & io_uring for handling ublk IO), this command is sent to the driver for allocating & exposing ``/dev/ublkb*``. Parameters set via ``UBLK_CMD_SET_PARAMS`` are applied for creating the device.h](hAfter the server prepares userspace resources (such as creating per-queue pthread & io_uring for handling ublk IO), this command is sent to the driver for allocating & exposing }(hj7hhhNhNubj)}(h``/dev/ublkb*``h]h /dev/ublkb*}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj7ubh. Parameters set via }(hj7hhhNhNubj)}(h``UBLK_CMD_SET_PARAMS``h]hUBLK_CMD_SET_PARAMS}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj7ubh% are applied for creating the device.}(hj7hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKvhjubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(h``UBLK_CMD_STOP_DEV`` Halt IO on ``/dev/ublkb*`` and remove the device. When this command returns, ublk server will release resources (such as destroying per-queue pthread & io_uring). h](h)}(h``UBLK_CMD_STOP_DEV``h]j)}(hjuh]hUBLK_CMD_STOP_DEV}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubah}(h]h ]h"]h$]h&]uh1hhhhK{hjoubh)}(hHalt IO on ``/dev/ublkb*`` and remove the device. When this command returns, ublk server will release resources (such as destroying per-queue pthread & io_uring).h](h Halt IO on }(hjhhhNhNubj)}(h``/dev/ublkb*``h]h /dev/ublkb*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh and remove the device. When this command returns, ublk server will release resources (such as destroying per-queue pthread & io_uring).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK}hjoubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(hy``UBLK_CMD_DEL_DEV`` Remove ``/dev/ublkc*``. When this command returns, the allocated ublk device number can be reused. h](h)}(h``UBLK_CMD_DEL_DEV``h]j)}(hjh]hUBLK_CMD_DEL_DEV}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hbRemove ``/dev/ublkc*``. When this command returns, the allocated ublk device number can be reused.h](hRemove }(hjhhhNhNubj)}(h``/dev/ublkc*``h]h /dev/ublkc*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhL. When this command returns, the allocated ublk device number can be reused.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(hXu``UBLK_CMD_GET_QUEUE_AFFINITY`` When ``/dev/ublkc`` is added, the driver creates block layer tagset, so that each queue's affinity info is available. The server sends ``UBLK_CMD_GET_QUEUE_AFFINITY`` to retrieve queue affinity info. It can set up the per-queue context efficiently, such as bind affine CPUs with IO pthread and try to allocate buffers in IO thread context. h](h)}(h``UBLK_CMD_GET_QUEUE_AFFINITY``h]j)}(hjh]hUBLK_CMD_GET_QUEUE_AFFINITY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hXSWhen ``/dev/ublkc`` is added, the driver creates block layer tagset, so that each queue's affinity info is available. The server sends ``UBLK_CMD_GET_QUEUE_AFFINITY`` to retrieve queue affinity info. It can set up the per-queue context efficiently, such as bind affine CPUs with IO pthread and try to allocate buffers in IO thread context.h](hWhen }(hj hhhNhNubj)}(h``/dev/ublkc``h]h /dev/ublkc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhv is added, the driver creates block layer tagset, so that each queue’s affinity info is available. The server sends }(hj hhhNhNubj)}(h``UBLK_CMD_GET_QUEUE_AFFINITY``h]hUBLK_CMD_GET_QUEUE_AFFINITY}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh to retrieve queue affinity info. It can set up the per-queue context efficiently, such as bind affine CPUs with IO pthread and try to allocate buffers in IO thread context.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(h``UBLK_CMD_GET_DEV_INFO`` For retrieving device info via ``ublksrv_ctrl_dev_info``. It is the server's responsibility to save IO target specific info in userspace. h](h)}(h``UBLK_CMD_GET_DEV_INFO``h]j)}(hjJh]hUBLK_CMD_GET_DEV_INFO}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjHubah}(h]h ]h"]h$]h&]uh1hhhhKhjDubh)}(hFor retrieving device info via ``ublksrv_ctrl_dev_info``. It is the server's responsibility to save IO target specific info in userspace.h](hFor retrieving device info via }(hj_hhhNhNubj)}(h``ublksrv_ctrl_dev_info``h]hublksrv_ctrl_dev_info}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jhj_ubhS. It is the server’s responsibility to save IO target specific info in userspace.}(hj_hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjDubeh}(h]h ]h"]h$]h&]uh1hhjNhhhhhNubh)}(hX``UBLK_CMD_GET_DEV_INFO2`` Same purpose with ``UBLK_CMD_GET_DEV_INFO``, but ublk server has to provide path of the char device of ``/dev/ublkc*`` for kernel to run permission check, and this command is added for supporting unprivileged ublk device, and introduced with ``UBLK_F_UNPRIVILEGED_DEV`` together. Only the user owning the requested device can retrieve the device info. How to deal with userspace/kernel compatibility: 1) if kernel is capable of handling ``UBLK_F_UNPRIVILEGED_DEV`` If ublk server supports ``UBLK_F_UNPRIVILEGED_DEV``: ublk server should send ``UBLK_CMD_GET_DEV_INFO2``, given anytime unprivileged application needs to query devices the current user owns, when the application has no idea if ``UBLK_F_UNPRIVILEGED_DEV`` is set given the capability info is stateless, and application should always retrieve it via ``UBLK_CMD_GET_DEV_INFO2`` If ublk server doesn't support ``UBLK_F_UNPRIVILEGED_DEV``: ``UBLK_CMD_GET_DEV_INFO`` is always sent to kernel, and the feature of UBLK_F_UNPRIVILEGED_DEV isn't available for user 2) if kernel isn't capable of handling ``UBLK_F_UNPRIVILEGED_DEV`` If ublk server supports ``UBLK_F_UNPRIVILEGED_DEV``: ``UBLK_CMD_GET_DEV_INFO2`` is tried first, and will be failed, then ``UBLK_CMD_GET_DEV_INFO`` needs to be retried given ``UBLK_F_UNPRIVILEGED_DEV`` can't be set If ublk server doesn't support ``UBLK_F_UNPRIVILEGED_DEV``: ``UBLK_CMD_GET_DEV_INFO`` is always sent to kernel, and the feature of ``UBLK_F_UNPRIVILEGED_DEV`` isn't available for user h](h)}(hXz``UBLK_CMD_GET_DEV_INFO2`` Same purpose with ``UBLK_CMD_GET_DEV_INFO``, but ublk server has to provide path of the char device of ``/dev/ublkc*`` for kernel to run permission check, and this command is added for supporting unprivileged ublk device, and introduced with ``UBLK_F_UNPRIVILEGED_DEV`` together. Only the user owning the requested device can retrieve the device info.h](j)}(h``UBLK_CMD_GET_DEV_INFO2``h]hUBLK_CMD_GET_DEV_INFO2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh Same purpose with }(hjhhhNhNubj)}(h``UBLK_CMD_GET_DEV_INFO``h]hUBLK_CMD_GET_DEV_INFO}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh<, but ublk server has to provide path of the char device of }(hjhhhNhNubj)}(h``/dev/ublkc*``h]h /dev/ublkc*}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh| for kernel to run permission check, and this command is added for supporting unprivileged ublk device, and introduced with }(hjhhhNhNubj)}(h``UBLK_F_UNPRIVILEGED_DEV``h]hUBLK_F_UNPRIVILEGED_DEV}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhR together. Only the user owning the requested device can retrieve the device info.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h0How to deal with userspace/kernel compatibility:h]h0How to deal with userspace/kernel compatibility:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubhenumerated_list)}(hhh]h)}(h=if kernel is capable of handling ``UBLK_F_UNPRIVILEGED_DEV`` h]h)}(hhjL hhubh)}(hXublk server implementing zero copy or user copy has to be CAP_SYS_ADMIN and be trusted, because it is ublk server's responsibility to make sure IO buffer filled with data for handling read command, and ublk server has to return correct result to ublk driver when handling READ command, and the result has to match with how many bytes filled to the IO buffer. Otherwise, uninitialized kernel IO buffer will be exposed to client application.Hh]hXublk server implementing zero copy or user copy has to be CAP_SYS_ADMIN and be trusted, because it is ublk server’s responsibility to make sure IO buffer filled with data for handling read command, and ublk server has to return correct result to ublk driver when handling READ command, and the result has to match with how many bytes filled to the IO buffer. Otherwise, uninitialized kernel IO buffer will be exposed to client application.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMHhjL hhubh)}(hwublk server needs to align the parameter of `struct ublk_param_dma_align` with backend for zero copy to work correctly.h](h,ublk server needs to align the parameter of }(hjhhhNhNubjf )}(h`struct ublk_param_dma_align`h]hstruct ublk_param_dma_align}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1je hjubh. with backend for zero copy to work correctly.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMOhjL hhubh)}(hFor reaching best IO performance, ublk server should align its segment parameter of `struct ublk_param_segment` with backend for avoiding unnecessary IO split, which usually hurts io_uring performance.h](hTFor reaching best IO performance, ublk server should align its segment parameter of }(hj9hhhNhNubjf )}(h`struct ublk_param_segment`h]hstruct ublk_param_segment}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1je hj9ubhZ with backend for avoiding unnecessary IO split, which usually hurts io_uring performance.}(hj9hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMRhjL hhubeh}(h] zero-copyah ]h"] zero copyah$]h&]uh1hhj hhhhhM9ubeh}(h]designah ]h"]designah$]h&]uh1hhhhhhhhK\ubh)}(hhh](h)}(h Referencesh]h References}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjihhhhhMWubhfootnote)}(h https://github.com/ming1/ubdsrv h](hlabel)}(hhh]h1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj|hhhNhNubh)}(hhttps://github.com/ming1/ubdsrvh]h reference)}(hjh]hhttps://github.com/ming1/ubdsrv}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhMYhj|ubeh}(h]jah ]h"] userspaceah$]h&]jajKjjuh1jzhhhMYhjihhubj{)}(h0https://github.com/ming1/ubdsrv/tree/master/lib h](j)}(hhh]h2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhNhNubh)}(h/https://github.com/ming1/ubdsrv/tree/master/libh]j)}(hjh]h/https://github.com/ming1/ubdsrv/tree/master/lib}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM[hjubeh}(h]j&ah ]h"] userspace_libah$]h&](j!jmejKjjuh1jzhhhM[hjihhubj{)}(h2https://gitlab.com/rwmjones/libnbd/-/tree/nbdublk h](j)}(hhh]h3}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhNhNubh)}(h1https://gitlab.com/rwmjones/libnbd/-/tree/nbdublkh]j)}(hjh]h1https://gitlab.com/rwmjones/libnbd/-/tree/nbdublk}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhM]hjubeh}(h]jLah ]h"]userspace_nbdublkah$]h&]jGajKjjuh1jzhhhM]hjihhubj{)}(h2https://github.com/ming1/ubdsrv/blob/master/READMEh](j)}(hhh]h4}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhNhNubh)}(hjh]j)}(hjh]h2https://github.com/ming1/ubdsrv/blob/master/README}(hj$hhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhj!ubah}(h]h ]h"]h$]h&]uh1hhhhM_hjubeh}(h]jah ]h"]userspace_readmeah$]h&]jajKjjuh1jzhhhM_hjihhubeh}(h] referencesah ]h"] referencesah$]h&]uh1hhhhhhhhMWubeh}(h])userspace-block-device-driver-ublk-driverah ]h"]+userspace block device driver (ublk driver)ah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjrerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}( userspace]ja userspace_lib](jjceuserspace_nbdublk]j=auserspace_readme]jaurefids}(j]jaj&](jjcejL]j=aj]jaunameids}(jLjIjjj jjfjcj j jI jF j^j[jDjAjjjj&j jLj<ju nametypes}(jLjj jfj jI j^jDjjj j<uh}(jIhjhjjj!jjGj=jmjcjjjjjcj j jjF j j[jL jAjijj|j&jjLjjju footnote_refs}(j]jaj](jjcej]j=aj]jau citation_refs} autofootnotes](j|jjjeautofootnote_refs](jjj=jcjesymbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "2" (ordinal 2)h]h>Enumerated list start value not ordinal-1: “2” (ordinal 2)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1jhjubatransform_messages] transformerN include_log] decorationNhhub.