Commit 67bb3316 authored by Damiano Cipriani's avatar Damiano Cipriani Committed by Tomasz Zawadzki
Browse files

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: default avatarDamiano Cipriani <damiano.cipriani@suse.com>
Change-Id: Ic3be3c0c86bd3010a23ba2681f0f00c62abcaaba
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14362


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 6defafc9
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -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);
+78 −0
Original line number Diff line number Diff line
@@ -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();