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 <james.r.harris@intel.com>
Change-Id: I932c500807c2f459c697fab2ffd91a88b88b0c87

Reviewed-on: https://review.gerrithub.io/362964
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Jim Harris 2017-05-29 15:46:39 -07:00 committed by Daniel Verkamp
parent 60145e2cc9
commit 59ed2aa9f6

View File

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