From mboxrd@z Thu Jan 1 00:00:00 1970 From: guijianfeng@cn.fujitsu.com (Gui Jianfeng) Date: Mon, 16 Mar 2009 10:52:30 +0800 Subject: [ltt-dev] [PATCH v2] LTTNG: Make marker enabled in advance In-Reply-To: <20090314024914.GA22526@Krystal> References: <49B9BA7A.4030007@cn.fujitsu.com> <20090314024914.GA22526@Krystal> Message-ID: <49BDBEEE.2050901@cn.fujitsu.com> Mathieu Desnoyers wrote: ... > Hrm, I did not notice it, but marker_info_read, as it is currently > implemented in LTTng, should take lock_markers() before iterating on the > markers. Can you provide a separate patch that fixes this ? (I don't > want to work under your feet...) > > The same should be done for build_marker_control_files() and > remove_marker_control_dir(). > Ok, will fix. > The rest looks good. I look forward to see V3. > > Thanks ! > > Mathieu > >> marker_iter_reset(&iter); >> marker_iter_start(&iter); >> for (; iter.marker != NULL; marker_iter_next(&iter)) { >> @@ -872,6 +890,7 @@ static ssize_t marker_info_read(struct file *filp, char __user *ubuf, >> } >> marker_iter_stop(&iter); >> >> +out: >> if (len >= PAGE_SIZE) { >> len = PAGE_SIZE; >> buf[PAGE_SIZE] = '\0'; >> @@ -887,6 +906,149 @@ static const struct file_operations info_fops = { >> .read = marker_info_read, >> }; >> >> +static int marker_mkdir(struct inode *dir, struct dentry *dentry, int mode) >> +{ >> + struct dentry *marker_d, *enable_d, *info_d, *channel_d; >> + int ret; >> + >> + ret = 0; >> + channel_d = (struct dentry *)dir->i_private; >> + mutex_unlock(&dir->i_mutex); >> + >> + marker_d = debugfs_create_dir(dentry->d_name.name, >> + channel_d); >> + if (IS_ERR(marker_d)) { >> + ret = PTR_ERR(marker_d); >> + goto out; >> + } >> + >> + enable_d = debugfs_create_file("enable", 0644, marker_d, >> + NULL, &enable_fops); >> + if (IS_ERR(enable_d) || !enable_d) { >> + printk(KERN_ERR >> + "%s: create file of %s failed\n", >> + __func__, "enable"); >> + ret = -ENOMEM; >> + goto remove_marker_dir; >> + } >> + >> + info_d = debugfs_create_file("info", 0644, marker_d, >> + NULL, &info_fops); >> + if (IS_ERR(info_d) || !info_d) { >> + printk(KERN_ERR >> + "%s: create file of %s failed\n", >> + __func__, "info"); >> + ret = -ENOMEM; >> + goto remove_enable_dir; >> + } >> + >> + goto out; >> + >> +remove_enable_dir: >> + debugfs_remove(enable_d); >> +remove_marker_dir: >> + debugfs_remove(marker_d); >> +out: >> + mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); >> + return ret; >> +} >> + >> +static int marker_rmdir(struct inode *dir, struct dentry *dentry) >> +{ >> + struct dentry *marker_d, *channel_d; >> + const char *channel, *name; >> + int ret; >> + >> + ret = 0; >> + >> + channel_d = (struct dentry *)dir->i_private; >> + channel = channel_d->d_name.name; >> + >> + marker_d = dir_lookup(channel_d, dentry->d_name.name); >> + >> + if (!marker_d) { >> + ret = -ENOENT; >> + goto out; >> + } >> + >> + name = marker_d->d_name.name; >> + >> + if (is_marker_present(channel, name) || >> + (!is_marker_present(channel, name) && >> + is_marker_enabled(channel, name))) { >> + ret = -EPERM; >> + goto out; >> + } >> + >> + mutex_unlock(&dir->i_mutex); >> + mutex_unlock(&dentry->d_inode->i_mutex); >> + debugfs_remove_recursive(marker_d); >> + mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); >> + mutex_lock(&dentry->d_inode->i_mutex); >> +out: >> + return ret; >> +} >> + >> +const struct inode_operations channel_dir_opt = { >> + .lookup = simple_lookup, >> + .mkdir = marker_mkdir, >> + .rmdir = marker_rmdir, >> +}; >> + >> +static int channel_mkdir(struct inode *dir, struct dentry *dentry, int mode) >> +{ >> + struct dentry *channel_d; >> + int ret; >> + >> + ret = 0; >> + mutex_unlock(&dir->i_mutex); >> + >> + channel_d = debugfs_create_dir(dentry->d_name.name, >> + markers_control_dir); >> + if (IS_ERR(channel_d)) { >> + ret = PTR_ERR(channel_d); >> + goto out; >> + } >> + >> + channel_d->d_inode->i_private = (void *)channel_d; >> + init_marker_dir(channel_d, &channel_dir_opt); >> +out: >> + mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); >> + return ret; >> +} >> + >> +static int channel_rmdir(struct inode *dir, struct dentry *dentry) >> +{ >> + struct dentry *channel_d; >> + int ret; >> + >> + ret = 0; >> + >> + channel_d = dir_lookup(markers_control_dir, dentry->d_name.name); >> + if (!channel_d) { >> + ret = -ENOENT; >> + goto out; >> + } >> + >> + if (list_empty(&channel_d->d_subdirs)) { >> + mutex_unlock(&dir->i_mutex); >> + mutex_unlock(&dentry->d_inode->i_mutex); >> + debugfs_remove(channel_d); >> + mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); >> + mutex_lock(&dentry->d_inode->i_mutex); >> + } else >> + ret = -EPERM; >> + >> +out: >> + return ret; >> +} >> + >> +const struct inode_operations root_dir_opt = { >> + .lookup = simple_lookup, >> + .mkdir = channel_mkdir, >> + .rmdir = channel_rmdir >> +}; >> + >> static int build_marker_file(struct marker *marker) >> { >> struct dentry *channel_d, *marker_d, *enable_d, *info_d; >> @@ -903,6 +1065,8 @@ static int build_marker_file(struct marker *marker) >> err = -ENOMEM; >> goto err_build_fail; >> } >> + channel_d->d_inode->i_private = (void *)channel_d; >> + init_marker_dir(channel_d, &channel_dir_opt); >> } >> >> marker_d = dir_lookup(channel_d, marker->name); >> @@ -1118,6 +1282,8 @@ static int __init ltt_trace_control_init(void) >> goto err_create_marker_control_dir; >> } >> >> + init_marker_dir(markers_control_dir, &root_dir_opt); >> + >> if (build_marker_control_files()) >> goto err_build_fail; >> >> -- >> 1.5.4.rc3 >> >> >> >> _______________________________________________ >> ltt-dev mailing list >> ltt-dev at lists.casi.polymtl.ca >> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev >> > -- Regards Gui Jianfeng