@@ -140,6 +140,9 @@ struct pid_entry {
NOD(NAME, (S_IFLNK|S_IRWXUGO), \
&proc_pid_link_inode_operations, NULL, \
{ .proc_get_link = get_link } )
+#define TASKLNK(NAME) \
+ NOD(NAME, (S_IFLNK|S_IRWXUGO), \
+ &proc_tgid_to_pid_link_inode_operations, NULL, {})
#define REG(NAME, MODE, fops) \
NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
#define ONE(NAME, MODE, show) \
@@ -2941,6 +2944,37 @@ static int proc_pid_patch_state(struct seq_file *m, struct pid_namespace *ns,
}
#endif /* CONFIG_LIVEPATCH */
+static const char *proc_tgid_to_pid_symlink_get_link(struct dentry *dentry,
+ struct inode *inode,
+ struct delayed_call *done)
+{
+ struct task_struct *task;
+ char *link = ERR_PTR(-ENOENT);
+
+ if (!dentry)
+ return ERR_PTR(-ECHILD);
+
+ task = get_proc_task(inode);
+ if (task) {
+ struct pid_namespace *ns = inode->i_sb->s_fs_info;
+
+ link = kasprintf(GFP_KERNEL, "task/%u/%.*s",
+ pid_nr_ns(PROC_I(inode)->pid, ns),
+ dentry->d_name.len, dentry->d_name.name);
+ if (link)
+ set_delayed_call(done, kfree_link, link);
+ else
+ link = ERR_PTR(-ENOMEM);
+ put_task_struct(task);
+ }
+ return link;
+}
+
+static const struct inode_operations proc_tgid_to_pid_link_inode_operations = {
+ .get_link = proc_tgid_to_pid_symlink_get_link,
+ .setattr = proc_setattr,
+};
+
/*
* Thread groups
*/
@@ -2948,12 +2982,12 @@ static const struct file_operations proc_task_operations;
static const struct inode_operations proc_task_inode_operations;
static const struct pid_entry tgid_base_stuff[] = {
- DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
+ TASKLNK("fd"),
DIR("map_files", S_IRUSR|S_IXUSR, proc_map_files_inode_operations, proc_map_files_operations),
- DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
- DIR("ns", S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations),
+ TASKLNK("fdinfo"),
+ TASKLNK("ns"),
#ifdef CONFIG_NET
- DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
+ TASKLNK("net"),
#endif
REG("environ", S_IRUSR, proc_environ_operations),
REG("auxv", S_IRUSR, proc_auxv_operations),
@@ -2991,7 +3025,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
#ifdef CONFIG_SECURITY
- DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
+ TASKLNK("attr"),
#endif
#ifdef CONFIG_KALLSYMS
ONE("wchan", S_IRUGO, proc_pid_wchan),