1/* @title: Block I/O Requests */
2#pragma once
3#include <container_of.h>
4#include <stdatomic.h>
5#include <stdbool.h>
6#include <stdint.h>
7#include <structures/list.h>
8
9/* urgent requests bypass the bio_scheduler,
10 * they get submitted immediately */
11enum bio_request_priority {
12 BIO_RQ_BACKGROUND = 0,
13 BIO_RQ_LOW = 1,
14 BIO_RQ_MEDIUM = 2,
15 BIO_RQ_HIGH = 3,
16 BIO_RQ_URGENT = 4,
17};
18
19enum bio_request_status : int32_t {
20 BIO_STATUS_OK = 0,
21 BIO_STATUS_INFLIGHT = -1,
22 BIO_STATUS_INVAL_ARG = -2,
23 BIO_STATUS_INVAL_INTERNAL = -3,
24 BIO_STATUS_TIMEOUT = -4,
25 BIO_STATUS_DEVICE_FAULT = -5,
26 BIO_STATUS_UNCORRECTABLE = -6,
27 BIO_STATUS_ABRT = -7,
28 BIO_STATUS_MEDIA_CHANGE = -8,
29 BIO_STATUS_ID_NOT_FOUND = -9,
30 BIO_STATUS_BAD_SECTOR = -10,
31 BIO_STATUS_WRITE_PROTECT = -11,
32 BIO_STATUS_UNKNOWN_ERR = -12
33};
34
35/* everything WITHOUT the / const / comment next to it
36 * can be changed by the scheduler during optimizations */
37struct bio_request {
38 /* REQUIRED to be set by sender */
39
40 /* starting priority - can get boosted */
41 enum bio_request_priority priority;
42 /* const */ struct block_device *disk;
43
44 /* starting logical block address */
45 /* const */ uint64_t lba;
46
47 /* const */ void *buffer;
48
49 /* buffer size in bytes */
50 uint64_t size;
51
52 /* sectors to read/write */
53 uint64_t sector_count;
54
55 /* const */ bool write;
56
57 /* OPTIONALLY set by sender */
58 void (*on_complete)(struct bio_request *);
59 /* const */ void *user_data;
60
61 /* set upon completion */
62 volatile bool done;
63 enum bio_request_status status;
64
65 void *driver_private;
66 void *driver_private2;
67
68 struct list_head list;
69
70 /* everything below this is internally used in scheduler */
71
72 /* coalescing */
73 bool skip;
74 bool is_aggregate;
75 struct bio_request *next_coalesced;
76
77 /* priority boosted to URGENT after
78 * enough waiting around */
79 uint64_t enqueue_time;
80
81 /* boosts are accelerated if it
82 * boosts often */
83 uint8_t boost_count;
84};
85
86#define bio_request_from_list_node(ln) \
87 (container_of(ln, struct bio_request, list))
88
89struct bio_request *bio_create_write(struct block_device *d, uint64_t lba,
90 uint64_t sectors, uint64_t size,
91 void (*cb)(struct bio_request *),
92 void *user, void *buf);
93
94struct bio_request *bio_create_read(struct block_device *d, uint64_t lba,
95 uint64_t sectors, uint64_t size,
96 void (*cb)(struct bio_request *),
97 void *user, void *buf);
98