aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c4
-rw-r--r--fs/proc/base.c51
-rw-r--r--fs/proc/generic.c37
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/root.c2
5 files changed, 32 insertions, 64 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index eba339ecba27..65c62e1bfd6f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -374,7 +374,9 @@ static cputime_t task_stime(struct task_struct *p)
374 stime = nsec_to_clock_t(p->se.sum_exec_runtime) - 374 stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
375 cputime_to_clock_t(task_utime(p)); 375 cputime_to_clock_t(task_utime(p));
376 376
377 p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime)); 377 if (stime >= 0)
378 p->prev_stime = max(p->prev_stime, clock_t_to_cputime(stime));
379
378 return p->prev_stime; 380 return p->prev_stime;
379} 381}
380#endif 382#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a17c26859074..02a63ac04178 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2411,19 +2411,23 @@ out:
2411 * Find the first task with tgid >= tgid 2411 * Find the first task with tgid >= tgid
2412 * 2412 *
2413 */ 2413 */
2414static struct task_struct *next_tgid(unsigned int tgid, 2414struct tgid_iter {
2415 struct pid_namespace *ns) 2415 unsigned int tgid;
2416{
2417 struct task_struct *task; 2416 struct task_struct *task;
2417};
2418static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
2419{
2418 struct pid *pid; 2420 struct pid *pid;
2419 2421
2422 if (iter.task)
2423 put_task_struct(iter.task);
2420 rcu_read_lock(); 2424 rcu_read_lock();
2421retry: 2425retry:
2422 task = NULL; 2426 iter.task = NULL;
2423 pid = find_ge_pid(tgid, ns); 2427 pid = find_ge_pid(iter.tgid, ns);
2424 if (pid) { 2428 if (pid) {
2425 tgid = pid_nr_ns(pid, ns) + 1; 2429 iter.tgid = pid_nr_ns(pid, ns);
2426 task = pid_task(pid, PIDTYPE_PID); 2430 iter.task = pid_task(pid, PIDTYPE_PID);
2427 /* What we to know is if the pid we have find is the 2431 /* What we to know is if the pid we have find is the
2428 * pid of a thread_group_leader. Testing for task 2432 * pid of a thread_group_leader. Testing for task
2429 * being a thread_group_leader is the obvious thing 2433 * being a thread_group_leader is the obvious thing
@@ -2436,23 +2440,25 @@ retry:
2436 * found doesn't happen to be a thread group leader. 2440 * found doesn't happen to be a thread group leader.
2437 * As we don't care in the case of readdir. 2441 * As we don't care in the case of readdir.
2438 */ 2442 */
2439 if (!task || !has_group_leader_pid(task)) 2443 if (!iter.task || !has_group_leader_pid(iter.task)) {
2444 iter.tgid += 1;
2440 goto retry; 2445 goto retry;
2441 get_task_struct(task); 2446 }
2447 get_task_struct(iter.task);
2442 } 2448 }
2443 rcu_read_unlock(); 2449 rcu_read_unlock();
2444 return task; 2450 return iter;
2445} 2451}
2446 2452
2447#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) 2453#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
2448 2454
2449static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 2455static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2450 struct task_struct *task, int tgid) 2456 struct tgid_iter iter)
2451{ 2457{
2452 char name[PROC_NUMBUF]; 2458 char name[PROC_NUMBUF];
2453 int len = snprintf(name, sizeof(name), "%d", tgid); 2459 int len = snprintf(name, sizeof(name), "%d", iter.tgid);
2454 return proc_fill_cache(filp, dirent, filldir, name, len, 2460 return proc_fill_cache(filp, dirent, filldir, name, len,
2455 proc_pid_instantiate, task, NULL); 2461 proc_pid_instantiate, iter.task, NULL);
2456} 2462}
2457 2463
2458/* for the /proc/ directory itself, after non-process stuff has been done */ 2464/* for the /proc/ directory itself, after non-process stuff has been done */
@@ -2460,8 +2466,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2460{ 2466{
2461 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; 2467 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
2462 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); 2468 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
2463 struct task_struct *task; 2469 struct tgid_iter iter;
2464 int tgid;
2465 struct pid_namespace *ns; 2470 struct pid_namespace *ns;
2466 2471
2467 if (!reaper) 2472 if (!reaper)
@@ -2474,14 +2479,14 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2474 } 2479 }
2475 2480
2476 ns = filp->f_dentry->d_sb->s_fs_info; 2481 ns = filp->f_dentry->d_sb->s_fs_info;
2477 tgid = filp->f_pos - TGID_OFFSET; 2482 iter.task = NULL;
2478 for (task = next_tgid(tgid, ns); 2483 iter.tgid = filp->f_pos - TGID_OFFSET;
2479 task; 2484 for (iter = next_tgid(ns, iter);
2480 put_task_struct(task), task = next_tgid(tgid + 1, ns)) { 2485 iter.task;
2481 tgid = task_pid_nr_ns(task, ns); 2486 iter.tgid += 1, iter = next_tgid(ns, iter)) {
2482 filp->f_pos = tgid + TGID_OFFSET; 2487 filp->f_pos = iter.tgid + TGID_OFFSET;
2483 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { 2488 if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
2484 put_task_struct(task); 2489 put_task_struct(iter.task);
2485 goto out; 2490 goto out;
2486 } 2491 }
2487 } 2492 }
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index c2b752341f89..5fccfe222a63 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -565,41 +565,6 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
565 return 0; 565 return 0;
566} 566}
567 567
568/*
569 * Kill an inode that got unregistered..
570 */
571static void proc_kill_inodes(struct proc_dir_entry *de)
572{
573 struct list_head *p;
574 struct super_block *sb;
575
576 /*
577 * Actually it's a partial revoke().
578 */
579 spin_lock(&sb_lock);
580 list_for_each_entry(sb, &proc_fs_type.fs_supers, s_instances) {
581 file_list_lock();
582 list_for_each(p, &sb->s_files) {
583 struct file *filp = list_entry(p, struct file,
584 f_u.fu_list);
585 struct dentry *dentry = filp->f_path.dentry;
586 struct inode *inode;
587 const struct file_operations *fops;
588
589 if (dentry->d_op != &proc_dentry_operations)
590 continue;
591 inode = dentry->d_inode;
592 if (PDE(inode) != de)
593 continue;
594 fops = filp->f_op;
595 filp->f_op = NULL;
596 fops_put(fops);
597 }
598 file_list_unlock();
599 }
600 spin_unlock(&sb_lock);
601}
602
603static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent, 568static struct proc_dir_entry *proc_create(struct proc_dir_entry **parent,
604 const char *name, 569 const char *name,
605 mode_t mode, 570 mode_t mode,
@@ -774,8 +739,6 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
774continue_removing: 739continue_removing:
775 if (S_ISDIR(de->mode)) 740 if (S_ISDIR(de->mode))
776 parent->nlink--; 741 parent->nlink--;
777 if (!S_ISREG(de->mode))
778 proc_kill_inodes(de);
779 de->nlink = 0; 742 de->nlink = 0;
780 WARN_ON(de->subdir); 743 WARN_ON(de->subdir);
781 if (!atomic_read(&de->count)) 744 if (!atomic_read(&de->count))
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 1b2b6c6bb475..1820eb2ef762 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -78,5 +78,3 @@ static inline int proc_fd(struct inode *inode)
78{ 78{
79 return PROC_I(inode)->fd; 79 return PROC_I(inode)->fd;
80} 80}
81
82extern struct file_system_type proc_fs_type;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 1f86bb860e04..ec9cb3b6c93b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -98,7 +98,7 @@ static void proc_kill_sb(struct super_block *sb)
98 put_pid_ns(ns); 98 put_pid_ns(ns);
99} 99}
100 100
101struct file_system_type proc_fs_type = { 101static struct file_system_type proc_fs_type = {
102 .name = "proc", 102 .name = "proc",
103 .get_sb = proc_get_sb, 103 .get_sb = proc_get_sb,
104 .kill_sb = proc_kill_sb, 104 .kill_sb = proc_kill_sb,