diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 21510c9aa89c..db7636041c10 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1937,14 +1937,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | |||
1937 | int buflen) | 1937 | int buflen) |
1938 | { | 1938 | { |
1939 | char tmp[PROC_NUMBUF]; | 1939 | char tmp[PROC_NUMBUF]; |
1940 | sprintf(tmp, "%d", current->tgid); | 1940 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1941 | return vfs_readlink(dentry,buffer,buflen,tmp); | 1941 | return vfs_readlink(dentry,buffer,buflen,tmp); |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 1944 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
1945 | { | 1945 | { |
1946 | char tmp[PROC_NUMBUF]; | 1946 | char tmp[PROC_NUMBUF]; |
1947 | sprintf(tmp, "%d", current->tgid); | 1947 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1948 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 1948 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
1949 | } | 1949 | } |
1950 | 1950 | ||
@@ -2316,6 +2316,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2316 | struct dentry *result = ERR_PTR(-ENOENT); | 2316 | struct dentry *result = ERR_PTR(-ENOENT); |
2317 | struct task_struct *task; | 2317 | struct task_struct *task; |
2318 | unsigned tgid; | 2318 | unsigned tgid; |
2319 | struct pid_namespace *ns; | ||
2319 | 2320 | ||
2320 | result = proc_base_lookup(dir, dentry); | 2321 | result = proc_base_lookup(dir, dentry); |
2321 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) | 2322 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) |
@@ -2325,8 +2326,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2325 | if (tgid == ~0U) | 2326 | if (tgid == ~0U) |
2326 | goto out; | 2327 | goto out; |
2327 | 2328 | ||
2329 | ns = dentry->d_sb->s_fs_info; | ||
2328 | rcu_read_lock(); | 2330 | rcu_read_lock(); |
2329 | task = find_task_by_pid(tgid); | 2331 | task = find_task_by_pid_ns(tgid, ns); |
2330 | if (task) | 2332 | if (task) |
2331 | get_task_struct(task); | 2333 | get_task_struct(task); |
2332 | rcu_read_unlock(); | 2334 | rcu_read_unlock(); |
@@ -2343,7 +2345,8 @@ out: | |||
2343 | * Find the first task with tgid >= tgid | 2345 | * Find the first task with tgid >= tgid |
2344 | * | 2346 | * |
2345 | */ | 2347 | */ |
2346 | static struct task_struct *next_tgid(unsigned int tgid) | 2348 | static struct task_struct *next_tgid(unsigned int tgid, |
2349 | struct pid_namespace *ns) | ||
2347 | { | 2350 | { |
2348 | struct task_struct *task; | 2351 | struct task_struct *task; |
2349 | struct pid *pid; | 2352 | struct pid *pid; |
@@ -2351,9 +2354,9 @@ static struct task_struct *next_tgid(unsigned int tgid) | |||
2351 | rcu_read_lock(); | 2354 | rcu_read_lock(); |
2352 | retry: | 2355 | retry: |
2353 | task = NULL; | 2356 | task = NULL; |
2354 | pid = find_ge_pid(tgid, &init_pid_ns); | 2357 | pid = find_ge_pid(tgid, ns); |
2355 | if (pid) { | 2358 | if (pid) { |
2356 | tgid = pid->nr + 1; | 2359 | tgid = pid_nr_ns(pid, ns) + 1; |
2357 | task = pid_task(pid, PIDTYPE_PID); | 2360 | task = pid_task(pid, PIDTYPE_PID); |
2358 | /* What we to know is if the pid we have find is the | 2361 | /* What we to know is if the pid we have find is the |
2359 | * pid of a thread_group_leader. Testing for task | 2362 | * pid of a thread_group_leader. Testing for task |
@@ -2393,6 +2396,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2393 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); | 2396 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
2394 | struct task_struct *task; | 2397 | struct task_struct *task; |
2395 | int tgid; | 2398 | int tgid; |
2399 | struct pid_namespace *ns; | ||
2396 | 2400 | ||
2397 | if (!reaper) | 2401 | if (!reaper) |
2398 | goto out_no_task; | 2402 | goto out_no_task; |
@@ -2403,11 +2407,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2403 | goto out; | 2407 | goto out; |
2404 | } | 2408 | } |
2405 | 2409 | ||
2410 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2406 | tgid = filp->f_pos - TGID_OFFSET; | 2411 | tgid = filp->f_pos - TGID_OFFSET; |
2407 | for (task = next_tgid(tgid); | 2412 | for (task = next_tgid(tgid, ns); |
2408 | task; | 2413 | task; |
2409 | put_task_struct(task), task = next_tgid(tgid + 1)) { | 2414 | put_task_struct(task), task = next_tgid(tgid + 1, ns)) { |
2410 | tgid = task->pid; | 2415 | tgid = task_pid_nr_ns(task, ns); |
2411 | filp->f_pos = tgid + TGID_OFFSET; | 2416 | filp->f_pos = tgid + TGID_OFFSET; |
2412 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { | 2417 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { |
2413 | put_task_struct(task); | 2418 | put_task_struct(task); |
@@ -2531,6 +2536,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2531 | struct task_struct *task; | 2536 | struct task_struct *task; |
2532 | struct task_struct *leader = get_proc_task(dir); | 2537 | struct task_struct *leader = get_proc_task(dir); |
2533 | unsigned tid; | 2538 | unsigned tid; |
2539 | struct pid_namespace *ns; | ||
2534 | 2540 | ||
2535 | if (!leader) | 2541 | if (!leader) |
2536 | goto out_no_task; | 2542 | goto out_no_task; |
@@ -2539,8 +2545,9 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2539 | if (tid == ~0U) | 2545 | if (tid == ~0U) |
2540 | goto out; | 2546 | goto out; |
2541 | 2547 | ||
2548 | ns = dentry->d_sb->s_fs_info; | ||
2542 | rcu_read_lock(); | 2549 | rcu_read_lock(); |
2543 | task = find_task_by_pid(tid); | 2550 | task = find_task_by_pid_ns(tid, ns); |
2544 | if (task) | 2551 | if (task) |
2545 | get_task_struct(task); | 2552 | get_task_struct(task); |
2546 | rcu_read_unlock(); | 2553 | rcu_read_unlock(); |
@@ -2571,14 +2578,14 @@ out_no_task: | |||
2571 | * threads past it. | 2578 | * threads past it. |
2572 | */ | 2579 | */ |
2573 | static struct task_struct *first_tid(struct task_struct *leader, | 2580 | static struct task_struct *first_tid(struct task_struct *leader, |
2574 | int tid, int nr) | 2581 | int tid, int nr, struct pid_namespace *ns) |
2575 | { | 2582 | { |
2576 | struct task_struct *pos; | 2583 | struct task_struct *pos; |
2577 | 2584 | ||
2578 | rcu_read_lock(); | 2585 | rcu_read_lock(); |
2579 | /* Attempt to start with the pid of a thread */ | 2586 | /* Attempt to start with the pid of a thread */ |
2580 | if (tid && (nr > 0)) { | 2587 | if (tid && (nr > 0)) { |
2581 | pos = find_task_by_pid(tid); | 2588 | pos = find_task_by_pid_ns(tid, ns); |
2582 | if (pos && (pos->group_leader == leader)) | 2589 | if (pos && (pos->group_leader == leader)) |
2583 | goto found; | 2590 | goto found; |
2584 | } | 2591 | } |
@@ -2647,6 +2654,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2647 | ino_t ino; | 2654 | ino_t ino; |
2648 | int tid; | 2655 | int tid; |
2649 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ | 2656 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ |
2657 | struct pid_namespace *ns; | ||
2650 | 2658 | ||
2651 | task = get_proc_task(inode); | 2659 | task = get_proc_task(inode); |
2652 | if (!task) | 2660 | if (!task) |
@@ -2680,12 +2688,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2680 | /* f_version caches the tgid value that the last readdir call couldn't | 2688 | /* f_version caches the tgid value that the last readdir call couldn't |
2681 | * return. lseek aka telldir automagically resets f_version to 0. | 2689 | * return. lseek aka telldir automagically resets f_version to 0. |
2682 | */ | 2690 | */ |
2691 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2683 | tid = (int)filp->f_version; | 2692 | tid = (int)filp->f_version; |
2684 | filp->f_version = 0; | 2693 | filp->f_version = 0; |
2685 | for (task = first_tid(leader, tid, pos - 2); | 2694 | for (task = first_tid(leader, tid, pos - 2, ns); |
2686 | task; | 2695 | task; |
2687 | task = next_tid(task), pos++) { | 2696 | task = next_tid(task), pos++) { |
2688 | tid = task->pid; | 2697 | tid = task_pid_nr_ns(task, ns); |
2689 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 2698 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { |
2690 | /* returning this tgid failed, save it as the first | 2699 | /* returning this tgid failed, save it as the first |
2691 | * pid for the next readir call */ | 2700 | * pid for the next readir call */ |