Add zoned storage support to ublk: report_zones and operations: - REQ_OP_ZONE_OPEN - REQ_OP_ZONE_CLOSE - REQ_OP_ZONE_FINISH - REQ_OP_ZONE_RESET - REQ_OP_ZONE_APPEND The zone append feature uses the `addr` field of `struct ublksrv_io_cmd` to communicate ALBA back to the kernel. Therefore ublk must be used with the user copy feature (UBLK_F_USER_COPY) for zoned storage support to be available. Without this feature, ublk will not allow zoned storage support.
Showing the changes to include/uapi (1 of 2 files). Show all
Unified · Split
| @@ -176,6 +176,12 @@ · 175 unmodified lines | ||
| 176 | 176 | /* Copy between request and user buffer by pread()/pwrite() */ |
| 177 | 177 | #define UBLK_F_USER_COPY (1UL << 7) |
| 178 | 178 | |
| 179 | +/* | |
| 180 | + * User space sets this flag when setting up the device to request zoned storage support. Kernel may | |
| 181 | + * deny the request by returning an error. | |
| 182 | + */ | |
| 183 | +#define UBLK_F_ZONED (1ULL << 8) | |
| 184 | + | |
| 179 | 185 | /* device state */ |
| 180 | 186 | #define UBLK_S_DEV_DEAD 0 |
| 181 | 187 | #define UBLK_S_DEV_LIVE 1 |
| @@ -232,9 +238,26 @@ struct ublksrv_ctrl_dev_info { · 50 unmodified lines | ||
| 232 | 238 | #define UBLK_IO_OP_READ 0 |
| 233 | 239 | #define UBLK_IO_OP_WRITE 1 |
| 234 | 240 | #define UBLK_IO_OP_FLUSH 2 |
| 235 | −#define UBLK_IO_OP_DISCARD 3 | |
| 236 | −#define UBLK_IO_OP_WRITE_SAME 4 | |
| 237 | −#define UBLK_IO_OP_WRITE_ZEROES 5 | |
| 241 | +#define UBLK_IO_OP_DISCARD 3 | |
| 242 | +#define UBLK_IO_OP_WRITE_SAME 4 | |
| 243 | +#define UBLK_IO_OP_WRITE_ZEROES 5 | |
| 244 | +#define UBLK_IO_OP_ZONE_OPEN 10 | |
| 245 | +#define UBLK_IO_OP_ZONE_CLOSE 11 | |
| 246 | +#define UBLK_IO_OP_ZONE_FINISH 12 | |
| 247 | +#define UBLK_IO_OP_ZONE_APPEND 13 | |
| 248 | +#define UBLK_IO_OP_ZONE_RESET 15 | |
| 249 | +/* | |
| 250 | + * Construct a zone report. The report request is carried in `struct | |
| 251 | + * ublksrv_io_desc`. The `start_sector` field must be the first sector of a zone | |
| 252 | + * and shall indicate the first zone of the report. The `nr_zones` shall | |
| 253 | + * indicate how many zones should be reported at most. The report shall be | |
| 254 | + * delivered as a `struct blk_zone` array. To report fewer zones than requested, | |
| 255 | + * zero the last entry of the returned array. | |
| 256 | + * | |
| 257 | + * Related definitions(blk_zone, blk_zone_cond, blk_zone_type, ...) in | |
| 258 | + * include/uapi/linux/blkzoned.h are part of ublk UAPI. | |
| 259 | + */ | |
| 260 | +#define UBLK_IO_OP_REPORT_ZONES 18 | |
| 238 | 261 | |
| 239 | 262 | #define UBLK_IO_F_FAILFAST_DEV (1U << 8) |
| 240 | 263 | #define UBLK_IO_F_FAILFAST_TRANSPORT (1U << 9) |
| @@ -255,7 +278,10 @@ struct ublksrv_io_desc { · 14 unmodified lines | ||
| 255 | 278 | /* op: bit 0-7, flags: bit 8-31 */ |
| 256 | 279 | __u32 op_flags; |
| 257 | 280 | |
| 258 | − __u32 nr_sectors; | |
| 281 | + union { | |
| 282 | + __u32 nr_sectors; | |
| 283 | + __u32 nr_zones; /* for UBLK_IO_OP_REPORT_ZONES */ | |
| 284 | + }; | |
| 259 | 285 | |
| 260 | 286 | /* start sector for this io */ |
| 261 | 287 | __u64 start_sector; |
| @@ -284,11 +310,21 @@ struct ublksrv_io_cmd { · 22 unmodified lines | ||
| 284 | 310 | /* io result, it is valid for COMMIT* command only */ |
| 285 | 311 | __s32 result; |
| 286 | 312 | |
| 287 | − /* | |
| 288 | − * userspace buffer address in ublksrv daemon process, valid for | |
| 289 | − * FETCH* command only | |
| 290 | − */ | |
| 291 | − __u64 addr; | |
| 313 | + union { | |
| 314 | + /* | |
| 315 | + * userspace buffer address in ublksrv daemon process, valid for | |
| 316 | + * FETCH* command only | |
| 317 | + * | |
| 318 | + * `addr` should not be used when UBLK_F_USER_COPY is enabled, | |
| 319 | + * because userspace handles data copy by pread()/pwrite() over | |
| 320 | + * /dev/ublkcN. But in case of UBLK_F_ZONED, this union is | |
| 321 | + * re-used to pass back the allocated LBA for | |
| 322 | + * UBLK_IO_OP_ZONE_APPEND which actually depends on | |
| 323 | + * UBLK_F_USER_COPY | |
| 324 | + */ | |
| 325 | + __u64 addr; | |
| 326 | + __u64 zone_append_lba; | |
| 327 | + }; | |
| 292 | 328 | }; |
| 293 | 329 | |
| 294 | 330 | struct ublk_param_basic { |
| @@ -331,6 +367,13 @@ struct ublk_param_devt { · 36 unmodified lines | ||
| 331 | 367 | __u32 disk_minor; |
| 332 | 368 | }; |
| 333 | 369 | |
| 370 | +struct ublk_param_zoned { | |
| 371 | + __u32 max_open_zones; | |
| 372 | + __u32 max_active_zones; | |
| 373 | + __u32 max_zone_append_sectors; | |
| 374 | + __u8 reserved[20]; | |
| 375 | +}; | |
| 376 | + | |
| 334 | 377 | struct ublk_params { |
| 335 | 378 | /* |
| 336 | 379 | * Total length of parameters, userspace has to set 'len' for both |
| @@ -342,11 +385,13 @@ struct ublk_params { · 5 unmodified lines | ||
| 342 | 385 | #define UBLK_PARAM_TYPE_BASIC (1 << 0) |
| 343 | 386 | #define UBLK_PARAM_TYPE_DISCARD (1 << 1) |
| 344 | 387 | #define UBLK_PARAM_TYPE_DEVT (1 << 2) |
| 388 | +#define UBLK_PARAM_TYPE_ZONED (1 << 3) | |
| 345 | 389 | __u32 types; /* types of parameter included */ |
| 346 | 390 | |
| 347 | 391 | struct ublk_param_basic basic; |
| 348 | 392 | struct ublk_param_discard discard; |
| 349 | 393 | struct ublk_param_devt devt; |
| 394 | + struct ublk_param_zoned zoned; | |
| 350 | 395 | }; |
| 351 | 396 | |
| 352 | 397 | #endif |