aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 03c8d747be48..b9760628e1fd 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1658,13 +1658,18 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
1658 return 0; 1658 return 0;
1659} 1659}
1660 1660
1661static inline bool proc_inode_is_dead(struct inode *inode)
1662{
1663 return !proc_pid(inode)->tasks[PIDTYPE_PID].first;
1664}
1665
1661int pid_delete_dentry(const struct dentry *dentry) 1666int pid_delete_dentry(const struct dentry *dentry)
1662{ 1667{
1663 /* Is the task we represent dead? 1668 /* Is the task we represent dead?
1664 * If so, then don't put the dentry on the lru list, 1669 * If so, then don't put the dentry on the lru list,
1665 * kill it immediately. 1670 * kill it immediately.
1666 */ 1671 */
1667 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; 1672 return proc_inode_is_dead(dentry->d_inode);
1668} 1673}
1669 1674
1670const struct dentry_operations pid_dentry_operations = 1675const struct dentry_operations pid_dentry_operations =
@@ -1819,6 +1824,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
1819 if (rc) 1824 if (rc)
1820 goto out_mmput; 1825 goto out_mmput;
1821 1826
1827 rc = -ENOENT;
1822 down_read(&mm->mmap_sem); 1828 down_read(&mm->mmap_sem);
1823 vma = find_exact_vma(mm, vm_start, vm_end); 1829 vma = find_exact_vma(mm, vm_start, vm_end);
1824 if (vma && vma->vm_file) { 1830 if (vma && vma->vm_file) {
@@ -3092,34 +3098,42 @@ out_no_task:
3092 * In the case of a seek we start with the leader and walk nr 3098 * In the case of a seek we start with the leader and walk nr
3093 * threads past it. 3099 * threads past it.
3094 */ 3100 */
3095static struct task_struct *first_tid(struct task_struct *leader, 3101static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos,
3096 int tid, int nr, struct pid_namespace *ns) 3102 struct pid_namespace *ns)
3097{ 3103{
3098 struct task_struct *pos; 3104 struct task_struct *pos, *task;
3105 unsigned long nr = f_pos;
3106
3107 if (nr != f_pos) /* 32bit overflow? */
3108 return NULL;
3099 3109
3100 rcu_read_lock(); 3110 rcu_read_lock();
3101 /* Attempt to start with the pid of a thread */ 3111 task = pid_task(pid, PIDTYPE_PID);
3102 if (tid && (nr > 0)) { 3112 if (!task)
3113 goto fail;
3114
3115 /* Attempt to start with the tid of a thread */
3116 if (tid && nr) {
3103 pos = find_task_by_pid_ns(tid, ns); 3117 pos = find_task_by_pid_ns(tid, ns);
3104 if (pos && (pos->group_leader == leader)) 3118 if (pos && same_thread_group(pos, task))
3105 goto found; 3119 goto found;
3106 } 3120 }
3107 3121
3108 /* If nr exceeds the number of threads there is nothing todo */ 3122 /* If nr exceeds the number of threads there is nothing todo */
3109 pos = NULL; 3123 if (nr >= get_nr_threads(task))
3110 if (nr && nr >= get_nr_threads(leader)) 3124 goto fail;
3111 goto out;
3112 3125
3113 /* If we haven't found our starting place yet start 3126 /* If we haven't found our starting place yet start
3114 * with the leader and walk nr threads forward. 3127 * with the leader and walk nr threads forward.
3115 */ 3128 */
3116 for (pos = leader; nr > 0; --nr) { 3129 pos = task = task->group_leader;
3117 pos = next_thread(pos); 3130 do {
3118 if (pos == leader) { 3131 if (!nr--)
3119 pos = NULL; 3132 goto found;
3120 goto out; 3133 } while_each_thread(task, pos);
3121 } 3134fail:
3122 } 3135 pos = NULL;
3136 goto out;
3123found: 3137found:
3124 get_task_struct(pos); 3138 get_task_struct(pos);
3125out: 3139out:
@@ -3152,25 +3166,16 @@ static struct task_struct *next_tid(struct task_struct *start)
3152/* for the /proc/TGID/task/ directories */ 3166/* for the /proc/TGID/task/ directories */
3153static int proc_task_readdir(struct file *file, struct dir_context *ctx) 3167static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3154{ 3168{
3155 struct task_struct *leader = NULL; 3169 struct inode *inode = file_inode(file);
3156 struct task_struct *task = get_proc_task(file_inode(file)); 3170 struct task_struct *task;
3157 struct pid_namespace *ns; 3171 struct pid_namespace *ns;
3158 int tid; 3172 int tid;
3159 3173
3160 if (!task) 3174 if (proc_inode_is_dead(inode))
3161 return -ENOENT;
3162 rcu_read_lock();
3163 if (pid_alive(task)) {
3164 leader = task->group_leader;
3165 get_task_struct(leader);
3166 }
3167 rcu_read_unlock();
3168 put_task_struct(task);
3169 if (!leader)
3170 return -ENOENT; 3175 return -ENOENT;
3171 3176
3172 if (!dir_emit_dots(file, ctx)) 3177 if (!dir_emit_dots(file, ctx))
3173 goto out; 3178 return 0;
3174 3179
3175 /* f_version caches the tgid value that the last readdir call couldn't 3180 /* f_version caches the tgid value that the last readdir call couldn't
3176 * return. lseek aka telldir automagically resets f_version to 0. 3181 * return. lseek aka telldir automagically resets f_version to 0.
@@ -3178,7 +3183,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3178 ns = file->f_dentry->d_sb->s_fs_info; 3183 ns = file->f_dentry->d_sb->s_fs_info;
3179 tid = (int)file->f_version; 3184 tid = (int)file->f_version;
3180 file->f_version = 0; 3185 file->f_version = 0;
3181 for (task = first_tid(leader, tid, ctx->pos - 2, ns); 3186 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
3182 task; 3187 task;
3183 task = next_tid(task), ctx->pos++) { 3188 task = next_tid(task), ctx->pos++) {
3184 char name[PROC_NUMBUF]; 3189 char name[PROC_NUMBUF];
@@ -3194,8 +3199,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3194 break; 3199 break;
3195 } 3200 }
3196 } 3201 }
3197out: 3202
3198 put_task_struct(leader);
3199 return 0; 3203 return 0;
3200} 3204}
3201 3205