vbdev_lvol: Implement SEEK_[DATA,HOLE] io type

Two functions have been added to implement bdev io type
SEEK_DATA and SEEK_HOLE. Blob functions to find next
[un]allocated io_unit are used

Signed-off-by: Damiano Cipriani <damiano.cipriani@suse.com>
Change-Id: Ic3be3c0c86bd3010a23ba2681f0f00c62abcaaba
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14362
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Damiano Cipriani 2022-09-05 15:22:18 +02:00 committed by Tomasz Zawadzki
parent 6defafc913
commit 67bb33160a
2 changed files with 104 additions and 0 deletions

View File

@ -765,6 +765,8 @@ vbdev_lvol_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
return !spdk_blob_is_read_only(lvol->blob);
case SPDK_BDEV_IO_TYPE_RESET:
case SPDK_BDEV_IO_TYPE_READ:
case SPDK_BDEV_IO_TYPE_SEEK_DATA:
case SPDK_BDEV_IO_TYPE_SEEK_HOLE:
return true;
default:
return false;
@ -800,6 +802,24 @@ lvol_unmap(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_
spdk_blob_io_unmap(blob, ch, start_page, num_pages, lvol_op_comp, bdev_io);
}
static void
lvol_seek_data(struct spdk_lvol *lvol, struct spdk_bdev_io *bdev_io)
{
bdev_io->u.bdev.seek.offset = spdk_blob_get_next_allocated_io_unit(lvol->blob,
bdev_io->u.bdev.offset_blocks);
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
}
static void
lvol_seek_hole(struct spdk_lvol *lvol, struct spdk_bdev_io *bdev_io)
{
bdev_io->u.bdev.seek.offset = spdk_blob_get_next_unallocated_io_unit(lvol->blob,
bdev_io->u.bdev.offset_blocks);
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
}
static void
lvol_write_zeroes(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
{
@ -910,6 +930,12 @@ vbdev_lvol_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_
case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
lvol_write_zeroes(lvol, ch, bdev_io);
break;
case SPDK_BDEV_IO_TYPE_SEEK_DATA:
lvol_seek_data(lvol, bdev_io);
break;
case SPDK_BDEV_IO_TYPE_SEEK_HOLE:
lvol_seek_hole(lvol, bdev_io);
break;
default:
SPDK_INFOLOG(vbdev_lvol, "lvol: unsupported I/O type %d\n", bdev_io->type);
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);

View File

@ -169,6 +169,33 @@ spdk_blob_get_num_clusters(struct spdk_blob *b)
return 0;
}
/* Simulation of a blob with:
* - 1 io_unit per cluster
* - 20 data cluster
* - only last cluster allocated
*/
uint64_t g_blob_allocated_io_unit_offset = 20;
uint64_t
spdk_blob_get_next_allocated_io_unit(struct spdk_blob *blob, uint64_t offset)
{
if (offset <= g_blob_allocated_io_unit_offset) {
return g_blob_allocated_io_unit_offset;
} else {
return UINT64_MAX;
}
}
uint64_t
spdk_blob_get_next_unallocated_io_unit(struct spdk_blob *blob, uint64_t offset)
{
if (offset < g_blob_allocated_io_unit_offset) {
return offset;
} else {
return UINT64_MAX;
}
}
int
spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
size_t *count)
@ -1347,6 +1374,10 @@ ut_vbdev_lvol_io_type_supported(void)
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_DATA);
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_HOLE);
CU_ASSERT(ret == true);
/* Unsupported types */
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
@ -1363,6 +1394,10 @@ ut_vbdev_lvol_io_type_supported(void)
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_DATA);
CU_ASSERT(ret == true);
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_SEEK_HOLE);
CU_ASSERT(ret == true);
/* Unsupported types */
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
@ -1495,6 +1530,48 @@ ut_lvs_rename(void)
free(g_base_bdev);
}
static void
ut_lvol_seek(void)
{
g_io = calloc(1, sizeof(struct spdk_bdev_io) + vbdev_lvs_get_ctx_size());
SPDK_CU_ASSERT_FATAL(g_io != NULL);
g_base_bdev = calloc(1, sizeof(struct spdk_bdev));
SPDK_CU_ASSERT_FATAL(g_base_bdev != NULL);
g_lvol = calloc(1, sizeof(struct spdk_lvol));
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
g_io->bdev = g_base_bdev;
g_io->bdev->ctxt = g_lvol;
/* Data found */
g_io->u.bdev.offset_blocks = 10;
lvol_seek_data(g_lvol, g_io);
CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
CU_ASSERT(g_io->u.bdev.seek.offset == g_blob_allocated_io_unit_offset);
/* Data not found */
g_io->u.bdev.offset_blocks = 30;
lvol_seek_data(g_lvol, g_io);
CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
CU_ASSERT(g_io->u.bdev.seek.offset == UINT64_MAX);
/* Hole found */
g_io->u.bdev.offset_blocks = 10;
lvol_seek_hole(g_lvol, g_io);
CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
CU_ASSERT(g_io->u.bdev.seek.offset == 10);
/* Hole not found */
g_io->u.bdev.offset_blocks = 30;
lvol_seek_hole(g_lvol, g_io);
CU_ASSERT(g_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
CU_ASSERT(g_io->u.bdev.seek.offset == UINT64_MAX);
free(g_io);
free(g_base_bdev);
free(g_lvol);
}
int
main(int argc, char **argv)
{
@ -1523,6 +1600,7 @@ main(int argc, char **argv)
CU_ADD_TEST(suite, ut_lvol_rename);
CU_ADD_TEST(suite, ut_bdev_finish);
CU_ADD_TEST(suite, ut_lvs_rename);
CU_ADD_TEST(suite, ut_lvol_seek);
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();