Commit 208748b4 authored by Maciej Szwed's avatar Maciej Szwed Committed by Daniel Verkamp
Browse files

lvol: Creating 2 lvols simultaneously with same name



This patch fixes issue where user creates 2 lvols
with the same name simultaneously. New solution
builds list of names of lvols that are currently
being created and when new request comes it compares
name against existing lvols and lvols that are in the
process of creation.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Change-Id: I31b59ee13b5b9bae531866925dd409b143f08ad4
Reviewed-on: https://review.gerrithub.io/407408


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 0629b01d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct spdk_lvol_store {
	int				lvols_opened;
	bool				destruct;
	TAILQ_HEAD(, spdk_lvol)		lvols;
	TAILQ_HEAD(, spdk_lvol)		pending_lvols;
	bool				on_list;
	TAILQ_ENTRY(spdk_lvol_store)	link;
	char				name[SPDK_LVS_NAME_MAX];
+15 −0
Original line number Diff line number Diff line
@@ -374,6 +374,7 @@ _spdk_lvs_load_cb(void *cb_arg, struct spdk_blob_store *bs, int lvolerrno)
	lvs->blobstore = bs;
	lvs->bs_dev = req->bs_dev;
	TAILQ_INIT(&lvs->lvols);
	TAILQ_INIT(&lvs->pending_lvols);

	req->lvol_store = lvs;

@@ -535,6 +536,7 @@ _spdk_lvs_init_cb(void *cb_arg, struct spdk_blob_store *bs, int lvserrno)
	assert(bs != NULL);
	lvs->blobstore = bs;
	TAILQ_INIT(&lvs->lvols);
	TAILQ_INIT(&lvs->pending_lvols);

	SPDK_INFOLOG(SPDK_LOG_LVOL, "Lvol store initialized\n");

@@ -961,6 +963,8 @@ _spdk_lvol_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno)
	spdk_blob_id blob_id = spdk_blob_get_id(blob);
	struct spdk_lvol *lvol = req->lvol;

	TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link);

	if (lvolerrno < 0) {
		free(lvol);
		req->cb_fn(req->cb_arg, NULL, lvolerrno);
@@ -994,6 +998,7 @@ _spdk_lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno)
	struct spdk_blob_store *bs;

	if (lvolerrno < 0) {
		TAILQ_REMOVE(&req->lvol->lvol_store->pending_lvols, req->lvol, link);
		free(req->lvol);
		assert(req->cb_fn != NULL);
		req->cb_fn(req->cb_arg, NULL, lvolerrno);
@@ -1048,6 +1053,13 @@ _spdk_lvs_verify_lvol_name(struct spdk_lvol_store *lvs, const char *name)
		}
	}

	TAILQ_FOREACH(tmp, &lvs->pending_lvols, link) {
		if (!strncmp(name, tmp->name, SPDK_LVOL_NAME_MAX)) {
			SPDK_ERRLOG("lvol with name %s is being already created\n", name);
			return -EEXIST;
		}
	}

	return 0;
}

@@ -1090,6 +1102,7 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
	lvol->close_only = false;
	lvol->thin_provision = thin_provision;
	snprintf(lvol->name, sizeof(lvol->name), "%s", name);
	TAILQ_INSERT_TAIL(&lvol->lvol_store->pending_lvols, lvol, link);
	spdk_uuid_generate(&lvol->uuid);
	spdk_uuid_fmt_lower(lvol->uuid_str, sizeof(lvol->uuid_str), &lvol->uuid);
	req->lvol = lvol;
@@ -1150,6 +1163,7 @@ spdk_lvol_create_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name,

	newlvol->lvol_store = origlvol->lvol_store;
	snprintf(newlvol->name, sizeof(newlvol->name), "%s", snapshot_name);
	TAILQ_INSERT_TAIL(&newlvol->lvol_store->pending_lvols, newlvol, link);
	spdk_uuid_generate(&newlvol->uuid);
	spdk_uuid_fmt_lower(newlvol->uuid_str, sizeof(newlvol->uuid_str), &newlvol->uuid);
	snapshot_xattrs.count = SPDK_COUNTOF(xattr_names);
@@ -1207,6 +1221,7 @@ spdk_lvol_create_clone(struct spdk_lvol *origlvol, const char *clone_name,

	newlvol->lvol_store = lvs;
	snprintf(newlvol->name, sizeof(newlvol->name), "%s", clone_name);
	TAILQ_INSERT_TAIL(&newlvol->lvol_store->pending_lvols, newlvol, link);
	spdk_uuid_generate(&newlvol->uuid);
	spdk_uuid_fmt_lower(newlvol->uuid_str, sizeof(newlvol->uuid_str), &newlvol->uuid);
	clone_xattrs.count = SPDK_COUNTOF(xattr_names);
+2 −0
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ spdk_lvs_load(struct spdk_bs_dev *dev,
		lvs = calloc(1, sizeof(*lvs));
		SPDK_CU_ASSERT_FATAL(lvs != NULL);
		TAILQ_INIT(&lvs->lvols);
		TAILQ_INIT(&lvs->pending_lvols);
		g_lvol_store = lvs;
		for (i = 0; i < g_num_lvols; i++) {
			_lvol_create(lvs);
@@ -269,6 +270,7 @@ spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
		lvs = calloc(1, sizeof(*lvs));
		SPDK_CU_ASSERT_FATAL(lvs != NULL);
		TAILQ_INIT(&lvs->lvols);
		TAILQ_INIT(&lvs->pending_lvols);
		spdk_uuid_generate(&lvs->uuid);
		snprintf(lvs->name, sizeof(lvs->name), "%s", o->name);
		lvs->bs_dev = bs_dev;
+21 −0
Original line number Diff line number Diff line
@@ -1627,6 +1627,27 @@ lvol_names(void)
	spdk_lvol_close(lvol2, close_cb, NULL);
	spdk_lvol_destroy(lvol2, destroy_cb, NULL);

	/* Simulate creating two lvols with same name simultaneously. */
	lvol = calloc(1, sizeof(*lvol));
	SPDK_CU_ASSERT_FATAL(lvol != NULL);
	snprintf(lvol->name, sizeof(lvol->name), "tmp_name");
	TAILQ_INSERT_TAIL(&lvs->pending_lvols, lvol, link);
	rc = spdk_lvol_create(lvs, "tmp_name", 1, false, lvol_op_with_handle_complete, NULL);
	CU_ASSERT(rc == -EEXIST);

	/* Remove name from temporary list and try again. */
	TAILQ_REMOVE(&lvs->pending_lvols, lvol, link);
	free(lvol);

	rc = spdk_lvol_create(lvs, "tmp_name", 1, false, lvol_op_with_handle_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
	lvol = g_lvol;

	spdk_lvol_close(lvol, close_cb, NULL);
	spdk_lvol_destroy(lvol, destroy_cb, NULL);

	g_lvserrno = -1;
	rc = spdk_lvs_destroy(lvs, lvol_store_op_complete, NULL);
	CU_ASSERT(rc == 0);