From 59ed2aa9f64ce08008fe196bd054a21dba31c38c Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Mon, 29 May 2017 15:46:39 -0700 Subject: [PATCH] blobfs: lock accesses to sync fs_request list Synchronous blobfs channels may allocate requests from the synchronous thread, but free the request from the async thread - especially for code that is shared between sync and async modes. So add a lock to the request list for sync channels only. Note this only affects metadata path (i.e. sync, delete, open) and not I/O path. Signed-off-by: Jim Harris Change-Id: I932c500807c2f459c697fab2ffd91a88b88b0c87 Reviewed-on: https://review.gerrithub.io/362964 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Ben Walker --- lib/blobfs/blobfs.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/blobfs/blobfs.c b/lib/blobfs/blobfs.c index fe8a40051..54e8375b5 100644 --- a/lib/blobfs/blobfs.c +++ b/lib/blobfs/blobfs.c @@ -232,6 +232,8 @@ struct spdk_fs_channel { struct spdk_filesystem *fs; struct spdk_io_channel *bs_channel; fs_send_request_fn send_request; + bool sync; + pthread_spinlock_t lock; }; static struct spdk_fs_request * @@ -239,11 +241,22 @@ alloc_fs_request(struct spdk_fs_channel *channel) { struct spdk_fs_request *req; + if (channel->sync) { + pthread_spin_lock(&channel->lock); + } + req = TAILQ_FIRST(&channel->reqs); - if (!req) { + if (req) { + TAILQ_REMOVE(&channel->reqs, req, link); + } + + if (channel->sync) { + pthread_spin_unlock(&channel->lock); + } + + if (req == NULL) { return NULL; } - TAILQ_REMOVE(&channel->reqs, req, link); memset(req, 0, sizeof(*req)); req->channel = channel; req->args.from_request = true; @@ -254,7 +267,17 @@ alloc_fs_request(struct spdk_fs_channel *channel) static void free_fs_request(struct spdk_fs_request *req) { + struct spdk_fs_channel *channel = req->channel; + + if (channel->sync) { + pthread_spin_lock(&channel->lock); + } + TAILQ_INSERT_HEAD(&req->channel->reqs, req, link); + + if (channel->sync) { + pthread_spin_unlock(&channel->lock); + } } static int @@ -1457,6 +1480,8 @@ spdk_fs_alloc_io_channel_sync(struct spdk_filesystem *fs) io_channel = spdk_get_io_channel(&fs->io_target); fs_channel = spdk_io_channel_get_ctx(io_channel); fs_channel->send_request = fs->send_request; + fs_channel->sync = 1; + pthread_spin_init(&fs_channel->lock, 0); return io_channel; }