nvme: Make spdk_nvme_cuse_register thread safe

There is no indication right now that this function couldn't be called
by multiple threads on different controllers. However, internally it is
using two globals that can become corrupted if the user were to do this.
Put a lock around them so it is safe.

Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Change-Id: I59361f510eb1659c2346f1fd33c375add1dc9c81
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1903
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Ben Walker 2020-04-16 13:34:31 -07:00 committed by Jim Harris
parent e396d97db0
commit 5340d17823

View File

@ -60,6 +60,7 @@ struct cuse_device {
TAILQ_ENTRY(cuse_device) tailq; TAILQ_ENTRY(cuse_device) tailq;
}; };
static pthread_mutex_t g_cuse_mtx = PTHREAD_MUTEX_INITIALIZER;
static TAILQ_HEAD(, cuse_device) g_ctrlr_ctx_head = TAILQ_HEAD_INITIALIZER(g_ctrlr_ctx_head); static TAILQ_HEAD(, cuse_device) g_ctrlr_ctx_head = TAILQ_HEAD_INITIALIZER(g_ctrlr_ctx_head);
static struct spdk_bit_array *g_ctrlr_started; static struct spdk_bit_array *g_ctrlr_started;
@ -910,13 +911,18 @@ nvme_cuse_stop(struct spdk_nvme_ctrlr *ctrlr)
{ {
struct cuse_device *ctrlr_device; struct cuse_device *ctrlr_device;
pthread_mutex_lock(&g_cuse_mtx);
ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
if (!ctrlr_device) { if (!ctrlr_device) {
SPDK_ERRLOG("Cannot find associated CUSE device\n"); SPDK_ERRLOG("Cannot find associated CUSE device\n");
pthread_mutex_unlock(&g_cuse_mtx);
return; return;
} }
cuse_nvme_ctrlr_stop(ctrlr_device); cuse_nvme_ctrlr_stop(ctrlr_device);
pthread_mutex_unlock(&g_cuse_mtx);
} }
static struct nvme_io_msg_producer cuse_nvme_io_msg_producer = { static struct nvme_io_msg_producer cuse_nvme_io_msg_producer = {
@ -934,11 +940,15 @@ spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr)
return rc; return rc;
} }
pthread_mutex_lock(&g_cuse_mtx);
rc = nvme_cuse_start(ctrlr); rc = nvme_cuse_start(ctrlr);
if (rc) { if (rc) {
nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
} }
pthread_mutex_unlock(&g_cuse_mtx);
return rc; return rc;
} }
@ -947,14 +957,19 @@ spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr)
{ {
struct cuse_device *ctrlr_device; struct cuse_device *ctrlr_device;
pthread_mutex_lock(&g_cuse_mtx);
ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
if (!ctrlr_device) { if (!ctrlr_device) {
SPDK_ERRLOG("Cannot find associated CUSE device\n"); SPDK_ERRLOG("Cannot find associated CUSE device\n");
pthread_mutex_unlock(&g_cuse_mtx);
return -ENODEV; return -ENODEV;
} }
cuse_nvme_ctrlr_stop(ctrlr_device); cuse_nvme_ctrlr_stop(ctrlr_device);
pthread_mutex_unlock(&g_cuse_mtx);
nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
return 0; return 0;
@ -966,18 +981,24 @@ spdk_nvme_cuse_get_ctrlr_name(struct spdk_nvme_ctrlr *ctrlr, char *name, size_t
struct cuse_device *ctrlr_device; struct cuse_device *ctrlr_device;
size_t req_len; size_t req_len;
pthread_mutex_lock(&g_cuse_mtx);
ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
if (!ctrlr_device) { if (!ctrlr_device) {
pthread_mutex_unlock(&g_cuse_mtx);
return -ENODEV; return -ENODEV;
} }
req_len = strnlen(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name)); req_len = strnlen(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name));
if (*size < req_len) { if (*size < req_len) {
*size = req_len; *size = req_len;
pthread_mutex_unlock(&g_cuse_mtx);
return -ENOSPC; return -ENOSPC;
} }
snprintf(name, req_len + 1, "%s", ctrlr_device->dev_name); snprintf(name, req_len + 1, "%s", ctrlr_device->dev_name);
pthread_mutex_unlock(&g_cuse_mtx);
return 0; return 0;
} }
@ -987,17 +1008,23 @@ spdk_nvme_cuse_get_ns_name(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, char *n
struct cuse_device *ns_device; struct cuse_device *ns_device;
size_t req_len; size_t req_len;
pthread_mutex_lock(&g_cuse_mtx);
ns_device = nvme_cuse_get_cuse_ns_device(ctrlr, nsid); ns_device = nvme_cuse_get_cuse_ns_device(ctrlr, nsid);
if (!ns_device) { if (!ns_device) {
pthread_mutex_unlock(&g_cuse_mtx);
return -ENODEV; return -ENODEV;
} }
req_len = strnlen(ns_device->dev_name, sizeof(ns_device->dev_name)); req_len = strnlen(ns_device->dev_name, sizeof(ns_device->dev_name));
if (*size < req_len) { if (*size < req_len) {
*size = req_len; *size = req_len;
pthread_mutex_unlock(&g_cuse_mtx);
return -ENOSPC; return -ENOSPC;
} }
snprintf(name, req_len + 1, "%s", ns_device->dev_name); snprintf(name, req_len + 1, "%s", ns_device->dev_name);
pthread_mutex_unlock(&g_cuse_mtx);
return 0; return 0;
} }