Commit 4210a752 authored by Damiano Cipriani's avatar Damiano Cipriani Committed by Tomasz Zawadzki
Browse files

vbdev_lvol: add shallow copy over a given bdev



This is mostly a wrapper around spdk_lvol_shallow_copy(), but it
also has the aim to create the spdk_bs_dev device from the given
bdev.

Change-Id: I180e6f64ca8025059665f99d0c507d15be61cef2
Signed-off-by: default avatarDamiano Cipriani <damiano.cipriani@suse.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19250


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent 24574350
Loading
Loading
Loading
Loading
+81 −0
Original line number Diff line number Diff line
@@ -1939,4 +1939,85 @@ fail:

/* End external snapshot support */

static void
_vbdev_lvol_shallow_copy_base_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
		void *event_ctx)
{
}

static void
_vbdev_lvol_shallow_copy_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_lvol_copy_req *req = cb_arg;
	struct spdk_lvol *lvol = req->lvol;

	if (lvolerrno != 0) {
		SPDK_ERRLOG("Could not make a shallow copy of lvol %s due to error: %d\n",
			    lvol->name, lvolerrno);
	}

	req->ext_dev->destroy(req->ext_dev);
	req->cb_fn(req->cb_arg, lvolerrno);
	free(req);
}

int
vbdev_lvol_shallow_copy(struct spdk_lvol *lvol, const char *bdev_name,
			spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg,
			spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	struct spdk_bs_dev *ext_dev;
	struct spdk_lvol_copy_req *req;
	int rc;

	if (lvol == NULL) {
		SPDK_ERRLOG("lvol must not be NULL\n");
		return -EINVAL;
	}

	if (bdev_name == NULL) {
		SPDK_ERRLOG("lvol %s, bdev name must not be NULL\n", lvol->name);
		return -EINVAL;
	}

	assert(lvol->bdev != NULL);

	req = calloc(1, sizeof(*req));
	if (req == NULL) {
		SPDK_ERRLOG("lvol %s, cannot alloc memory for lvol copy request\n", lvol->name);
		return -ENOMEM;
	}

	rc = spdk_bdev_create_bs_dev_ext(bdev_name, _vbdev_lvol_shallow_copy_base_bdev_event_cb,
					 NULL, &ext_dev);
	if (rc < 0) {
		SPDK_ERRLOG("lvol %s, cannot create blobstore block device from bdev %s\n", lvol->name, bdev_name);
		free(req);
		return rc;
	}

	rc = spdk_bs_bdev_claim(ext_dev, &g_lvol_if);
	if (rc != 0) {
		SPDK_ERRLOG("lvol %s, unable to claim bdev %s, error %d\n", lvol->name, bdev_name, rc);
		ext_dev->destroy(ext_dev);
		free(req);
		return rc;
	}

	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;
	req->lvol = lvol;
	req->ext_dev = ext_dev;

	rc = spdk_lvol_shallow_copy(lvol, ext_dev, status_cb_fn, status_cb_arg, _vbdev_lvol_shallow_copy_cb,
				    req);

	if (rc < 0) {
		ext_dev->destroy(ext_dev);
		free(req);
	}

	return rc;
}

SPDK_LOG_REGISTER_COMPONENT(vbdev_lvol)
+16 −0
Original line number Diff line number Diff line
@@ -116,4 +116,20 @@ int vbdev_lvol_esnap_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *
				const void *esnap_id, uint32_t id_len,
				struct spdk_bs_dev **_bs_dev);

/**
 * \brief Make a shallow copy of lvol over a bdev
 *
 * \param lvol Handle to lvol
 * \param bdev_name Name of the bdev to copy on
 * \param status_cb_fn Called repeatedly during operation with status updates
 * \param status_cb_arg Argument passed to function status_cb_fn.
 * \param cb_fn Completion callback
 * \param cb_arg Completion callback custom arguments
 *
 * \return 0 if operation starts correctly, negative errno on failure.
 */
int vbdev_lvol_shallow_copy(struct spdk_lvol *lvol, const char *bdev_name,
			    spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg,
			    spdk_lvol_op_complete cb_fn, void *cb_arg);

#endif /* SPDK_VBDEV_LVOL_H */
+77 −0
Original line number Diff line number Diff line
@@ -906,6 +906,23 @@ spdk_lvs_notify_hotplug(const void *esnap_id, uint32_t id_len,
	return g_bdev_is_missing;
}

int
spdk_lvol_shallow_copy(struct spdk_lvol *lvol, struct spdk_bs_dev *ext_dev,
		       spdk_blob_shallow_copy_status status_cb_fn, void *status_cb_arg,
		       spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	if (lvol == NULL) {
		return -ENODEV;
	}

	if (ext_dev == NULL) {
		return -ENODEV;
	}

	cb_fn(cb_arg, 0);
	return 0;
}

static void
lvol_store_op_complete(void *cb_arg, int lvserrno)
{
@@ -946,6 +963,12 @@ vbdev_lvol_rename_complete(void *cb_arg, int lvolerrno)
	g_lvolerrno = lvolerrno;
}

static void
vbdev_lvol_shallow_copy_complete(void *cb_arg, int lvolerrno)
{
	g_lvolerrno = lvolerrno;
}

static void
ut_lvs_destroy(void)
{
@@ -1952,6 +1975,59 @@ ut_lvol_esnap_clone_bad_args(void)
	g_base_bdev = NULL;
}

static void
ut_lvol_shallow_copy(void)
{
	struct spdk_lvol_store *lvs;
	int sz = 10;
	int rc;
	struct spdk_lvol *lvol = NULL;

	/* Lvol store is successfully created */
	rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
			      lvol_store_op_with_handle_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
	CU_ASSERT(g_lvol_store->bs_dev != NULL);
	lvs = g_lvol_store;

	/* Successful lvol create */
	g_lvolerrno = -1;
	rc = vbdev_lvol_create(lvs, "lvol_sc", sz, false, LVOL_CLEAR_WITH_DEFAULT,
			       vbdev_lvol_create_complete,
			       NULL);
	SPDK_CU_ASSERT_FATAL(rc == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
	CU_ASSERT(g_lvolerrno == 0);

	lvol = g_lvol;

	/* Shallow copy error with NULL lvol */
	rc = vbdev_lvol_shallow_copy(NULL, "", NULL, NULL, vbdev_lvol_shallow_copy_complete, NULL);
	CU_ASSERT(rc == -EINVAL);

	/* Shallow copy error with NULL bdev name */
	rc = vbdev_lvol_shallow_copy(lvol, NULL, NULL, NULL, vbdev_lvol_shallow_copy_complete, NULL);
	CU_ASSERT(rc == -EINVAL);

	/* Successful shallow copy */
	g_lvolerrno = -1;
	lvol_already_opened = false;
	rc = vbdev_lvol_shallow_copy(lvol, "bdev_sc", NULL, NULL, vbdev_lvol_shallow_copy_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvolerrno == 0);

	/* Successful lvol destroy */
	vbdev_lvol_destroy(g_lvol, lvol_store_op_complete, NULL);
	CU_ASSERT(g_lvol == NULL);

	/* Destroy lvol store */
	vbdev_lvs_destruct(lvs, lvol_store_op_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);
	CU_ASSERT(g_lvol_store == NULL);
}

int
main(int argc, char **argv)
{
@@ -1983,6 +2059,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, ut_lvol_seek);
	CU_ADD_TEST(suite, ut_esnap_dev_create);
	CU_ADD_TEST(suite, ut_lvol_esnap_clone_bad_args);
	CU_ADD_TEST(suite, ut_lvol_shallow_copy);

	allocate_threads(1);
	set_thread(0);