X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=lttng-abi.c;h=64364794718b5ab2756b068fe95108893211d27f;hb=623d019720d708350ed55bce2b79b04e49604b23;hp=26a456ece13f7ed0a62b5e3b3e92d2cff942c17c;hpb=d4d4b9c765362750b023ac23161573113189620d;p=lttng-modules.git diff --git a/lttng-abi.c b/lttng-abi.c index 26a456ec..64364794 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ #include "wrapper/ringbuffer/vfs.h" #include "wrapper/ringbuffer/backend.h" @@ -553,10 +554,9 @@ int lttng_metadata_ring_buffer_ioctl_get_next_subbuf(struct file *filp, struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; struct channel *chan = buf->backend.chan; - struct lttng_channel *lttng_chan = channel_get_private(chan); int ret; - ret = lttng_metadata_output_channel(lttng_chan, stream); + ret = lttng_metadata_output_channel(stream, chan); if (ret > 0) { lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); ret = 0; @@ -671,6 +671,10 @@ err: } #endif +/* + * This is not used by anonymous file descriptors. This code is left + * there if we ever want to implement an inode with open() operation. + */ static int lttng_metadata_ring_buffer_open(struct inode *inode, struct file *file) { @@ -678,6 +682,14 @@ int lttng_metadata_ring_buffer_open(struct inode *inode, struct file *file) struct lib_ring_buffer *buf = stream->priv; file->private_data = buf; + /* + * Since life-time of metadata cache differs from that of + * session, we need to keep our own reference on the transport. + */ + if (!try_module_get(stream->transport->owner)) { + printk(KERN_WARNING "LTT : Can't lock transport module.\n"); + return -EBUSY; + } return lib_ring_buffer_open(inode, file, buf); } @@ -686,12 +698,9 @@ int lttng_metadata_ring_buffer_release(struct inode *inode, struct file *file) { struct lttng_metadata_stream *stream = file->private_data; struct lib_ring_buffer *buf = stream->priv; - struct channel *chan = buf->backend.chan; - struct lttng_channel *lttng_chan = channel_get_private(chan); kref_put(&stream->metadata_cache->refcount, metadata_cache_destroy); - fput(lttng_chan->file); - + module_put(stream->transport->owner); return lib_ring_buffer_release(inode, file, buf); } @@ -811,24 +820,41 @@ int lttng_abi_open_metadata_stream(struct file *channel_file) metadata_stream = kzalloc(sizeof(struct lttng_metadata_stream), GFP_KERNEL); - if (!metadata_stream) - return -ENOMEM; + if (!metadata_stream) { + ret = -ENOMEM; + goto nomem; + } metadata_stream->metadata_cache = session->metadata_cache; init_waitqueue_head(&metadata_stream->read_wait); metadata_stream->priv = buf; stream_priv = metadata_stream; + metadata_stream->transport = channel->transport; + + /* + * Since life-time of metadata cache differs from that of + * session, we need to keep our own reference on the transport. + */ + if (!try_module_get(metadata_stream->transport->owner)) { + printk(KERN_WARNING "LTT : Can't lock transport module.\n"); + ret = -EINVAL; + goto notransport; + } + ret = lttng_abi_create_stream_fd(channel_file, stream_priv, <tng_metadata_ring_buffer_file_operations); if (ret < 0) goto fd_error; - atomic_long_inc(&channel_file->f_count); kref_get(&session->metadata_cache->refcount); list_add(&metadata_stream->list, &session->metadata_cache->metadata_stream); return ret; fd_error: + module_put(metadata_stream->transport->owner); +notransport: + kfree(metadata_stream); +nomem: channel->ops->buffer_read_close(buf); return ret; } @@ -875,8 +901,9 @@ int lttng_abi_create_event(struct file *channel_file, * will stay invariant for the rest of the session. */ event = lttng_event_create(channel, event_param, NULL, NULL); - if (!event) { - ret = -EINVAL; + WARN_ON_ONCE(!event); + if (IS_ERR(event)) { + ret = PTR_ERR(event); goto event_error; } event_file->private_data = event;