1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2*a6dbe372Spaul luse * Copyright (C) 2019 Intel Corporation.
3aa35048dSWojciech Malikowski * All rights reserved.
4aa35048dSWojciech Malikowski */
5aa35048dSWojciech Malikowski
6aa35048dSWojciech Malikowski #include "spdk/stdinc.h"
7aa35048dSWojciech Malikowski
8aa35048dSWojciech Malikowski #include "spdk/bdev_zone.h"
9aa35048dSWojciech Malikowski #include "spdk/bdev_module.h"
10b7ad5b0bSNiklas Cassel #include "spdk/likely.h"
11aa35048dSWojciech Malikowski
1202cabd9eSWojciech Malikowski #include "bdev_internal.h"
1302cabd9eSWojciech Malikowski
14aa35048dSWojciech Malikowski uint64_t
spdk_bdev_get_zone_size(const struct spdk_bdev * bdev)15aa35048dSWojciech Malikowski spdk_bdev_get_zone_size(const struct spdk_bdev *bdev)
16aa35048dSWojciech Malikowski {
17aa35048dSWojciech Malikowski return bdev->zone_size;
18aa35048dSWojciech Malikowski }
19aa35048dSWojciech Malikowski
200859db6bSNiklas Cassel uint64_t
spdk_bdev_get_num_zones(const struct spdk_bdev * bdev)210859db6bSNiklas Cassel spdk_bdev_get_num_zones(const struct spdk_bdev *bdev)
220859db6bSNiklas Cassel {
230859db6bSNiklas Cassel return bdev->zone_size ? bdev->blockcnt / bdev->zone_size : 0;
240859db6bSNiklas Cassel }
250859db6bSNiklas Cassel
26b7ad5b0bSNiklas Cassel uint64_t
spdk_bdev_get_zone_id(const struct spdk_bdev * bdev,uint64_t offset_blocks)27b7ad5b0bSNiklas Cassel spdk_bdev_get_zone_id(const struct spdk_bdev *bdev, uint64_t offset_blocks)
28b7ad5b0bSNiklas Cassel {
29b7ad5b0bSNiklas Cassel uint64_t zslba;
30b7ad5b0bSNiklas Cassel
31b7ad5b0bSNiklas Cassel if (spdk_likely(spdk_u64_is_pow2(bdev->zone_size))) {
32b7ad5b0bSNiklas Cassel uint64_t zone_mask = bdev->zone_size - 1;
33b7ad5b0bSNiklas Cassel zslba = offset_blocks & ~zone_mask;
34b7ad5b0bSNiklas Cassel } else {
35b7ad5b0bSNiklas Cassel /* integer division */
36b7ad5b0bSNiklas Cassel zslba = (offset_blocks / bdev->zone_size) * bdev->zone_size;
37b7ad5b0bSNiklas Cassel }
38b7ad5b0bSNiklas Cassel
39b7ad5b0bSNiklas Cassel return zslba;
40b7ad5b0bSNiklas Cassel }
41b7ad5b0bSNiklas Cassel
42aa35048dSWojciech Malikowski uint32_t
spdk_bdev_get_max_zone_append_size(const struct spdk_bdev * bdev)439f5852d0SNiklas Cassel spdk_bdev_get_max_zone_append_size(const struct spdk_bdev *bdev)
449f5852d0SNiklas Cassel {
459f5852d0SNiklas Cassel return bdev->max_zone_append_size;
469f5852d0SNiklas Cassel }
479f5852d0SNiklas Cassel
489f5852d0SNiklas Cassel uint32_t
spdk_bdev_get_max_open_zones(const struct spdk_bdev * bdev)49aa35048dSWojciech Malikowski spdk_bdev_get_max_open_zones(const struct spdk_bdev *bdev)
50aa35048dSWojciech Malikowski {
51aa35048dSWojciech Malikowski return bdev->max_open_zones;
52aa35048dSWojciech Malikowski }
53aa35048dSWojciech Malikowski
54aa35048dSWojciech Malikowski uint32_t
spdk_bdev_get_max_active_zones(const struct spdk_bdev * bdev)55ee4868deSNiklas Cassel spdk_bdev_get_max_active_zones(const struct spdk_bdev *bdev)
56ee4868deSNiklas Cassel {
57ee4868deSNiklas Cassel return bdev->max_active_zones;
58ee4868deSNiklas Cassel }
59ee4868deSNiklas Cassel
60ee4868deSNiklas Cassel uint32_t
spdk_bdev_get_optimal_open_zones(const struct spdk_bdev * bdev)61aa35048dSWojciech Malikowski spdk_bdev_get_optimal_open_zones(const struct spdk_bdev *bdev)
62aa35048dSWojciech Malikowski {
63aa35048dSWojciech Malikowski return bdev->optimal_open_zones;
64aa35048dSWojciech Malikowski }
6502cabd9eSWojciech Malikowski
6602cabd9eSWojciech Malikowski int
spdk_bdev_get_zone_info(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t zone_id,size_t num_zones,struct spdk_bdev_zone_info * info,spdk_bdev_io_completion_cb cb,void * cb_arg)6702cabd9eSWojciech Malikowski spdk_bdev_get_zone_info(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
6802cabd9eSWojciech Malikowski uint64_t zone_id, size_t num_zones, struct spdk_bdev_zone_info *info,
6902cabd9eSWojciech Malikowski spdk_bdev_io_completion_cb cb, void *cb_arg)
7002cabd9eSWojciech Malikowski {
7102cabd9eSWojciech Malikowski struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
7202cabd9eSWojciech Malikowski struct spdk_bdev_io *bdev_io;
7302cabd9eSWojciech Malikowski struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
7402cabd9eSWojciech Malikowski
75fdfb4e12SJim Harris bdev_io = bdev_channel_get_io(channel);
7602cabd9eSWojciech Malikowski if (!bdev_io) {
7702cabd9eSWojciech Malikowski return -ENOMEM;
7802cabd9eSWojciech Malikowski }
7902cabd9eSWojciech Malikowski
8002cabd9eSWojciech Malikowski bdev_io->internal.ch = channel;
8102cabd9eSWojciech Malikowski bdev_io->internal.desc = desc;
8202cabd9eSWojciech Malikowski bdev_io->type = SPDK_BDEV_IO_TYPE_GET_ZONE_INFO;
8302cabd9eSWojciech Malikowski bdev_io->u.zone_mgmt.zone_id = zone_id;
8402cabd9eSWojciech Malikowski bdev_io->u.zone_mgmt.num_zones = num_zones;
8502cabd9eSWojciech Malikowski bdev_io->u.zone_mgmt.buf = info;
86a1d68e9cSJim Harris bdev_io_init(bdev_io, bdev, cb_arg, cb);
8702cabd9eSWojciech Malikowski
886c07e9d1SJim Harris bdev_io_submit(bdev_io);
8902cabd9eSWojciech Malikowski return 0;
9002cabd9eSWojciech Malikowski }
912b16dcc7SWojciech Malikowski
922b16dcc7SWojciech Malikowski int
spdk_bdev_zone_management(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,uint64_t zone_id,enum spdk_bdev_zone_action action,spdk_bdev_io_completion_cb cb,void * cb_arg)932b16dcc7SWojciech Malikowski spdk_bdev_zone_management(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
942b16dcc7SWojciech Malikowski uint64_t zone_id, enum spdk_bdev_zone_action action,
952b16dcc7SWojciech Malikowski spdk_bdev_io_completion_cb cb, void *cb_arg)
962b16dcc7SWojciech Malikowski {
972b16dcc7SWojciech Malikowski struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
982b16dcc7SWojciech Malikowski struct spdk_bdev_io *bdev_io;
992b16dcc7SWojciech Malikowski struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
1002b16dcc7SWojciech Malikowski
101fdfb4e12SJim Harris bdev_io = bdev_channel_get_io(channel);
1022b16dcc7SWojciech Malikowski if (!bdev_io) {
1032b16dcc7SWojciech Malikowski return -ENOMEM;
1042b16dcc7SWojciech Malikowski }
1052b16dcc7SWojciech Malikowski
1062b16dcc7SWojciech Malikowski bdev_io->internal.ch = channel;
1072b16dcc7SWojciech Malikowski bdev_io->internal.desc = desc;
1082b16dcc7SWojciech Malikowski bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT;
1092b16dcc7SWojciech Malikowski bdev_io->u.zone_mgmt.zone_action = action;
1102b16dcc7SWojciech Malikowski bdev_io->u.zone_mgmt.zone_id = zone_id;
1112b16dcc7SWojciech Malikowski bdev_io->u.zone_mgmt.num_zones = 1;
112a1d68e9cSJim Harris bdev_io_init(bdev_io, bdev, cb_arg, cb);
1132b16dcc7SWojciech Malikowski
1146c07e9d1SJim Harris bdev_io_submit(bdev_io);
1152b16dcc7SWojciech Malikowski return 0;
1162b16dcc7SWojciech Malikowski }
117a9e6fadfSWojciech Malikowski
11845b5808eSWojciech Malikowski static int
zone_bdev_append_with_md(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,void * buf,void * md_buf,uint64_t zone_id,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)119d145b977SSeth Howell zone_bdev_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
12045b5808eSWojciech Malikowski void *buf, void *md_buf, uint64_t zone_id, uint64_t num_blocks,
12145b5808eSWojciech Malikowski spdk_bdev_io_completion_cb cb, void *cb_arg)
12245b5808eSWojciech Malikowski {
12345b5808eSWojciech Malikowski struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
12445b5808eSWojciech Malikowski struct spdk_bdev_io *bdev_io;
12545b5808eSWojciech Malikowski struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
12645b5808eSWojciech Malikowski
127fdfb4e12SJim Harris bdev_io = bdev_channel_get_io(channel);
12845b5808eSWojciech Malikowski if (!bdev_io) {
12945b5808eSWojciech Malikowski return -ENOMEM;
13045b5808eSWojciech Malikowski }
13145b5808eSWojciech Malikowski
13245b5808eSWojciech Malikowski bdev_io->internal.ch = channel;
13345b5808eSWojciech Malikowski bdev_io->internal.desc = desc;
13445b5808eSWojciech Malikowski bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
13545b5808eSWojciech Malikowski bdev_io->u.bdev.iovs = &bdev_io->iov;
13645b5808eSWojciech Malikowski bdev_io->u.bdev.iovs[0].iov_base = buf;
13745b5808eSWojciech Malikowski bdev_io->u.bdev.iovs[0].iov_len = num_blocks * bdev->blocklen;
13845b5808eSWojciech Malikowski bdev_io->u.bdev.iovcnt = 1;
13945b5808eSWojciech Malikowski bdev_io->u.bdev.md_buf = md_buf;
14045b5808eSWojciech Malikowski bdev_io->u.bdev.num_blocks = num_blocks;
14145b5808eSWojciech Malikowski bdev_io->u.bdev.offset_blocks = zone_id;
142a1d68e9cSJim Harris bdev_io_init(bdev_io, bdev, cb_arg, cb);
14345b5808eSWojciech Malikowski
1446c07e9d1SJim Harris bdev_io_submit(bdev_io);
14545b5808eSWojciech Malikowski return 0;
14645b5808eSWojciech Malikowski }
14745b5808eSWojciech Malikowski
14845b5808eSWojciech Malikowski int
spdk_bdev_zone_append(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,void * buf,uint64_t start_lba,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)14945b5808eSWojciech Malikowski spdk_bdev_zone_append(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
15045b5808eSWojciech Malikowski void *buf, uint64_t start_lba, uint64_t num_blocks,
15145b5808eSWojciech Malikowski spdk_bdev_io_completion_cb cb, void *cb_arg)
15245b5808eSWojciech Malikowski {
153d145b977SSeth Howell return zone_bdev_append_with_md(desc, ch, buf, NULL, start_lba, num_blocks,
15445b5808eSWojciech Malikowski cb, cb_arg);
15545b5808eSWojciech Malikowski }
15645b5808eSWojciech Malikowski
15745b5808eSWojciech Malikowski int
spdk_bdev_zone_append_with_md(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,void * buf,void * md,uint64_t start_lba,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)15845b5808eSWojciech Malikowski spdk_bdev_zone_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
15945b5808eSWojciech Malikowski void *buf, void *md, uint64_t start_lba, uint64_t num_blocks,
16045b5808eSWojciech Malikowski spdk_bdev_io_completion_cb cb, void *cb_arg)
16145b5808eSWojciech Malikowski {
162d145b977SSeth Howell return zone_bdev_append_with_md(desc, ch, buf, md, start_lba, num_blocks,
16345b5808eSWojciech Malikowski cb, cb_arg);
16445b5808eSWojciech Malikowski }
16545b5808eSWojciech Malikowski
16626f39f1eSKonrad Sztyber int
spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iov,int iovcnt,void * md_buf,uint64_t zone_id,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)16726f39f1eSKonrad Sztyber spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
16826f39f1eSKonrad Sztyber struct iovec *iov, int iovcnt, void *md_buf, uint64_t zone_id,
16926f39f1eSKonrad Sztyber uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
17026f39f1eSKonrad Sztyber void *cb_arg)
17126f39f1eSKonrad Sztyber {
17226f39f1eSKonrad Sztyber struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
17326f39f1eSKonrad Sztyber struct spdk_bdev_io *bdev_io;
17426f39f1eSKonrad Sztyber struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
17526f39f1eSKonrad Sztyber
17626f39f1eSKonrad Sztyber bdev_io = bdev_channel_get_io(channel);
17726f39f1eSKonrad Sztyber if (!bdev_io) {
17826f39f1eSKonrad Sztyber return -ENOMEM;
17926f39f1eSKonrad Sztyber }
18026f39f1eSKonrad Sztyber
18126f39f1eSKonrad Sztyber bdev_io->internal.ch = channel;
18226f39f1eSKonrad Sztyber bdev_io->internal.desc = desc;
18326f39f1eSKonrad Sztyber bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND;
18426f39f1eSKonrad Sztyber bdev_io->u.bdev.iovs = iov;
18526f39f1eSKonrad Sztyber bdev_io->u.bdev.iovcnt = iovcnt;
18626f39f1eSKonrad Sztyber bdev_io->u.bdev.md_buf = md_buf;
18726f39f1eSKonrad Sztyber bdev_io->u.bdev.num_blocks = num_blocks;
18826f39f1eSKonrad Sztyber bdev_io->u.bdev.offset_blocks = zone_id;
18926f39f1eSKonrad Sztyber bdev_io_init(bdev_io, bdev, cb_arg, cb);
19026f39f1eSKonrad Sztyber
19126f39f1eSKonrad Sztyber bdev_io_submit(bdev_io);
19226f39f1eSKonrad Sztyber return 0;
19326f39f1eSKonrad Sztyber }
19426f39f1eSKonrad Sztyber
19526f39f1eSKonrad Sztyber int
spdk_bdev_zone_appendv(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,struct iovec * iovs,int iovcnt,uint64_t zone_id,uint64_t num_blocks,spdk_bdev_io_completion_cb cb,void * cb_arg)19626f39f1eSKonrad Sztyber spdk_bdev_zone_appendv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
19726f39f1eSKonrad Sztyber struct iovec *iovs, int iovcnt, uint64_t zone_id, uint64_t num_blocks,
19826f39f1eSKonrad Sztyber spdk_bdev_io_completion_cb cb, void *cb_arg)
19926f39f1eSKonrad Sztyber {
20026f39f1eSKonrad Sztyber return spdk_bdev_zone_appendv_with_md(desc, ch, iovs, iovcnt, NULL, zone_id, num_blocks,
20126f39f1eSKonrad Sztyber cb, cb_arg);
20226f39f1eSKonrad Sztyber }
20326f39f1eSKonrad Sztyber
204a9e6fadfSWojciech Malikowski uint64_t
spdk_bdev_io_get_append_location(struct spdk_bdev_io * bdev_io)205a9e6fadfSWojciech Malikowski spdk_bdev_io_get_append_location(struct spdk_bdev_io *bdev_io)
206a9e6fadfSWojciech Malikowski {
207a9e6fadfSWojciech Malikowski return bdev_io->u.bdev.offset_blocks;
208a9e6fadfSWojciech Malikowski }
209