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:
parent
0629b01d21
commit
208748b423
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user