summaryrefslogtreecommitdiff
path: root/zbd.h
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@wdc.com>2018-08-24 11:31:27 -0700
committerJens Axboe <axboe@kernel.dk>2018-08-24 12:54:36 -0600
commitbfbdd35b3e8f7de1bf1f48e7087c04a6b37e9c61 (patch)
tree60f60a55b46990c3d6167fa93f897c6e2614b43d /zbd.h
parentbd6b959a034cdcfcef010e56b139c609f56b83cf (diff)
downloadfio-bfbdd35b3e8f7de1bf1f48e7087c04a6b37e9c61.tar.gz
fio-bfbdd35b3e8f7de1bf1f48e7087c04a6b37e9c61.tar.bz2
Add support for zoned block devices
This patch adds support for zoned block devices as follows: - After the file size has been determined, check whether the file name refers to a block device. If so, check whether that block device is a host-managed block device. If that is the case, read the zone information using the BLKREPORTZONE ioctl. That ioctl is supported by the Linux kernel since kernel version v4.10. - After all command-line options have been processed and all job files have been read, verify whether these refer to a zoned block device and also whether the specified options are compatible with a zoned block device. Complain if that is not the case. - After each get_next_block() call, verify whether the block is appropriate for a zoned block device. When writing data to a sequential zone, adjust the write offset to the zone write pointer. When reading from a sequential zone, avoid reading past the write pointer. - After I/O submission, update the variable that represents the write pointer. - When writing data and with data verification enabled, reset a zone before writing any data into a zone. Otherwise reset a zone before issuing a write if that zone is full. - Translate trim into zone resets. Zoned block devices namely do not have to support any of the SCSI commands that are used by the kernel to implement the discard ioctl (UNMAP / WRITE SAME). This work started from a patch from Masato Suzuki <masato.suzuki@wdc.com>. Some of the ideas in this patch come from Phillip Chen <phillip.a.chen@seagate.com>. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'zbd.h')
-rw-r--r--zbd.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/zbd.h b/zbd.h
new file mode 100644
index 00000000..ec5d85e1
--- /dev/null
+++ b/zbd.h
@@ -0,0 +1,125 @@
+/*
+ * 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>
+#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 in 512 byte units
+ * @wp: zone write pointer location in 512 byte units
+ * @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).
+ * @zone_size: size of a single zone 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
+ * @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;
+ uint32_t zone_size_log2;
+ uint32_t nr_zones;
+ uint32_t refcount;
+ 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);
+enum io_u_action zbd_adjust_block(struct thread_data *td, struct io_u *io_u);
+int zbd_do_trim(struct thread_data *td, const struct io_u *io_u);
+void zbd_update_wp(struct thread_data *td, const struct io_u *io_u);
+#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 int zbd_do_trim(struct thread_data *td, const struct io_u *io_u)
+{
+ return 1;
+}
+
+static inline void zbd_update_wp(struct thread_data *td,
+ const struct io_u *io_u)
+{
+}
+#endif
+
+#endif /* FIO_ZBD_H */