From:Suzuki K.Poulose <suz...@in.ibm.com> Keep track of the core generation requests. Concurrent core generation requests for the same target process are not allowed.
Signed-off-by: Suzuki K. Poulose <suz...@in.ibm.com> Signed-off-by: Ananth N.Mavinakayanahalli <ana...@in.ibm.com> --- fs/proc/gencore.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/proc/gencore.h | 12 +++++++ 2 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 fs/proc/gencore.h diff --git a/fs/proc/gencore.c b/fs/proc/gencore.c index 115f1e4..580a8b5 100644 --- a/fs/proc/gencore.c +++ b/fs/proc/gencore.c @@ -23,23 +23,105 @@ */ #include <linux/seq_file.h> +#include <linux/slab.h> #include "internal.h" +#include "gencore.h" + +static LIST_HEAD(core_list); +static DEFINE_MUTEX(core_mutex); + +/* Called with core_mutex held */ +static struct core_proc* get_core_proc(struct task_struct *t) +{ + struct core_proc *cp; + + list_for_each_entry(cp, &core_list, list) { + if (cp->task == t->group_leader) + return cp; + } + return NULL; +} static ssize_t read_gencore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) { - return 0; + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); + struct core_proc *cp; + ssize_t ret = 0; + + if (!task) + return -EIO; + + mutex_lock(&core_mutex); + cp = get_core_proc(task); + if (!cp) { + mutex_unlock(&core_mutex); + ret = -EIO; + goto out; + } + mutex_unlock(&core_mutex); + +out: + put_task_struct(task); + return ret; } static int release_gencore(struct inode *inode, struct file *file) { + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); + struct core_proc *cp; + + if (!task) + return -EIO; + + mutex_lock(&core_mutex); + cp = get_core_proc(task); + if (cp) { + list_del(&cp->list); + kfree(cp); + } + mutex_unlock(&core_mutex); + put_task_struct(task); return 0; } +/* + * Validate if the call is valid. We also need to prevent >1 open + * of the same file. + */ static int open_gencore(struct inode *inode, struct file *filp) { - return 0; + struct task_struct *task = get_proc_task(inode); + struct core_proc *cp; + int ret = 0; + if (!task) + return -ENOENT; + + mutex_lock(&core_mutex); + cp = get_core_proc(task); + mutex_unlock(&core_mutex); + if (cp) { + ret = -EALREADY; + goto out; + } + + cp = kzalloc(sizeof (*cp), GFP_KERNEL); + if (!cp) { + ret = -ENOMEM; + goto out; + } + + cp->task = task->group_leader; + INIT_LIST_HEAD(&cp->list); + mutex_lock(&core_mutex); + list_add(&cp->list, &core_list); + mutex_unlock(&core_mutex); + +out: + put_task_struct(task); + return ret; } + const struct file_operations proc_gen_core_operations = { .open = open_gencore, .read = read_gencore, diff --git a/fs/proc/gencore.h b/fs/proc/gencore.h new file mode 100644 index 0000000..c98fddf --- /dev/null +++ b/fs/proc/gencore.h @@ -0,0 +1,12 @@ +#ifndef __GEN_CORE_H +#define __GEN_CORE_H + +#include <linux/list.h> +#include <linux/sched.h> + +struct core_proc { + struct list_head list; + struct task_struct *task; +}; + +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/