aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2010-07-10 17:52:49 -0400
committerEric W. Biederman <ebiederm@xmission.com>2012-11-19 06:09:34 -0500
commite656d8a6f7fdf7612d2f5771f0ddfca9487f59d9 (patch)
tree66479ae4b636517e0e54e78b4ec95acadd0aec7a /fs/proc/base.c
parentdd34ad35c32bb3d16789d8d4084aead7e68a7b09 (diff)
procfs: Use the proc generic infrastructure for proc/self.
I had visions at one point of splitting proc into two filesystems. If that had happened proc/self being the the part of proc that actually deals with pids would have been a nice cleanup. As it is proc/self requires a lot of unnecessary infrastructure for a single file. The only user visible change is that a mounted /proc for a pid namespace that is dead now shows a broken proc symlink, instead of being completely invisible. I don't think anyone will notice or care. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c154
1 files changed, 2 insertions, 152 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 144a96732dd7..cbe454e94af8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2237,146 +2237,6 @@ static const struct file_operations proc_coredump_filter_operations = {
2237}; 2237};
2238#endif 2238#endif
2239 2239
2240/*
2241 * /proc/self:
2242 */
2243static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
2244 int buflen)
2245{
2246 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2247 pid_t tgid = task_tgid_nr_ns(current, ns);
2248 char tmp[PROC_NUMBUF];
2249 if (!tgid)
2250 return -ENOENT;
2251 sprintf(tmp, "%d", tgid);
2252 return vfs_readlink(dentry,buffer,buflen,tmp);
2253}
2254
2255static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
2256{
2257 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2258 pid_t tgid = task_tgid_nr_ns(current, ns);
2259 char *name = ERR_PTR(-ENOENT);
2260 if (tgid) {
2261 /* 11 for max length of signed int in decimal + NULL term */
2262 name = kmalloc(12, GFP_KERNEL);
2263 if (!name)
2264 name = ERR_PTR(-ENOMEM);
2265 else
2266 sprintf(name, "%d", tgid);
2267 }
2268 nd_set_link(nd, name);
2269 return NULL;
2270}
2271
2272static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
2273 void *cookie)
2274{
2275 char *s = nd_get_link(nd);
2276 if (!IS_ERR(s))
2277 kfree(s);
2278}
2279
2280static const struct inode_operations proc_self_inode_operations = {
2281 .readlink = proc_self_readlink,
2282 .follow_link = proc_self_follow_link,
2283 .put_link = proc_self_put_link,
2284};
2285
2286/*
2287 * proc base
2288 *
2289 * These are the directory entries in the root directory of /proc
2290 * that properly belong to the /proc filesystem, as they describe
2291 * describe something that is process related.
2292 */
2293static const struct pid_entry proc_base_stuff[] = {
2294 NOD("self", S_IFLNK|S_IRWXUGO,
2295 &proc_self_inode_operations, NULL, {}),
2296};
2297
2298static struct dentry *proc_base_instantiate(struct inode *dir,
2299 struct dentry *dentry, struct task_struct *task, const void *ptr)
2300{
2301 const struct pid_entry *p = ptr;
2302 struct inode *inode;
2303 struct proc_inode *ei;
2304 struct dentry *error;
2305
2306 /* Allocate the inode */
2307 error = ERR_PTR(-ENOMEM);
2308 inode = new_inode(dir->i_sb);
2309 if (!inode)
2310 goto out;
2311
2312 /* Initialize the inode */
2313 ei = PROC_I(inode);
2314 inode->i_ino = get_next_ino();
2315 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2316
2317 /*
2318 * grab the reference to the task.
2319 */
2320 ei->pid = get_task_pid(task, PIDTYPE_PID);
2321 if (!ei->pid)
2322 goto out_iput;
2323
2324 inode->i_mode = p->mode;
2325 if (S_ISDIR(inode->i_mode))
2326 set_nlink(inode, 2);
2327 if (S_ISLNK(inode->i_mode))
2328 inode->i_size = 64;
2329 if (p->iop)
2330 inode->i_op = p->iop;
2331 if (p->fop)
2332 inode->i_fop = p->fop;
2333 ei->op = p->op;
2334 d_add(dentry, inode);
2335 error = NULL;
2336out:
2337 return error;
2338out_iput:
2339 iput(inode);
2340 goto out;
2341}
2342
2343static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
2344{
2345 struct dentry *error;
2346 struct task_struct *task = get_proc_task(dir);
2347 const struct pid_entry *p, *last;
2348
2349 error = ERR_PTR(-ENOENT);
2350
2351 if (!task)
2352 goto out_no_task;
2353
2354 /* Lookup the directory entry */
2355 last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1];
2356 for (p = proc_base_stuff; p <= last; p++) {
2357 if (p->len != dentry->d_name.len)
2358 continue;
2359 if (!memcmp(dentry->d_name.name, p->name, p->len))
2360 break;
2361 }
2362 if (p > last)
2363 goto out;
2364
2365 error = proc_base_instantiate(dir, dentry, task, p);
2366
2367out:
2368 put_task_struct(task);
2369out_no_task:
2370 return error;
2371}
2372
2373static int proc_base_fill_cache(struct file *filp, void *dirent,
2374 filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
2375{
2376 return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
2377 proc_base_instantiate, task, p);
2378}
2379
2380#ifdef CONFIG_TASK_IO_ACCOUNTING 2240#ifdef CONFIG_TASK_IO_ACCOUNTING
2381static int do_io_accounting(struct task_struct *task, char *buffer, int whole) 2241static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
2382{ 2242{
@@ -2767,15 +2627,11 @@ out:
2767 2627
2768struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) 2628struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
2769{ 2629{
2770 struct dentry *result; 2630 struct dentry *result = NULL;
2771 struct task_struct *task; 2631 struct task_struct *task;
2772 unsigned tgid; 2632 unsigned tgid;
2773 struct pid_namespace *ns; 2633 struct pid_namespace *ns;
2774 2634
2775 result = proc_base_lookup(dir, dentry);
2776 if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
2777 goto out;
2778
2779 tgid = name_to_int(dentry); 2635 tgid = name_to_int(dentry);
2780 if (tgid == ~0U) 2636 if (tgid == ~0U)
2781 goto out; 2637 goto out;
@@ -2838,7 +2694,7 @@ retry:
2838 return iter; 2694 return iter;
2839} 2695}
2840 2696
2841#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) 2697#define TGID_OFFSET (FIRST_PROCESS_ENTRY)
2842 2698
2843static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 2699static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2844 struct tgid_iter iter) 2700 struct tgid_iter iter)
@@ -2872,12 +2728,6 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2872 if (!reaper) 2728 if (!reaper)
2873 goto out_no_task; 2729 goto out_no_task;
2874 2730
2875 for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
2876 const struct pid_entry *p = &proc_base_stuff[nr];
2877 if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
2878 goto out;
2879 }
2880
2881 ns = filp->f_dentry->d_sb->s_fs_info; 2731 ns = filp->f_dentry->d_sb->s_fs_info;
2882 iter.task = NULL; 2732 iter.task = NULL;
2883 iter.tgid = filp->f_pos - TGID_OFFSET; 2733 iter.tgid = filp->f_pos - TGID_OFFSET;