diff options
| author | Steve French <sfrench@us.ibm.com> | 2011-12-16 10:39:20 +0400 | 
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2011-12-16 10:39:20 +0400 | 
| commit | aaf015890754d58dcb71a4aa44ed246bb082bcf6 (patch) | |
| tree | 17b51ff707fd1b3efec3a3ab872f0d7a7416aca5 /fs/proc/base.c | |
| parent | 9c32c63bb70b2fafc3b18bee29959c3bf245ceba (diff) | |
| parent | 8def5f51b012efb00e77ba2d04696cc0aadd0609 (diff) | |
| download | linux-aaf015890754d58dcb71a4aa44ed246bb082bcf6.tar.xz | |
Merge branch 'master' of git+ssh://git.samba.org/data/git/sfrench/cifs-2.6
Diffstat (limited to 'fs/proc/base.c')
| -rw-r--r-- | fs/proc/base.c | 146 | 
1 files changed, 43 insertions, 103 deletions
| diff --git a/fs/proc/base.c b/fs/proc/base.c index 2db1bd3173b2..851ba3dcdc29 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1652,46 +1652,12 @@ out:  	return error;  } -static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry, -		struct kstat *stat) -{ -	struct inode *inode = dentry->d_inode; -	struct task_struct *task = get_proc_task(inode); -	int rc; - -	if (task == NULL) -		return -ESRCH; - -	rc = -EACCES; -	if (lock_trace(task)) -		goto out_task; - -	generic_fillattr(inode, stat); -	unlock_trace(task); -	rc = 0; -out_task: -	put_task_struct(task); -	return rc; -} -  static const struct inode_operations proc_pid_link_inode_operations = {  	.readlink	= proc_pid_readlink,  	.follow_link	= proc_pid_follow_link,  	.setattr	= proc_setattr,  }; -static const struct inode_operations proc_fdinfo_link_inode_operations = { -	.setattr	= proc_setattr, -	.getattr	= proc_pid_fd_link_getattr, -}; - -static const struct inode_operations proc_fd_link_inode_operations = { -	.readlink	= proc_pid_readlink, -	.follow_link	= proc_pid_follow_link, -	.setattr	= proc_setattr, -	.getattr	= proc_pid_fd_link_getattr, -}; -  /* building an inode */ @@ -1923,61 +1889,49 @@ out:  static int proc_fd_info(struct inode *inode, struct path *path, char *info)  { -	struct task_struct *task; -	struct files_struct *files; +	struct task_struct *task = get_proc_task(inode); +	struct files_struct *files = NULL;  	struct file *file;  	int fd = proc_fd(inode); -	int rc; - -	task = get_proc_task(inode); -	if (!task) -		return -ENOENT; - -	rc = -EACCES; -	if (lock_trace(task)) -		goto out_task; - -	rc = -ENOENT; -	files = get_files_struct(task); -	if (files == NULL) -		goto out_unlock; -	/* -	 * We are not taking a ref to the file structure, so we must -	 * hold ->file_lock. -	 */ -	spin_lock(&files->file_lock); -	file = fcheck_files(files, fd); -	if (file) { -		unsigned int f_flags; -		struct fdtable *fdt; - -		fdt = files_fdtable(files); -		f_flags = file->f_flags & ~O_CLOEXEC; -		if (FD_ISSET(fd, fdt->close_on_exec)) -			f_flags |= O_CLOEXEC; - -		if (path) { -			*path = file->f_path; -			path_get(&file->f_path); +	if (task) { +		files = get_files_struct(task); +		put_task_struct(task); +	} +	if (files) { +		/* +		 * We are not taking a ref to the file structure, so we must +		 * hold ->file_lock. +		 */ +		spin_lock(&files->file_lock); +		file = fcheck_files(files, fd); +		if (file) { +			unsigned int f_flags; +			struct fdtable *fdt; + +			fdt = files_fdtable(files); +			f_flags = file->f_flags & ~O_CLOEXEC; +			if (FD_ISSET(fd, fdt->close_on_exec)) +				f_flags |= O_CLOEXEC; + +			if (path) { +				*path = file->f_path; +				path_get(&file->f_path); +			} +			if (info) +				snprintf(info, PROC_FDINFO_MAX, +					 "pos:\t%lli\n" +					 "flags:\t0%o\n", +					 (long long) file->f_pos, +					 f_flags); +			spin_unlock(&files->file_lock); +			put_files_struct(files); +			return 0;  		} -		if (info) -			snprintf(info, PROC_FDINFO_MAX, -				 "pos:\t%lli\n" -				 "flags:\t0%o\n", -				 (long long) file->f_pos, -				 f_flags); -		rc = 0; -	} else -		rc = -ENOENT; -	spin_unlock(&files->file_lock); -	put_files_struct(files); - -out_unlock: -	unlock_trace(task); -out_task: -	put_task_struct(task); -	return rc; +		spin_unlock(&files->file_lock); +		put_files_struct(files); +	} +	return -ENOENT;  }  static int proc_fd_link(struct inode *inode, struct path *path) @@ -2072,7 +2026,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,  	spin_unlock(&files->file_lock);  	put_files_struct(files); -	inode->i_op = &proc_fd_link_inode_operations; +	inode->i_op = &proc_pid_link_inode_operations;  	inode->i_size = 64;  	ei->op.proc_get_link = proc_fd_link;  	d_set_d_op(dentry, &tid_fd_dentry_operations); @@ -2104,12 +2058,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,  	if (fd == ~0U)  		goto out; -	result = ERR_PTR(-EACCES); -	if (lock_trace(task)) -		goto out; -  	result = instantiate(dir, dentry, task, &fd); -	unlock_trace(task);  out:  	put_task_struct(task);  out_no_task: @@ -2129,28 +2078,23 @@ static int proc_readfd_common(struct file * filp, void * dirent,  	retval = -ENOENT;  	if (!p)  		goto out_no_task; - -	retval = -EACCES; -	if (lock_trace(p)) -		goto out; -  	retval = 0;  	fd = filp->f_pos;  	switch (fd) {  		case 0:  			if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) -				goto out_unlock; +				goto out;  			filp->f_pos++;  		case 1:  			ino = parent_ino(dentry);  			if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) -				goto out_unlock; +				goto out;  			filp->f_pos++;  		default:  			files = get_files_struct(p);  			if (!files) -				goto out_unlock; +				goto out;  			rcu_read_lock();  			for (fd = filp->f_pos-2;  			     fd < files_fdtable(files)->max_fds; @@ -2174,9 +2118,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,  			rcu_read_unlock();  			put_files_struct(files);  	} - -out_unlock: -	unlock_trace(p);  out:  	put_task_struct(p);  out_no_task: @@ -2254,7 +2195,6 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,  	ei->fd = fd;  	inode->i_mode = S_IFREG | S_IRUSR;  	inode->i_fop = &proc_fdinfo_file_operations; -	inode->i_op = &proc_fdinfo_link_inode_operations;  	d_set_d_op(dentry, &tid_fd_dentry_operations);  	d_add(dentry, inode);  	/* Close the race of the process dying before we return the dentry */ | 
