1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/*
* Copyright (C) 2018 Western Digital Corporation or its affiliates.
*
* This file is released under the GPL.
*/
#ifndef FIO_ZBD_H
#define FIO_ZBD_H
#include <inttypes.h>
#include "fio.h" /* FIO_MAX_OPEN_ZBD_ZONES */
#ifdef CONFIG_LINUX_BLKZONED
#include <linux/blkzoned.h>
#endif
struct fio_file;
/*
* Zoned block device models.
*/
enum blk_zoned_model {
ZBD_DM_NONE, /* Regular block device */
ZBD_DM_HOST_AWARE, /* Host-aware zoned block device */
ZBD_DM_HOST_MANAGED, /* Host-managed zoned block device */
};
enum io_u_action {
io_u_accept = 0,
io_u_eof = 1,
};
/**
* struct fio_zone_info - information about a single ZBD zone
* @start: zone start location (bytes)
* @wp: zone write pointer location (bytes)
* @verify_block: number of blocks that have been verified for this zone
* @mutex: protects the modifiable members in this structure
* @type: zone type (BLK_ZONE_TYPE_*)
* @cond: zone state (BLK_ZONE_COND_*)
* @open: whether or not this zone is currently open. Only relevant if
* max_open_zones > 0.
* @reset_zone: whether or not this zone should be reset before writing to it
*/
struct fio_zone_info {
#ifdef CONFIG_LINUX_BLKZONED
pthread_mutex_t mutex;
uint64_t start;
uint64_t wp;
uint32_t verify_block;
enum blk_zone_type type:2;
enum blk_zone_cond cond:4;
unsigned int open:1;
unsigned int reset_zone:1;
#endif
};
/**
* zoned_block_device_info - zoned block device characteristics
* @model: Device model.
* @mutex: Protects the modifiable members in this structure (refcount and
* num_open_zones).
* @zone_size: size of a single zone in units of 512 bytes
* @sectors_with_data: total size of data in all zones in units of 512 bytes
* @zone_size_log2: log2 of the zone size in bytes if it is a power of 2 or 0
* if the zone size is not a power of 2.
* @nr_zones: number of zones
* @refcount: number of fio files that share this structure
* @num_open_zones: number of open zones
* @write_cnt: Number of writes since the latest zone reset triggered by
* the zone_reset_frequency fio job parameter.
* @open_zones: zone numbers of open zones
* @zone_info: description of the individual zones
*
* Only devices for which all zones have the same size are supported.
* Note: if the capacity is not a multiple of the zone size then the last zone
* will be smaller than 'zone_size'.
*/
struct zoned_block_device_info {
enum blk_zoned_model model;
pthread_mutex_t mutex;
uint64_t zone_size;
uint64_t sectors_with_data;
uint32_t zone_size_log2;
uint32_t nr_zones;
uint32_t refcount;
uint32_t num_open_zones;
uint32_t write_cnt;
uint32_t open_zones[FIO_MAX_OPEN_ZBD_ZONES];
struct fio_zone_info zone_info[0];
};
#ifdef CONFIG_LINUX_BLKZONED
void zbd_free_zone_info(struct fio_file *f);
int zbd_init(struct thread_data *td);
void zbd_file_reset(struct thread_data *td, struct fio_file *f);
bool zbd_unaligned_write(int error_code);
void setup_zbd_zone_mode(struct thread_data *td, struct io_u *io_u);
enum io_u_action zbd_adjust_block(struct thread_data *td, struct io_u *io_u);
char *zbd_write_status(const struct thread_stat *ts);
static inline void zbd_queue_io_u(struct io_u *io_u, enum fio_q_status status)
{
if (io_u->zbd_queue_io) {
io_u->zbd_queue_io(io_u, status, io_u->error == 0);
io_u->zbd_queue_io = NULL;
}
}
static inline void zbd_put_io_u(struct io_u *io_u)
{
if (io_u->zbd_put_io) {
io_u->zbd_put_io(io_u);
io_u->zbd_queue_io = NULL;
io_u->zbd_put_io = NULL;
}
}
#else
static inline void zbd_free_zone_info(struct fio_file *f)
{
}
static inline int zbd_init(struct thread_data *td)
{
return 0;
}
static inline void zbd_file_reset(struct thread_data *td, struct fio_file *f)
{
}
static inline bool zbd_unaligned_write(int error_code)
{
return false;
}
static inline enum io_u_action zbd_adjust_block(struct thread_data *td,
struct io_u *io_u)
{
return io_u_accept;
}
static inline char *zbd_write_status(const struct thread_stat *ts)
{
return NULL;
}
static inline void zbd_queue_io_u(struct io_u *io_u,
enum fio_q_status status) {}
static inline void zbd_put_io_u(struct io_u *io_u) {}
static inline void setup_zbd_zone_mode(struct thread_data *td,
struct io_u *io_u)
{
}
#endif
#endif /* FIO_ZBD_H */
|