From a33c99273818348fe61ba5bbd08fa61382eab22b Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 20 Jul 2011 14:12:59 -0400 Subject: [PATCH] Keep reference count on transport and file ops modules Signed-off-by: Mathieu Desnoyers --- lib/ringbuffer/ring_buffer_iterator.c | 2 ++ lib/ringbuffer/ring_buffer_vfs.c | 1 + ltt-debugfs-abi.c | 10 ++++++++++ ltt-events.c | 10 +++++++++- ltt-events.h | 15 ++++++++------- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/ringbuffer/ring_buffer_iterator.c b/lib/ringbuffer/ring_buffer_iterator.c index df8d485a..1321b5f9 100644 --- a/lib/ringbuffer/ring_buffer_iterator.c +++ b/lib/ringbuffer/ring_buffer_iterator.c @@ -780,6 +780,7 @@ int channel_file_release(struct inode *inode, struct file *file) } const struct file_operations channel_payload_file_operations = { + .owner = THIS_MODULE, .open = channel_file_open, .release = channel_file_release, .read = channel_file_read, @@ -788,6 +789,7 @@ const struct file_operations channel_payload_file_operations = { EXPORT_SYMBOL_GPL(channel_payload_file_operations); const struct file_operations lib_ring_buffer_payload_file_operations = { + .owner = THIS_MODULE, .open = lib_ring_buffer_file_open, .release = lib_ring_buffer_file_release, .read = lib_ring_buffer_file_read, diff --git a/lib/ringbuffer/ring_buffer_vfs.c b/lib/ringbuffer/ring_buffer_vfs.c index 60d69a92..1708ffd6 100644 --- a/lib/ringbuffer/ring_buffer_vfs.c +++ b/lib/ringbuffer/ring_buffer_vfs.c @@ -368,6 +368,7 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd, #endif const struct file_operations lib_ring_buffer_file_operations = { + .owner = THIS_MODULE, .open = lib_ring_buffer_open, .release = lib_ring_buffer_release, .poll = lib_ring_buffer_poll, diff --git a/ltt-debugfs-abi.c b/ltt-debugfs-abi.c index 72077183..cfc364a8 100644 --- a/ltt-debugfs-abi.c +++ b/ltt-debugfs-abi.c @@ -49,6 +49,11 @@ static const struct file_operations lttng_channel_fops; static const struct file_operations lttng_metadata_fops; static const struct file_operations lttng_event_fops; +/* + * Teardown management: opened file descriptors keep a refcount on the module, + * so it can only exit when all file descriptors are closed. + */ + enum channel_type { PER_CPU_CHANNEL, METADATA_CHANNEL, @@ -221,6 +226,7 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } static const struct file_operations lttng_fops = { + .owner = THIS_MODULE, .unlocked_ioctl = lttng_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = lttng_ioctl, @@ -410,6 +416,7 @@ int lttng_session_release(struct inode *inode, struct file *file) } static const struct file_operations lttng_session_fops = { + .owner = THIS_MODULE, .release = lttng_session_release, .unlocked_ioctl = lttng_session_ioctl, #ifdef CONFIG_COMPAT @@ -628,6 +635,7 @@ int lttng_channel_release(struct inode *inode, struct file *file) } static const struct file_operations lttng_channel_fops = { + .owner = THIS_MODULE, .release = lttng_channel_release, .poll = lttng_channel_poll, .unlocked_ioctl = lttng_channel_ioctl, @@ -637,6 +645,7 @@ static const struct file_operations lttng_channel_fops = { }; static const struct file_operations lttng_metadata_fops = { + .owner = THIS_MODULE, .release = lttng_channel_release, .unlocked_ioctl = lttng_metadata_ioctl, #ifdef CONFIG_COMPAT @@ -690,6 +699,7 @@ int lttng_event_release(struct inode *inode, struct file *file) /* TODO: filter control ioctl */ static const struct file_operations lttng_event_fops = { + .owner = THIS_MODULE, .release = lttng_event_release, .unlocked_ioctl = lttng_event_ioctl, #ifdef CONFIG_COMPAT diff --git a/ltt-events.c b/ltt-events.c index e9e076d8..3532dee5 100644 --- a/ltt-events.c +++ b/ltt-events.c @@ -196,7 +196,7 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, unsigned int read_timer_interval) { struct ltt_channel *chan; - struct ltt_transport *transport; + struct ltt_transport *transport = NULL; mutex_lock(&sessions_mutex); if (session->been_active) @@ -207,6 +207,10 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, transport_name); goto notransport; } + if (!try_module_get(transport->owner)) { + printk(KERN_WARNING "LTT : Can't lock transport module.\n"); + goto notransport; + } chan = kzalloc(sizeof(struct ltt_channel), GFP_KERNEL); if (!chan) goto nomem; @@ -224,6 +228,7 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, goto create_error; chan->enabled = 1; chan->ops = &transport->ops; + chan->transport = transport; list_add(&chan->list, &session->chan); mutex_unlock(&sessions_mutex); return chan; @@ -231,6 +236,8 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, create_error: kfree(chan); nomem: + if (transport) + module_put(transport->owner); notransport: active: mutex_unlock(&sessions_mutex); @@ -244,6 +251,7 @@ static void _ltt_channel_destroy(struct ltt_channel *chan) { chan->ops->channel_destroy(chan->chan); + module_put(chan->transport->owner); list_del(&chan->list); lttng_destroy_context(chan->ctx); kfree(chan); diff --git a/ltt-events.h b/ltt-events.h index 304bcb69..8cbe8efb 100644 --- a/ltt-events.h +++ b/ltt-events.h @@ -210,6 +210,13 @@ struct ltt_channel_ops { int (*is_disabled)(struct channel *chan); }; +struct ltt_transport { + char *name; + struct module *owner; + struct list_head node; + struct ltt_channel_ops ops; +}; + struct ltt_channel { unsigned int id; struct channel *chan; /* Channel buffers */ @@ -221,6 +228,7 @@ struct ltt_channel { unsigned int free_event_id; /* Next event ID to allocate */ struct list_head list; /* Channel list */ struct ltt_channel_ops *ops; + struct ltt_transport *transport; int header_type; /* 0: unset, 1: compact, 2: large */ int metadata_dumped:1; }; @@ -238,13 +246,6 @@ struct ltt_session { int metadata_dumped:1; }; -struct ltt_transport { - char *name; - struct module *owner; - struct list_head node; - struct ltt_channel_ops ops; -}; - struct ltt_session *ltt_session_create(void); int ltt_session_enable(struct ltt_session *session); int ltt_session_disable(struct ltt_session *session); -- 2.34.1