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: Maciej Szwed <maciej.szwed@intel.com>
Change-Id: I31b59ee13b5b9bae531866925dd409b143f08ad4
Reviewed-on: https://review.gerrithub.io/407408
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Maciej Szwed 2018-04-12 10:10:49 +02:00 committed by Daniel Verkamp
parent 0629b01d21
commit 208748b423
4 changed files with 39 additions and 0 deletions

View File

@ -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];

View File

@ -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);

View File

@ -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;

View File

@ -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);