From 5340d17823cf5cd1806f92a98930257fa8e215ca Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Thu, 16 Apr 2020 13:34:31 -0700 Subject: [PATCH] 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 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 Tested-by: SPDK CI Jenkins --- lib/nvme/nvme_cuse.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/nvme/nvme_cuse.c b/lib/nvme/nvme_cuse.c index f4c13c607..5f274594d 100644 --- a/lib/nvme/nvme_cuse.c +++ b/lib/nvme/nvme_cuse.c @@ -60,6 +60,7 @@ struct cuse_device { 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 struct spdk_bit_array *g_ctrlr_started; @@ -910,13 +911,18 @@ nvme_cuse_stop(struct spdk_nvme_ctrlr *ctrlr) { struct cuse_device *ctrlr_device; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { SPDK_ERRLOG("Cannot find associated CUSE device\n"); + pthread_mutex_unlock(&g_cuse_mtx); return; } cuse_nvme_ctrlr_stop(ctrlr_device); + + pthread_mutex_unlock(&g_cuse_mtx); } 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; } + pthread_mutex_lock(&g_cuse_mtx); + rc = nvme_cuse_start(ctrlr); if (rc) { nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); } + pthread_mutex_unlock(&g_cuse_mtx); + return rc; } @@ -947,14 +957,19 @@ spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr) { struct cuse_device *ctrlr_device; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { SPDK_ERRLOG("Cannot find associated CUSE device\n"); + pthread_mutex_unlock(&g_cuse_mtx); return -ENODEV; } cuse_nvme_ctrlr_stop(ctrlr_device); + pthread_mutex_unlock(&g_cuse_mtx); + nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer); 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; size_t req_len; + pthread_mutex_lock(&g_cuse_mtx); + ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr); if (!ctrlr_device) { + pthread_mutex_unlock(&g_cuse_mtx); return -ENODEV; } req_len = strnlen(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name)); if (*size < req_len) { *size = req_len; + pthread_mutex_unlock(&g_cuse_mtx); return -ENOSPC; } snprintf(name, req_len + 1, "%s", ctrlr_device->dev_name); + pthread_mutex_unlock(&g_cuse_mtx); + 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; size_t req_len; + pthread_mutex_lock(&g_cuse_mtx); + ns_device = nvme_cuse_get_cuse_ns_device(ctrlr, nsid); if (!ns_device) { + pthread_mutex_unlock(&g_cuse_mtx); return -ENODEV; } req_len = strnlen(ns_device->dev_name, sizeof(ns_device->dev_name)); if (*size < req_len) { *size = req_len; + pthread_mutex_unlock(&g_cuse_mtx); return -ENOSPC; } snprintf(name, req_len + 1, "%s", ns_device->dev_name); + pthread_mutex_unlock(&g_cuse_mtx); + return 0; }