summaryrefslogtreecommitdiff
path: root/zbd.h
blob: e0a7e447521d1bb3b71a9803241bca3c093871a2 (plain)
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 */