Merge branch 'akpm' (patches from Andrew)
[sfrench/cifs-2.6.git] / fs / proc / base.c
index 1f394095eb8800de45b7a93e79b998ebf7737bef..13eda8de29981912b7809e6bab1ad289956b8701 100644 (file)
@@ -1982,19 +1982,21 @@ static int pid_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct inode *inode;
        struct task_struct *task;
+       int ret = 0;
 
-       if (flags & LOOKUP_RCU)
-               return -ECHILD;
-
-       inode = d_inode(dentry);
-       task = get_proc_task(inode);
+       rcu_read_lock();
+       inode = d_inode_rcu(dentry);
+       if (!inode)
+               goto out;
+       task = pid_task(proc_pid(inode), PIDTYPE_PID);
 
        if (task) {
                pid_update_inode(task, inode);
-               put_task_struct(task);
-               return 1;
+               ret = 1;
        }
-       return 0;
+out:
+       rcu_read_unlock();
+       return ret;
 }
 
 static inline bool proc_inode_is_dead(struct inode *inode)
@@ -3802,7 +3804,10 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
             task = next_tid(task), ctx->pos++) {
                char name[10 + 1];
                unsigned int len;
+
                tid = task_pid_nr_ns(task, ns);
+               if (!tid)
+                       continue;       /* The task has just exited. */
                len = snprintf(name, sizeof(name), "%u", tid);
                if (!proc_fill_cache(file, ctx, name, len,
                                proc_task_instantiate, task, NULL)) {