diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 169 |
1 files changed, 3 insertions, 166 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index aa63d25157b8..5a5a0be40e40 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2345,146 +2345,6 @@ static const struct file_operations proc_coredump_filter_operations = { | |||
2345 | }; | 2345 | }; |
2346 | #endif | 2346 | #endif |
2347 | 2347 | ||
2348 | /* | ||
2349 | * /proc/self: | ||
2350 | */ | ||
2351 | static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | ||
2352 | int buflen) | ||
2353 | { | ||
2354 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2355 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2356 | char tmp[PROC_NUMBUF]; | ||
2357 | if (!tgid) | ||
2358 | return -ENOENT; | ||
2359 | sprintf(tmp, "%d", tgid); | ||
2360 | return vfs_readlink(dentry,buffer,buflen,tmp); | ||
2361 | } | ||
2362 | |||
2363 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
2364 | { | ||
2365 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2366 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2367 | char *name = ERR_PTR(-ENOENT); | ||
2368 | if (tgid) { | ||
2369 | /* 11 for max length of signed int in decimal + NULL term */ | ||
2370 | name = kmalloc(12, GFP_KERNEL); | ||
2371 | if (!name) | ||
2372 | name = ERR_PTR(-ENOMEM); | ||
2373 | else | ||
2374 | sprintf(name, "%d", tgid); | ||
2375 | } | ||
2376 | nd_set_link(nd, name); | ||
2377 | return NULL; | ||
2378 | } | ||
2379 | |||
2380 | static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, | ||
2381 | void *cookie) | ||
2382 | { | ||
2383 | char *s = nd_get_link(nd); | ||
2384 | if (!IS_ERR(s)) | ||
2385 | kfree(s); | ||
2386 | } | ||
2387 | |||
2388 | static const struct inode_operations proc_self_inode_operations = { | ||
2389 | .readlink = proc_self_readlink, | ||
2390 | .follow_link = proc_self_follow_link, | ||
2391 | .put_link = proc_self_put_link, | ||
2392 | }; | ||
2393 | |||
2394 | /* | ||
2395 | * proc base | ||
2396 | * | ||
2397 | * These are the directory entries in the root directory of /proc | ||
2398 | * that properly belong to the /proc filesystem, as they describe | ||
2399 | * describe something that is process related. | ||
2400 | */ | ||
2401 | static const struct pid_entry proc_base_stuff[] = { | ||
2402 | NOD("self", S_IFLNK|S_IRWXUGO, | ||
2403 | &proc_self_inode_operations, NULL, {}), | ||
2404 | }; | ||
2405 | |||
2406 | static struct dentry *proc_base_instantiate(struct inode *dir, | ||
2407 | struct dentry *dentry, struct task_struct *task, const void *ptr) | ||
2408 | { | ||
2409 | const struct pid_entry *p = ptr; | ||
2410 | struct inode *inode; | ||
2411 | struct proc_inode *ei; | ||
2412 | struct dentry *error; | ||
2413 | |||
2414 | /* Allocate the inode */ | ||
2415 | error = ERR_PTR(-ENOMEM); | ||
2416 | inode = new_inode(dir->i_sb); | ||
2417 | if (!inode) | ||
2418 | goto out; | ||
2419 | |||
2420 | /* Initialize the inode */ | ||
2421 | ei = PROC_I(inode); | ||
2422 | inode->i_ino = get_next_ino(); | ||
2423 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
2424 | |||
2425 | /* | ||
2426 | * grab the reference to the task. | ||
2427 | */ | ||
2428 | ei->pid = get_task_pid(task, PIDTYPE_PID); | ||
2429 | if (!ei->pid) | ||
2430 | goto out_iput; | ||
2431 | |||
2432 | inode->i_mode = p->mode; | ||
2433 | if (S_ISDIR(inode->i_mode)) | ||
2434 | set_nlink(inode, 2); | ||
2435 | if (S_ISLNK(inode->i_mode)) | ||
2436 | inode->i_size = 64; | ||
2437 | if (p->iop) | ||
2438 | inode->i_op = p->iop; | ||
2439 | if (p->fop) | ||
2440 | inode->i_fop = p->fop; | ||
2441 | ei->op = p->op; | ||
2442 | d_add(dentry, inode); | ||
2443 | error = NULL; | ||
2444 | out: | ||
2445 | return error; | ||
2446 | out_iput: | ||
2447 | iput(inode); | ||
2448 | goto out; | ||
2449 | } | ||
2450 | |||
2451 | static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | ||
2452 | { | ||
2453 | struct dentry *error; | ||
2454 | struct task_struct *task = get_proc_task(dir); | ||
2455 | const struct pid_entry *p, *last; | ||
2456 | |||
2457 | error = ERR_PTR(-ENOENT); | ||
2458 | |||
2459 | if (!task) | ||
2460 | goto out_no_task; | ||
2461 | |||
2462 | /* Lookup the directory entry */ | ||
2463 | last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1]; | ||
2464 | for (p = proc_base_stuff; p <= last; p++) { | ||
2465 | if (p->len != dentry->d_name.len) | ||
2466 | continue; | ||
2467 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | ||
2468 | break; | ||
2469 | } | ||
2470 | if (p > last) | ||
2471 | goto out; | ||
2472 | |||
2473 | error = proc_base_instantiate(dir, dentry, task, p); | ||
2474 | |||
2475 | out: | ||
2476 | put_task_struct(task); | ||
2477 | out_no_task: | ||
2478 | return error; | ||
2479 | } | ||
2480 | |||
2481 | static int proc_base_fill_cache(struct file *filp, void *dirent, | ||
2482 | filldir_t filldir, struct task_struct *task, const struct pid_entry *p) | ||
2483 | { | ||
2484 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, | ||
2485 | proc_base_instantiate, task, p); | ||
2486 | } | ||
2487 | |||
2488 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2348 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2489 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | 2349 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2490 | { | 2350 | { |
@@ -2839,10 +2699,6 @@ void proc_flush_task(struct task_struct *task) | |||
2839 | proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, | 2699 | proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, |
2840 | tgid->numbers[i].nr); | 2700 | tgid->numbers[i].nr); |
2841 | } | 2701 | } |
2842 | |||
2843 | upid = &pid->numbers[pid->level]; | ||
2844 | if (upid->nr == 1) | ||
2845 | pid_ns_release_proc(upid->ns); | ||
2846 | } | 2702 | } |
2847 | 2703 | ||
2848 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2704 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
@@ -2876,15 +2732,11 @@ out: | |||
2876 | 2732 | ||
2877 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 2733 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
2878 | { | 2734 | { |
2879 | struct dentry *result; | 2735 | struct dentry *result = NULL; |
2880 | struct task_struct *task; | 2736 | struct task_struct *task; |
2881 | unsigned tgid; | 2737 | unsigned tgid; |
2882 | struct pid_namespace *ns; | 2738 | struct pid_namespace *ns; |
2883 | 2739 | ||
2884 | result = proc_base_lookup(dir, dentry); | ||
2885 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) | ||
2886 | goto out; | ||
2887 | |||
2888 | tgid = name_to_int(dentry); | 2740 | tgid = name_to_int(dentry); |
2889 | if (tgid == ~0U) | 2741 | if (tgid == ~0U) |
2890 | goto out; | 2742 | goto out; |
@@ -2947,7 +2799,7 @@ retry: | |||
2947 | return iter; | 2799 | return iter; |
2948 | } | 2800 | } |
2949 | 2801 | ||
2950 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) | 2802 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY) |
2951 | 2803 | ||
2952 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 2804 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
2953 | struct tgid_iter iter) | 2805 | struct tgid_iter iter) |
@@ -2967,25 +2819,12 @@ static int fake_filldir(void *buf, const char *name, int namelen, | |||
2967 | /* for the /proc/ directory itself, after non-process stuff has been done */ | 2819 | /* for the /proc/ directory itself, after non-process stuff has been done */ |
2968 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | 2820 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) |
2969 | { | 2821 | { |
2970 | unsigned int nr; | ||
2971 | struct task_struct *reaper; | ||
2972 | struct tgid_iter iter; | 2822 | struct tgid_iter iter; |
2973 | struct pid_namespace *ns; | 2823 | struct pid_namespace *ns; |
2974 | filldir_t __filldir; | 2824 | filldir_t __filldir; |
2975 | 2825 | ||
2976 | if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) | 2826 | if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) |
2977 | goto out_no_task; | 2827 | goto out; |
2978 | nr = filp->f_pos - FIRST_PROCESS_ENTRY; | ||
2979 | |||
2980 | reaper = get_proc_task(filp->f_path.dentry->d_inode); | ||
2981 | if (!reaper) | ||
2982 | goto out_no_task; | ||
2983 | |||
2984 | for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { | ||
2985 | const struct pid_entry *p = &proc_base_stuff[nr]; | ||
2986 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) | ||
2987 | goto out; | ||
2988 | } | ||
2989 | 2828 | ||
2990 | ns = filp->f_dentry->d_sb->s_fs_info; | 2829 | ns = filp->f_dentry->d_sb->s_fs_info; |
2991 | iter.task = NULL; | 2830 | iter.task = NULL; |
@@ -3006,8 +2845,6 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
3006 | } | 2845 | } |
3007 | filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET; | 2846 | filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET; |
3008 | out: | 2847 | out: |
3009 | put_task_struct(reaper); | ||
3010 | out_no_task: | ||
3011 | return 0; | 2848 | return 0; |
3012 | } | 2849 | } |
3013 | 2850 | ||