xref: /spdk/lib/bdev/bdev_zone.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
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