diff options
author | Steven Rostedt (Red Hat) <srostedt@redhat.com> | 2013-03-06 15:27:24 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-03-15 00:35:51 -0400 |
commit | a695cb5816228f86576f5f5c6809fdf8ed382ece (patch) | |
tree | 922f12a1a2fab1efa16f74216d6883deeefd1b74 /kernel/trace/trace.c | |
parent | 121aaee7b0a82605d33af200c7e9ebab6fd6e444 (diff) |
tracing: Prevent deleting instances when they are being read
Add a ref count to the trace_array structure and prevent removal
of instances that have open descriptors.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c547ebbe36ff..3a89496dc99b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2613,6 +2613,8 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) | |||
2613 | tracing_iter_reset(iter, cpu); | 2613 | tracing_iter_reset(iter, cpu); |
2614 | } | 2614 | } |
2615 | 2615 | ||
2616 | tr->ref++; | ||
2617 | |||
2616 | mutex_unlock(&trace_types_lock); | 2618 | mutex_unlock(&trace_types_lock); |
2617 | 2619 | ||
2618 | return iter; | 2620 | return iter; |
@@ -2649,6 +2651,10 @@ static int tracing_release(struct inode *inode, struct file *file) | |||
2649 | tr = iter->tr; | 2651 | tr = iter->tr; |
2650 | 2652 | ||
2651 | mutex_lock(&trace_types_lock); | 2653 | mutex_lock(&trace_types_lock); |
2654 | |||
2655 | WARN_ON(!tr->ref); | ||
2656 | tr->ref--; | ||
2657 | |||
2652 | for_each_tracing_cpu(cpu) { | 2658 | for_each_tracing_cpu(cpu) { |
2653 | if (iter->buffer_iter[cpu]) | 2659 | if (iter->buffer_iter[cpu]) |
2654 | ring_buffer_read_finish(iter->buffer_iter[cpu]); | 2660 | ring_buffer_read_finish(iter->buffer_iter[cpu]); |
@@ -4460,6 +4466,10 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
4460 | if (!info) | 4466 | if (!info) |
4461 | return -ENOMEM; | 4467 | return -ENOMEM; |
4462 | 4468 | ||
4469 | mutex_lock(&trace_types_lock); | ||
4470 | |||
4471 | tr->ref++; | ||
4472 | |||
4463 | info->iter.tr = tr; | 4473 | info->iter.tr = tr; |
4464 | info->iter.cpu_file = tc->cpu; | 4474 | info->iter.cpu_file = tc->cpu; |
4465 | info->iter.trace = tr->current_trace; | 4475 | info->iter.trace = tr->current_trace; |
@@ -4470,6 +4480,8 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) | |||
4470 | 4480 | ||
4471 | filp->private_data = info; | 4481 | filp->private_data = info; |
4472 | 4482 | ||
4483 | mutex_unlock(&trace_types_lock); | ||
4484 | |||
4473 | return nonseekable_open(inode, filp); | 4485 | return nonseekable_open(inode, filp); |
4474 | } | 4486 | } |
4475 | 4487 | ||
@@ -4568,10 +4580,17 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) | |||
4568 | struct ftrace_buffer_info *info = file->private_data; | 4580 | struct ftrace_buffer_info *info = file->private_data; |
4569 | struct trace_iterator *iter = &info->iter; | 4581 | struct trace_iterator *iter = &info->iter; |
4570 | 4582 | ||
4583 | mutex_lock(&trace_types_lock); | ||
4584 | |||
4585 | WARN_ON(!iter->tr->ref); | ||
4586 | iter->tr->ref--; | ||
4587 | |||
4571 | if (info->spare) | 4588 | if (info->spare) |
4572 | ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); | 4589 | ring_buffer_free_read_page(iter->trace_buffer->buffer, info->spare); |
4573 | kfree(info); | 4590 | kfree(info); |
4574 | 4591 | ||
4592 | mutex_unlock(&trace_types_lock); | ||
4593 | |||
4575 | return 0; | 4594 | return 0; |
4576 | } | 4595 | } |
4577 | 4596 | ||
@@ -5411,6 +5430,10 @@ static int instance_delete(const char *name) | |||
5411 | if (!found) | 5430 | if (!found) |
5412 | goto out_unlock; | 5431 | goto out_unlock; |
5413 | 5432 | ||
5433 | ret = -EBUSY; | ||
5434 | if (tr->ref) | ||
5435 | goto out_unlock; | ||
5436 | |||
5414 | list_del(&tr->list); | 5437 | list_del(&tr->list); |
5415 | 5438 | ||
5416 | event_trace_del_tracer(tr); | 5439 | event_trace_del_tracer(tr); |