@@ -21,6 +21,7 @@ endif
TEST_PROGS := test_null_01.sh
TEST_PROGS += test_null_02.sh
+TEST_PROGS += test_null_03.sh
# Order correspond to 'make run_tests' order
TEST_GEN_PROGS_EXTENDED = ublk_bpf
@@ -11,6 +11,40 @@
/* libbpf v1.4.5 is required for struct_ops to work */
+static inline ublk_bpf_return_t __ublk_null_handle_io_split(const struct ublk_bpf_io *io, unsigned int _off)
+{
+ unsigned long off = -1, sects = -1;
+ const struct ublksrv_io_desc *iod;
+ int res;
+
+ iod = ublk_bpf_get_iod(io);
+ if (iod) {
+ res = iod->nr_sectors << 9;
+ off = iod->start_sector;
+ sects = iod->nr_sectors;
+ } else
+ res = -EINVAL;
+
+ BPF_DBG("ublk dev %u qid %u: handle io tag %u %lx-%d res %d",
+ ublk_bpf_get_dev_id(io),
+ ublk_bpf_get_queue_id(io),
+ ublk_bpf_get_io_tag(io),
+ off, sects, res);
+ if (res < 0) {
+ ublk_bpf_complete_io(io, res);
+ return ublk_bpf_return_val(UBLK_BPF_IO_QUEUED, 0);
+ }
+
+ /* split this io to one 512bytes sub-io and the remainder */
+ if (_off < 512 && res > 512)
+ return ublk_bpf_return_val(UBLK_BPF_IO_CONTINUE, 512);
+
+ /* complete the whole io command after the 2nd sub-io is queued */
+ ublk_bpf_complete_io(io, res);
+ return ublk_bpf_return_val(UBLK_BPF_IO_QUEUED, 0);
+}
+
+
static inline ublk_bpf_return_t __ublk_null_handle_io(const struct ublk_bpf_io *io, unsigned int _off)
{
unsigned long off = -1, sects = -1;
@@ -60,4 +94,16 @@ struct ublk_bpf_ops null_ublk_bpf_ops = {
.detach_dev = (void *)ublk_null_detach_dev,
};
+SEC("struct_ops/ublk_bpf_queue_io_cmd")
+ublk_bpf_return_t BPF_PROG(ublk_null_handle_io_split, struct ublk_bpf_io *io, unsigned int off)
+{
+ return __ublk_null_handle_io_split(io, off);
+}
+
+SEC(".struct_ops.link")
+struct ublk_bpf_ops null_ublk_bpf_ops_split = {
+ .id = 1,
+ .queue_io_cmd = (void *)ublk_null_handle_io_split,
+};
+
char LICENSE[] SEC("license") = "GPL";
new file mode 100755
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+. test_common.sh
+
+TID="null_03"
+ERR_CODE=0
+
+# prepare and register & pin bpf prog
+_prep_bpf_test "null" ublk_null.bpf.o
+
+# add two ublk null disks with the pinned bpf prog
+_add_ublk_dev -t null -n 0 --bpf_prog 1 --quiet
+
+# run fio over the ublk disk
+fio --name=job1 --filename=/dev/ublkb0 --ioengine=libaio --rw=readwrite --iodepth=32 --size=256M > /dev/null 2>&1
+ERR_CODE=$?
+
+# clean and unregister & unpin the bpf prog
+_cleanup_bpf_test "null"
+
+_show_result $TID $ERR_CODE
One io command can be queued in split way, add test case for covering this way: - split the io command into two sub-io if the io size is bigger than 512 - the 1st sub-io size is 512byte, and the 2nd sub-io is the remained bytes Complete the whole io command until the two sub-io are queued. Signed-off-by: Ming Lei <tom.leiming@gmail.com> --- tools/testing/selftests/ublk/Makefile | 1 + .../testing/selftests/ublk/progs/ublk_null.c | 46 +++++++++++++++++++ tools/testing/selftests/ublk/test_null_03.sh | 21 +++++++++ 3 files changed, 68 insertions(+) create mode 100755 tools/testing/selftests/ublk/test_null_03.sh