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:
parent
6defafc913
commit
67bb33160a
@ -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);
|
return !spdk_blob_is_read_only(lvol->blob);
|
||||||
case SPDK_BDEV_IO_TYPE_RESET:
|
case SPDK_BDEV_IO_TYPE_RESET:
|
||||||
case SPDK_BDEV_IO_TYPE_READ:
|
case SPDK_BDEV_IO_TYPE_READ:
|
||||||
|
case SPDK_BDEV_IO_TYPE_SEEK_DATA:
|
||||||
|
case SPDK_BDEV_IO_TYPE_SEEK_HOLE:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
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);
|
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
|
static void
|
||||||
lvol_write_zeroes(struct spdk_lvol *lvol, struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io)
|
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:
|
case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
|
||||||
lvol_write_zeroes(lvol, ch, bdev_io);
|
lvol_write_zeroes(lvol, ch, bdev_io);
|
||||||
break;
|
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:
|
default:
|
||||||
SPDK_INFOLOG(vbdev_lvol, "lvol: unsupported I/O type %d\n", bdev_io->type);
|
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);
|
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
|
||||||
|
@ -169,6 +169,33 @@ spdk_blob_get_num_clusters(struct spdk_blob *b)
|
|||||||
return 0;
|
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
|
int
|
||||||
spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
|
spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
|
||||||
size_t *count)
|
size_t *count)
|
||||||
@ -1347,6 +1374,10 @@ ut_vbdev_lvol_io_type_supported(void)
|
|||||||
CU_ASSERT(ret == true);
|
CU_ASSERT(ret == true);
|
||||||
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
|
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
|
||||||
CU_ASSERT(ret == true);
|
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 */
|
/* Unsupported types */
|
||||||
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_FLUSH);
|
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);
|
CU_ASSERT(ret == true);
|
||||||
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
|
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_RESET);
|
||||||
CU_ASSERT(ret == true);
|
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 */
|
/* Unsupported types */
|
||||||
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
|
ret = vbdev_lvol_io_type_supported(lvol, SPDK_BDEV_IO_TYPE_WRITE);
|
||||||
@ -1495,6 +1530,48 @@ ut_lvs_rename(void)
|
|||||||
free(g_base_bdev);
|
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
|
int
|
||||||
main(int argc, char **argv)
|
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_lvol_rename);
|
||||||
CU_ADD_TEST(suite, ut_bdev_finish);
|
CU_ADD_TEST(suite, ut_bdev_finish);
|
||||||
CU_ADD_TEST(suite, ut_lvs_rename);
|
CU_ADD_TEST(suite, ut_lvs_rename);
|
||||||
|
CU_ADD_TEST(suite, ut_lvol_seek);
|
||||||
|
|
||||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||||
CU_basic_run_tests();
|
CU_basic_run_tests();
|
||||||
|
Loading…
Reference in New Issue
Block a user