diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2010-07-10 14:52:49 -0700 | 
|---|---|---|
| committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-19 03:09:34 -0800 | 
| commit | e656d8a6f7fdf7612d2f5771f0ddfca9487f59d9 (patch) | |
| tree | 66479ae4b636517e0e54e78b4ec95acadd0aec7a /fs/proc/base.c | |
| parent | dd34ad35c32bb3d16789d8d4084aead7e68a7b09 (diff) | |
| download | olio-linux-3.10-e656d8a6f7fdf7612d2f5771f0ddfca9487f59d9.tar.xz olio-linux-3.10-e656d8a6f7fdf7612d2f5771f0ddfca9487f59d9.zip  | |
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.c | 154 | 
1 files changed, 2 insertions, 152 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 144a96732dd..cbe454e94af 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2237,146 +2237,6 @@ static const struct file_operations proc_coredump_filter_operations = {  };  #endif -/* - * /proc/self: - */ -static int proc_self_readlink(struct dentry *dentry, char __user *buffer, -			      int buflen) -{ -	struct pid_namespace *ns = dentry->d_sb->s_fs_info; -	pid_t tgid = task_tgid_nr_ns(current, ns); -	char tmp[PROC_NUMBUF]; -	if (!tgid) -		return -ENOENT; -	sprintf(tmp, "%d", tgid); -	return vfs_readlink(dentry,buffer,buflen,tmp); -} - -static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) -{ -	struct pid_namespace *ns = dentry->d_sb->s_fs_info; -	pid_t tgid = task_tgid_nr_ns(current, ns); -	char *name = ERR_PTR(-ENOENT); -	if (tgid) { -		/* 11 for max length of signed int in decimal + NULL term */ -		name = kmalloc(12, GFP_KERNEL); -		if (!name) -			name = ERR_PTR(-ENOMEM); -		else -			sprintf(name, "%d", tgid); -	} -	nd_set_link(nd, name); -	return NULL; -} - -static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, -				void *cookie) -{ -	char *s = nd_get_link(nd); -	if (!IS_ERR(s)) -		kfree(s); -} - -static const struct inode_operations proc_self_inode_operations = { -	.readlink	= proc_self_readlink, -	.follow_link	= proc_self_follow_link, -	.put_link	= proc_self_put_link, -}; - -/* - * proc base - * - * These are the directory entries in the root directory of /proc - * that properly belong to the /proc filesystem, as they describe - * describe something that is process related. - */ -static const struct pid_entry proc_base_stuff[] = { -	NOD("self", S_IFLNK|S_IRWXUGO, -		&proc_self_inode_operations, NULL, {}), -}; - -static struct dentry *proc_base_instantiate(struct inode *dir, -	struct dentry *dentry, struct task_struct *task, const void *ptr) -{ -	const struct pid_entry *p = ptr; -	struct inode *inode; -	struct proc_inode *ei; -	struct dentry *error; - -	/* Allocate the inode */ -	error = ERR_PTR(-ENOMEM); -	inode = new_inode(dir->i_sb); -	if (!inode) -		goto out; - -	/* Initialize the inode */ -	ei = PROC_I(inode); -	inode->i_ino = get_next_ino(); -	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - -	/* -	 * grab the reference to the task. -	 */ -	ei->pid = get_task_pid(task, PIDTYPE_PID); -	if (!ei->pid) -		goto out_iput; - -	inode->i_mode = p->mode; -	if (S_ISDIR(inode->i_mode)) -		set_nlink(inode, 2); -	if (S_ISLNK(inode->i_mode)) -		inode->i_size = 64; -	if (p->iop) -		inode->i_op = p->iop; -	if (p->fop) -		inode->i_fop = p->fop; -	ei->op = p->op; -	d_add(dentry, inode); -	error = NULL; -out: -	return error; -out_iput: -	iput(inode); -	goto out; -} - -static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) -{ -	struct dentry *error; -	struct task_struct *task = get_proc_task(dir); -	const struct pid_entry *p, *last; - -	error = ERR_PTR(-ENOENT); - -	if (!task) -		goto out_no_task; - -	/* Lookup the directory entry */ -	last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1]; -	for (p = proc_base_stuff; p <= last; p++) { -		if (p->len != dentry->d_name.len) -			continue; -		if (!memcmp(dentry->d_name.name, p->name, p->len)) -			break; -	} -	if (p > last) -		goto out; - -	error = proc_base_instantiate(dir, dentry, task, p); - -out: -	put_task_struct(task); -out_no_task: -	return error; -} - -static int proc_base_fill_cache(struct file *filp, void *dirent, -	filldir_t filldir, struct task_struct *task, const struct pid_entry *p) -{ -	return proc_fill_cache(filp, dirent, filldir, p->name, p->len, -				proc_base_instantiate, task, p); -} -  #ifdef CONFIG_TASK_IO_ACCOUNTING  static int do_io_accounting(struct task_struct *task, char *buffer, int whole)  { @@ -2767,15 +2627,11 @@ out:  struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)  { -	struct dentry *result; +	struct dentry *result = NULL;  	struct task_struct *task;  	unsigned tgid;  	struct pid_namespace *ns; -	result = proc_base_lookup(dir, dentry); -	if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) -		goto out; -  	tgid = name_to_int(dentry);  	if (tgid == ~0U)  		goto out; @@ -2838,7 +2694,7 @@ retry:  	return iter;  } -#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) +#define TGID_OFFSET (FIRST_PROCESS_ENTRY)  static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,  	struct tgid_iter iter) @@ -2872,12 +2728,6 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)  	if (!reaper)  		goto out_no_task; -	for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { -		const struct pid_entry *p = &proc_base_stuff[nr]; -		if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) -			goto out; -	} -  	ns = filp->f_dentry->d_sb->s_fs_info;  	iter.task = NULL;  	iter.tgid = filp->f_pos - TGID_OFFSET;  |