The metadata stream is part of a list of metadata streams in the
metadata cache. Its addition to the list should be protected by
the metadata cache lock. It needs to be paired with protection
of list iteration with the same lock.
Removal from the list is entirely missing, and should be added
to lttng_metadata_ring_buffer_release (with proper locking).
This missing list removal was probably not causing issues because the
metadata stream structure was leaked: a kfree() is missing from
lttng_metadata_ring_buffer_release as well.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
struct lttng_metadata_stream *stream = file->private_data;
struct lib_ring_buffer *buf = stream->priv;
struct lttng_metadata_stream *stream = file->private_data;
struct lib_ring_buffer *buf = stream->priv;
+ mutex_lock(&stream->metadata_cache->lock);
+ list_del(&stream->list);
+ mutex_unlock(&stream->metadata_cache->lock);
kref_put(&stream->metadata_cache->refcount, metadata_cache_destroy);
module_put(stream->transport->owner);
kref_put(&stream->metadata_cache->refcount, metadata_cache_destroy);
module_put(stream->transport->owner);
return lib_ring_buffer_release(inode, file, buf);
}
return lib_ring_buffer_release(inode, file, buf);
}
if (ret < 0)
goto fd_error;
if (ret < 0)
goto fd_error;
+ mutex_lock(&session->metadata_cache->lock);
list_add(&metadata_stream->list,
&session->metadata_cache->metadata_stream);
list_add(&metadata_stream->list,
&session->metadata_cache->metadata_stream);
+ mutex_unlock(&session->metadata_cache->lock);
if (atomic_dec_return(&session->metadata_cache->producing) == 0) {
struct lttng_metadata_stream *stream;
if (atomic_dec_return(&session->metadata_cache->producing) == 0) {
struct lttng_metadata_stream *stream;
- mutex_unlock(&session->metadata_cache->lock);
list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list)
wake_up_interruptible(&stream->read_wait);
list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list)
wake_up_interruptible(&stream->read_wait);
+ mutex_unlock(&session->metadata_cache->lock);