1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2019 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 /** \file 7 * Zoned device public interface 8 */ 9 10 #ifndef SPDK_BDEV_ZONE_H 11 #define SPDK_BDEV_ZONE_H 12 13 #include "spdk/stdinc.h" 14 #include "spdk/bdev.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 /** 21 * \brief SPDK block device. 22 * 23 * This is a virtual representation of a block device that is exported by the backend. 24 */ 25 26 struct spdk_bdev; 27 28 enum spdk_bdev_zone_type { 29 SPDK_BDEV_ZONE_TYPE_CNV = 0x1, 30 SPDK_BDEV_ZONE_TYPE_SEQWR = 0x2, 31 SPDK_BDEV_ZONE_TYPE_SEQWP = 0x3, 32 }; 33 34 enum spdk_bdev_zone_action { 35 SPDK_BDEV_ZONE_CLOSE, 36 SPDK_BDEV_ZONE_FINISH, 37 SPDK_BDEV_ZONE_OPEN, 38 SPDK_BDEV_ZONE_RESET, 39 SPDK_BDEV_ZONE_OFFLINE, 40 }; 41 42 enum spdk_bdev_zone_state { 43 SPDK_BDEV_ZONE_STATE_EMPTY = 0x0, 44 SPDK_BDEV_ZONE_STATE_IMP_OPEN = 0x1, 45 /* OPEN is an alias for IMP_OPEN. OPEN is kept for backwards compatibility. */ 46 SPDK_BDEV_ZONE_STATE_OPEN = SPDK_BDEV_ZONE_STATE_IMP_OPEN, 47 SPDK_BDEV_ZONE_STATE_FULL = 0x2, 48 SPDK_BDEV_ZONE_STATE_CLOSED = 0x3, 49 SPDK_BDEV_ZONE_STATE_READ_ONLY = 0x4, 50 SPDK_BDEV_ZONE_STATE_OFFLINE = 0x5, 51 SPDK_BDEV_ZONE_STATE_EXP_OPEN = 0x6, 52 SPDK_BDEV_ZONE_STATE_NOT_WP = 0x7, 53 }; 54 55 struct spdk_bdev_zone_info { 56 uint64_t zone_id; 57 uint64_t write_pointer; 58 uint64_t capacity; 59 enum spdk_bdev_zone_state state; 60 enum spdk_bdev_zone_type type; 61 }; 62 63 /** 64 * Get device zone size in logical blocks. 65 * 66 * \param bdev Block device to query. 67 * \return Size of zone for this zoned device in logical blocks. 68 */ 69 uint64_t spdk_bdev_get_zone_size(const struct spdk_bdev *bdev); 70 71 /** 72 * Get the number of zones for the given device. 73 * 74 * \param bdev Block device to query. 75 * \return The number of zones. 76 */ 77 uint64_t spdk_bdev_get_num_zones(const struct spdk_bdev *bdev); 78 79 /** 80 * Get the first logical block of a zone (known as zone_id or zslba) 81 * for a given offset. 82 * 83 * \param bdev Block device to query. 84 * \param offset_blocks The offset, in blocks, from the start of the block device. 85 * \return The zone_id (also known as zslba) for the given offset. 86 */ 87 uint64_t spdk_bdev_get_zone_id(const struct spdk_bdev *bdev, uint64_t offset_blocks); 88 89 /** 90 * Get device maximum zone append data transfer size in logical blocks. 91 * 92 * If this value is 0, there is no limit. 93 * 94 * \param bdev Block device to query. 95 * \return Maximum zone append data transfer size for this zoned device in logical blocks. 96 */ 97 uint32_t spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev); 98 99 /** 100 * Get device maximum number of open zones. 101 * 102 * An open zone is defined as a zone being in zone state 103 * SPDK_BDEV_ZONE_STATE_IMP_OPEN or SPDK_BDEV_ZONE_STATE_EXP_OPEN. 104 * 105 * If this value is 0, there is no limit. 106 * 107 * \param bdev Block device to query. 108 * \return Maximum number of open zones for this zoned device. 109 */ 110 uint32_t spdk_bdev_get_max_open_zones(const struct spdk_bdev *bdev); 111 112 /** 113 * Get device maximum number of active zones. 114 * 115 * An active zone is defined as a zone being in zone state 116 * SPDK_BDEV_ZONE_STATE_IMP_OPEN, SPDK_BDEV_ZONE_STATE_EXP_OPEN or 117 * SPDK_BDEV_ZONE_STATE_CLOSED. 118 * 119 * If this value is 0, there is no limit. 120 * 121 * \param bdev Block device to query. 122 * \return Maximum number of active zones for this zoned device. 123 */ 124 uint32_t spdk_bdev_get_max_active_zones(const struct spdk_bdev *bdev); 125 126 /** 127 * Get device optimal number of open zones. 128 * 129 * \param bdev Block device to query. 130 * \return Optimal number of open zones for this zoned device. 131 */ 132 uint32_t spdk_bdev_get_optimal_open_zones(const struct spdk_bdev *bdev); 133 134 /** 135 * Submit a get_zone_info request to the bdev. 136 * 137 * \ingroup bdev_io_submit_functions 138 * 139 * \param desc Block device descriptor. 140 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 141 * \param zone_id First logical block of a zone. 142 * \param num_zones Number of consecutive zones info to retrieve. 143 * \param info Pointer to array capable of storing num_zones elements. 144 * \param cb Called when the request is complete. 145 * \param cb_arg Argument passed to cb. 146 * 147 * \return 0 on success. On success, the callback will always 148 * be called (even if the request ultimately failed). Return 149 * negated errno on failure, in which case the callback will not be called. 150 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 151 */ 152 int spdk_bdev_get_zone_info(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 153 uint64_t zone_id, size_t num_zones, struct spdk_bdev_zone_info *info, 154 spdk_bdev_io_completion_cb cb, void *cb_arg); 155 156 157 /** 158 * Submit a zone_management request to the bdev. 159 * 160 * \ingroup bdev_io_submit_functions 161 * 162 * \param desc Block device descriptor. 163 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 164 * \param zone_id First logical block of a zone. 165 * \param action Action to perform on a zone (open, close, reset, finish, offline). 166 * \param cb Called when the request is complete. 167 * \param cb_arg Argument passed to cb. 168 * 169 * \return 0 on success. On success, the callback will always 170 * be called (even if the request ultimately failed). Return 171 * negated errno on failure, in which case the callback will not be called. 172 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 173 */ 174 int spdk_bdev_zone_management(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 175 uint64_t zone_id, enum spdk_bdev_zone_action action, 176 spdk_bdev_io_completion_cb cb, void *cb_arg); 177 178 /** 179 * Submit a zone_append request to the bdev. 180 * 181 * \ingroup bdev_io_submit_functions 182 * 183 * \param desc Block device descriptor. 184 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 185 * \param buf Data buffer to written from. 186 * \param zone_id First logical block of a zone. 187 * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. 188 * \param cb Called when the request is complete. 189 * \param cb_arg Argument passed to cb. 190 * 191 * \return 0 on success. On success, the callback will always 192 * be called (even if the request ultimately failed). 193 * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). 194 * Return negated errno on failure, in which case the callback will not be called. 195 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 196 */ 197 int spdk_bdev_zone_append(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 198 void *buf, uint64_t zone_id, uint64_t num_blocks, 199 spdk_bdev_io_completion_cb cb, void *cb_arg); 200 201 /** 202 * Submit a zone_append request to the bdev. This differs from 203 * spdk_bdev_zone_append by allowing the data buffer to be described in a scatter 204 * gather list. 205 * 206 * \ingroup bdev_io_submit_functions 207 * 208 * \param desc Block device descriptor. 209 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 210 * \param iov A scatter gather list of buffers to be written from. 211 * \param iovcnt The number of elements in iov. 212 * \param zone_id First logical block of a zone. 213 * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. 214 * \param cb Called when the request is complete. 215 * \param cb_arg Argument passed to cb. 216 * 217 * \return 0 on success. On success, the callback will always 218 * be called (even if the request ultimately failed). 219 * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). 220 * Return negated errno on failure, in which case the callback will not be called. 221 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 222 */ 223 int spdk_bdev_zone_appendv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 224 struct iovec *iov, int iovcnt, uint64_t zone_id, uint64_t num_blocks, 225 spdk_bdev_io_completion_cb cb, void *cb_arg); 226 227 /** 228 * Submit a zone_append request with metadata to the bdev. 229 * 230 * This function uses separate buffer for metadata transfer (valid only if bdev supports this 231 * mode). 232 * 233 * \ingroup bdev_io_submit_functions 234 * 235 * \param desc Block device descriptor. 236 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 237 * \param buf Data buffer to written from. 238 * \param md Metadata buffer. 239 * \param zone_id First logical block of a zone. 240 * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. 241 * \param cb Called when the request is complete. 242 * \param cb_arg Argument passed to cb. 243 * 244 * \return 0 on success. On success, the callback will always 245 * be called (even if the request ultimately failed). 246 * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). 247 * Return negated errno on failure, in which case the callback will not be called. 248 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 249 */ 250 int spdk_bdev_zone_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 251 void *buf, void *md, uint64_t zone_id, uint64_t num_blocks, 252 spdk_bdev_io_completion_cb cb, void *cb_arg); 253 254 /** 255 * Submit a zone_append request with metadata to the bdev. This differs from 256 * spdk_bdev_zone_append by allowing the data buffer to be described in a scatter 257 * gather list. 258 * 259 * This function uses separate buffer for metadata transfer (valid only if bdev supports this 260 * mode). 261 * 262 * \ingroup bdev_io_submit_functions 263 * 264 * \param desc Block device descriptor. 265 * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). 266 * \param iov A scatter gather list of buffers to be written from. 267 * \param iovcnt The number of elements in iov. 268 * \param md Metadata buffer. 269 * \param zone_id First logical block of a zone. 270 * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. 271 * \param cb Called when the request is complete. 272 * \param cb_arg Argument passed to cb. 273 * 274 * \return 0 on success. On success, the callback will always 275 * be called (even if the request ultimately failed). 276 * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). 277 * Return negated errno on failure, in which case the callback will not be called. 278 * * -ENOMEM - spdk_bdev_io buffer cannot be allocated 279 */ 280 int spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 281 struct iovec *iov, int iovcnt, void *md, uint64_t zone_id, 282 uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 283 void *cb_arg); 284 285 /** 286 * Get append location (offset in blocks of the bdev) for this I/O. 287 * 288 * \param bdev_io I/O to get append location from. 289 */ 290 uint64_t spdk_bdev_io_get_append_location(struct spdk_bdev_io *bdev_io); 291 292 #ifdef __cplusplus 293 } 294 #endif 295 296 #endif /* SPDK_BDEV_ZONE_H */ 297