selftests: ublk: fix UBLK_F_NEED_GET_DATA
authorMing Lei <ming.lei@redhat.com>
Tue, 29 Apr 2025 02:29:36 +0000 (10:29 +0800)
committerJens Axboe <axboe@kernel.dk>
Tue, 29 Apr 2025 12:01:36 +0000 (06:01 -0600)
Commit 57e13a2e8cd2 ("selftests: ublk: support user recovery") starts to
support UBLK_F_NEED_GET_DATA for covering recovery feature, however the
ublk utility implementation isn't done correctly.

Fix it by supporting UBLK_F_NEED_GET_DATA correctly.

Also add test generic_07 for covering UBLK_F_NEED_GET_DATA.

Reviewed-by: Caleb Sander Mateos <csander@purestorage.com>
Fixes: 57e13a2e8cd2 ("selftests: ublk: support user recovery")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250429022941.1718671-2-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
tools/testing/selftests/ublk/Makefile
tools/testing/selftests/ublk/kublk.c
tools/testing/selftests/ublk/kublk.h
tools/testing/selftests/ublk/test_generic_07.sh [new file with mode: 0755]
tools/testing/selftests/ublk/test_stress_05.sh

index ec4624a283bce2ebeed80509be6573c1b7a3623d..f34ac0bac696233084bec2e19e8f6312d775c3e9 100644 (file)
@@ -9,6 +9,7 @@ TEST_PROGS += test_generic_03.sh
 TEST_PROGS += test_generic_04.sh
 TEST_PROGS += test_generic_05.sh
 TEST_PROGS += test_generic_06.sh
+TEST_PROGS += test_generic_07.sh
 
 TEST_PROGS += test_null_01.sh
 TEST_PROGS += test_null_02.sh
index e57a1486bb48d8aa0340f96d65c3f0bbcf71efff..842b40736a9b81507960bba21a246c8b5d3bddee 100644 (file)
@@ -536,12 +536,17 @@ int ublk_queue_io_cmd(struct ublk_queue *q, struct ublk_io *io, unsigned tag)
        if (!(io->flags & UBLKSRV_IO_FREE))
                return 0;
 
-       /* we issue because we need either fetching or committing */
+       /*
+        * we issue because we need either fetching or committing or
+        * getting data
+        */
        if (!(io->flags &
-               (UBLKSRV_NEED_FETCH_RQ | UBLKSRV_NEED_COMMIT_RQ_COMP)))
+               (UBLKSRV_NEED_FETCH_RQ | UBLKSRV_NEED_COMMIT_RQ_COMP | UBLKSRV_NEED_GET_DATA)))
                return 0;
 
-       if (io->flags & UBLKSRV_NEED_COMMIT_RQ_COMP)
+       if (io->flags & UBLKSRV_NEED_GET_DATA)
+               cmd_op = UBLK_U_IO_NEED_GET_DATA;
+       else if (io->flags & UBLKSRV_NEED_COMMIT_RQ_COMP)
                cmd_op = UBLK_U_IO_COMMIT_AND_FETCH_REQ;
        else if (io->flags & UBLKSRV_NEED_FETCH_RQ)
                cmd_op = UBLK_U_IO_FETCH_REQ;
@@ -658,6 +663,9 @@ static void ublk_handle_cqe(struct io_uring *r,
                assert(tag < q->q_depth);
                if (q->tgt_ops->queue_io)
                        q->tgt_ops->queue_io(q, tag);
+       } else if (cqe->res == UBLK_IO_RES_NEED_GET_DATA) {
+               io->flags |= UBLKSRV_NEED_GET_DATA | UBLKSRV_IO_FREE;
+               ublk_queue_io_cmd(q, io, tag);
        } else {
                /*
                 * COMMIT_REQ will be completed immediately since no fetching
@@ -1237,7 +1245,7 @@ static void __cmd_create_help(char *exe, bool recovery)
 
        printf("%s %s -t [null|loop|stripe|fault_inject] [-q nr_queues] [-d depth] [-n dev_id]\n",
                        exe, recovery ? "recover" : "add");
-       printf("\t[--foreground] [--quiet] [-z] [--debug_mask mask] [-r 0|1 ] [-g 0|1]\n");
+       printf("\t[--foreground] [--quiet] [-z] [--debug_mask mask] [-r 0|1 ] [-g]\n");
        printf("\t[-e 0|1 ] [-i 0|1]\n");
        printf("\t[target options] [backfile1] [backfile2] ...\n");
        printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), dev_id=-1(auto allocation)\n");
@@ -1313,7 +1321,7 @@ int main(int argc, char *argv[])
 
        opterr = 0;
        optind = 2;
-       while ((opt = getopt_long(argc, argv, "t:n:d:q:r:e:i:az",
+       while ((opt = getopt_long(argc, argv, "t:n:d:q:r:e:i:gaz",
                                  longopts, &option_idx)) != -1) {
                switch (opt) {
                case 'a':
@@ -1351,9 +1359,7 @@ int main(int argc, char *argv[])
                                ctx.flags |= UBLK_F_USER_RECOVERY | UBLK_F_USER_RECOVERY_REISSUE;
                        break;
                case 'g':
-                       value = strtol(optarg, NULL, 10);
-                       if (value)
-                               ctx.flags |= UBLK_F_NEED_GET_DATA;
+                       ctx.flags |= UBLK_F_NEED_GET_DATA;
                        break;
                case 0:
                        if (!strcmp(longopts[option_idx].name, "debug_mask"))
index 918db5cd633fc1041e1e0805142f00e7e4f28bf7..44ee1e4ac55b2de145249205ddb449a56d8103ce 100644 (file)
@@ -115,6 +115,7 @@ struct ublk_io {
 #define UBLKSRV_NEED_FETCH_RQ          (1UL << 0)
 #define UBLKSRV_NEED_COMMIT_RQ_COMP    (1UL << 1)
 #define UBLKSRV_IO_FREE                        (1UL << 2)
+#define UBLKSRV_NEED_GET_DATA           (1UL << 3)
        unsigned short flags;
        unsigned short refs;            /* used by target code only */
 
diff --git a/tools/testing/selftests/ublk/test_generic_07.sh b/tools/testing/selftests/ublk/test_generic_07.sh
new file mode 100755 (executable)
index 0000000..cba8645
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
+
+TID="generic_07"
+ERR_CODE=0
+
+if ! _have_program fio; then
+       exit "$UBLK_SKIP_CODE"
+fi
+
+_prep_test "generic" "test UBLK_F_NEED_GET_DATA"
+
+_create_backfile 0 256M
+dev_id=$(_add_ublk_dev -t loop -q 2 -g "${UBLK_BACKFILES[0]}")
+_check_add_dev $TID $?
+
+# run fio over the ublk disk
+_run_fio_verify_io --filename=/dev/ublkb"${dev_id}" --size=256M
+ERR_CODE=$?
+if [ "$ERR_CODE" -eq 0 ]; then
+       _mkfs_mount_test /dev/ublkb"${dev_id}"
+       ERR_CODE=$?
+fi
+
+_cleanup_test "generic"
+_show_result $TID $ERR_CODE
index a7071b10224d9f834ca98d61f90fe554c6060efe..88601b48f1cd377d23f725d7773e14e4834da8ef 100755 (executable)
@@ -47,15 +47,15 @@ _create_backfile 0 256M
 _create_backfile 1 256M
 
 for reissue in $(seq 0 1); do
-       ublk_io_and_remove 8G -t null -q 4 -g -r 1 -i "$reissue" &
-       ublk_io_and_remove 256M -t loop -q 4 -g -r 1 -i "$reissue" "${UBLK_BACKFILES[0]}" &
+       ublk_io_and_remove 8G -t null -q 4 -g -r 1 -i "$reissue" &
+       ublk_io_and_remove 256M -t loop -q 4 -g -r 1 -i "$reissue" "${UBLK_BACKFILES[0]}" &
        wait
 done
 
 if _have_feature "ZERO_COPY"; then
        for reissue in $(seq 0 1); do
-               ublk_io_and_remove 8G -t null -q 4 -g -z -r 1 -i "$reissue" &
-               ublk_io_and_remove 256M -t loop -q 4 -g -z -r 1 -i "$reissue" "${UBLK_BACKFILES[1]}" &
+               ublk_io_and_remove 8G -t null -q 4 -g -z -r 1 -i "$reissue" &
+               ublk_io_and_remove 256M -t loop -q 4 -g -z -r 1 -i "$reissue" "${UBLK_BACKFILES[1]}" &
                wait
        done
 fi