1#include "block/tests/test_internal.h"
2
3TEST_GROUP_DECLARE(bio, .intensity_desc = {
4 .curve = SCALE_PIECEWISE_LINEAR,
5 .unit = "ios",
6 });
7
8#define EXT2_INIT \
9 if (global.root_node->fs_type != FS_EXT2) { \
10 test_info("the mounted root is not ext2"); \
11 return TEST_SKIP(TEST_SKIP_NONE); \
12 } \
13 struct vfs_node *root = global.root_node;
14
15static atomic_bool done = false;
16static void bio_callback(struct bio_request *req) {
17 (void) req;
18 done = true;
19 test_info("blkdev_bio callback succeeded");
20}
21
22TEST_DECLARE_INTEGRATION(bio, async_submit, TEST_INTENSITY(1, 1, 16)) {
23 EXT2_INIT;
24 struct ext2_fs *fs = root->fs_data;
25 struct block_device *d = fs->drive;
26 uint64_t run_times = ctx->intensity_val ? ctx->intensity_val : 1;
27 done = false;
28 enable_interrupts();
29
30 for (uint64_t i = 0; i < run_times; i++) {
31 struct bio_request *bio = kmalloc(sizeof(struct bio_request), 0);
32 uint8_t *buf = kmalloc_aligned(64 * PAGE_SIZE, PAGE_SIZE);
33 *bio = (struct bio_request){
34 .lba = 0,
35 .buffer = buf,
36 .size = 512 * 512,
37 .sector_count = 512,
38 .write = false,
39 .done = false,
40 .status = -1,
41 .on_complete = bio_callback,
42 .priority = BIO_RQ_MEDIUM,
43 .user_data = (void *) BIO_RQ_MEDIUM,
44 };
45
46 if (i % 2 == 0) {
47 bio->priority = BIO_RQ_HIGH;
48 bio->user_data = (void *) BIO_RQ_HIGH;
49 }
50
51 bool submitted = d->submit_bio_async(d, bio);
52 if (!submitted)
53 return TEST_FAIL("submit_bio_async rejected the request");
54
55 sleep_spin_ms(msec: 100);
56
57 TEST_ASSERT_OK(bio->status);
58 }
59 TEST_ASSERT_TRUE(done);
60 return TEST_SUCCESS;
61}
62