bdev/zone: Add finish zone handling to zoned vbdev

Handle finish zone management function to zoned block vbdev

Signed-off-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com>
Change-Id: Iffe24572609e741a79b6bb92f72b56cede4906ca
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468041
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
Mateusz Kozlowski 2019-09-13 16:15:31 +02:00 committed by Tomasz Zawadzki
parent 011cc5d61c
commit 68c3a79a15
2 changed files with 84 additions and 1 deletions

View File

@ -307,6 +307,19 @@ zone_block_close_zone(struct block_zone *zone, struct spdk_bdev_io *bdev_io)
}
}
static int
zone_block_finish_zone(struct block_zone *zone, struct spdk_bdev_io *bdev_io)
{
pthread_spin_lock(&zone->lock);
zone->zone_info.write_pointer = zone->zone_info.zone_id + zone->zone_info.capacity;
zone->zone_info.state = SPDK_BDEV_ZONE_STATE_FULL;
pthread_spin_unlock(&zone->lock);
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
return 0;
}
static int
zone_block_zone_management(struct bdev_zone_block *bdev_node, struct zone_block_io_channel *ch,
struct spdk_bdev_io *bdev_io)
@ -325,6 +338,8 @@ zone_block_zone_management(struct bdev_zone_block *bdev_node, struct zone_block_
return zone_block_open_zone(zone, bdev_io);
case SPDK_BDEV_ZONE_CLOSE:
return zone_block_close_zone(zone, bdev_io);
case SPDK_BDEV_ZONE_FINISH:
return zone_block_finish_zone(zone, bdev_io);
default:
return -EINVAL;
}

View File

@ -948,6 +948,13 @@ send_close_zone(struct bdev_zone_block *bdev, struct spdk_io_channel *ch, uint64
send_zone_management(bdev, ch, zone_id, output_index, SPDK_BDEV_ZONE_CLOSE, success);
}
static void
send_finish_zone(struct bdev_zone_block *bdev, struct spdk_io_channel *ch, uint64_t zone_id,
uint32_t output_index, bool success)
{
send_zone_management(bdev, ch, zone_id, output_index, SPDK_BDEV_ZONE_FINISH, success);
}
static void
test_reset_zone(void)
{
@ -1299,6 +1306,66 @@ test_close_zone(void)
test_cleanup();
}
static void
test_finish_zone(void)
{
struct spdk_io_channel *ch;
struct bdev_zone_block *bdev;
char *name = "Nvme0n1";
uint32_t num_zones = 20;
uint64_t zone_id, wp;
uint32_t output_index = 0;
init_test_globals(20 * 1024ul);
CU_ASSERT(zone_block_init() == 0);
/* Create zone dev */
bdev = create_and_get_vbdev("zone_dev1", name, num_zones, 1, true);
ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct zone_block_io_channel));
SPDK_CU_ASSERT_FATAL(ch != NULL);
/* Reset an unused zone */
send_reset_zone(bdev, ch, bdev->bdev.zone_size, output_index, true);
/* Finish a full zone */
zone_id = 0;
wp = bdev->bdev.zone_size;
send_finish_zone(bdev, ch, zone_id, output_index, true);
send_zone_info(bdev, ch, zone_id, wp, SPDK_BDEV_ZONE_STATE_FULL, output_index, true);
/* Finish an empty zone */
send_reset_zone(bdev, ch, zone_id, output_index, true);
send_finish_zone(bdev, ch, zone_id, output_index, true);
send_zone_info(bdev, ch, zone_id, wp, SPDK_BDEV_ZONE_STATE_FULL, output_index, true);
/* Finish an open zone */
send_reset_zone(bdev, ch, zone_id, output_index, true);
send_write_zone(bdev, ch, zone_id, 1, output_index, true);
send_finish_zone(bdev, ch, zone_id, output_index, true);
send_zone_info(bdev, ch, zone_id, wp, SPDK_BDEV_ZONE_STATE_FULL, output_index, true);
/* Send finish with misaligned LBA */
zone_id = 1;
send_finish_zone(bdev, ch, zone_id, output_index, false);
/* Send finish to non-existing zone */
zone_id = num_zones * bdev->bdev.zone_size;
send_finish_zone(bdev, ch, zone_id, output_index, false);
/* Make sure unused zone wasn't written to */
zone_id = bdev->bdev.zone_size;
send_zone_info(bdev, ch, zone_id, zone_id, SPDK_BDEV_ZONE_STATE_EMPTY, output_index, true);
/* Delete zone dev */
send_delete_vbdev("zone_dev1", true);
while (spdk_thread_poll(g_thread, 0, 0) > 0) {}
free(ch);
test_cleanup();
}
int main(int argc, char **argv)
{
CU_pSuite suite = NULL;
@ -1323,7 +1390,8 @@ int main(int argc, char **argv)
CU_add_test(suite, "test_open_zone", test_open_zone) == NULL ||
CU_add_test(suite, "test_zone_write", test_zone_write) == NULL ||
CU_add_test(suite, "test_zone_read", test_zone_read) == NULL ||
CU_add_test(suite, "test_close_zone", test_close_zone) == NULL
CU_add_test(suite, "test_close_zone", test_close_zone) == NULL ||
CU_add_test(suite, "test_finish_zone", test_finish_zone) == NULL
) {
CU_cleanup_registry();
return CU_get_error();