chan_param.switch_timer_interval,
chan_param.read_timer_interval);
if (!chan) {
- ret = -ENOMEM;
+ ret = -EINVAL;
goto chan_error;
}
chan->file = chan_file;
chan_file->private_data = chan;
fd_install(chan_fd, chan_file);
/* The channel created holds a reference on the session */
- atomic_inc(&session_file->f_count);
+ atomic_long_inc(&session_file->f_count);
return chan_fd;
int lttng_session_release(struct inode *inode, struct file *file)
{
struct ltt_session *session = file->private_data;
- ltt_session_destroy(session);
+
+ if (session)
+ ltt_session_destroy(session);
return 0;
}
goto file_error;
}
fd_install(stream_fd, stream_file);
- /* The stream holds a reference on the channel */
- atomic_inc(&channel_file->f_count);
+ /*
+ * The stream holds a reference to the channel within the generic ring
+ * buffer library, so no need to hold a refcount on the channel and
+ * session files here.
+ */
return stream_fd;
file_error:
struct lttng_event event_param;
int event_fd, ret;
struct file *event_file;
+ void *probe;
if (copy_from_user(&event_param, uevent_param, sizeof(event_param)))
return -EFAULT;
event_name = kmalloc(PATH_MAX, GFP_KERNEL);
if (!event_name)
return -ENOMEM;
- if (strncpy_from_user(event_name, uevent_param->name, PATH_MAX)) {
+ if (strncpy_from_user(event_name, uevent_param->name, PATH_MAX) < 0) {
ret = -EFAULT;
goto name_error;
}
event_name[PATH_MAX - 1] = '\0';
+
+ probe = ltt_probe_get(event_name);
+ if (!probe) {
+ ret = -ENOENT;
+ goto probe_error;
+ }
event_fd = get_unused_fd();
if (event_fd < 0) {
ret = event_fd;
* invariant for the rest of the session.
*/
event = ltt_event_create(channel, event_name, event_param.itype,
- NULL, NULL); /* TODO non-null probe */
+ probe, NULL);
if (!event) {
goto event_error;
ret = -EEXIST;
event_file->private_data = event;
fd_install(event_fd, event_file);
/* The event holds a reference on the channel */
- atomic_inc(&channel_file->f_count);
+ atomic_long_inc(&channel_file->f_count);
kfree(event_name);
return event_fd;
file_error:
put_unused_fd(event_fd);
fd_error:
+ ltt_probe_put(probe);
+probe_error:
name_error:
kfree(event_name);
return ret;
int lttng_channel_release(struct inode *inode, struct file *file)
{
struct ltt_channel *channel = file->private_data;
- fput(channel->session->file);
+
+ if (channel)
+ fput(channel->session->file);
return 0;
}
int lttng_event_release(struct inode *inode, struct file *file)
{
struct ltt_event *event = file->private_data;
- fput(event->chan->file);
+
+ if (event)
+ fput(event->chan->file);
return 0;
}
int ret = 0;
lttng_dentry = debugfs_create_file("lttng", S_IWUSR, NULL, NULL,
- <tng_session_fops);
+ <tng_fops);
if (IS_ERR(lttng_dentry) || !lttng_dentry) {
printk(KERN_ERR "Error creating LTTng control file\n");
ret = -ENOMEM;