aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 21:10:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 21:10:18 -0400
commit08615d7d85e5aa02c05bf6c4dde87d940e7f85f6 (patch)
tree18906149d313d25914160aca21cedf54b3a7e818 /fs/proc/base.c
parent9fdadb2cbaf4b482dfd6086e8bd3d2db071a1702 (diff)
parent0a4dd35c67b144d8ef9432120105f1aab9293ee9 (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc patches from Andrew Morton: - the "misc" tree - stuff from all over the map - checkpatch updates - fatfs - kmod changes - procfs - cpumask - UML - kexec - mqueue - rapidio - pidns - some checkpoint-restore feature work. Reluctantly. Most of it delayed a release. I'm still rather worried that we don't have a clear roadmap to completion for this work. * emailed from Andrew Morton <akpm@linux-foundation.org>: (78 patches) kconfig: update compression algorithm info c/r: prctl: add ability to set new mm_struct::exe_file c/r: prctl: extend PR_SET_MM to set up more mm_struct entries c/r: procfs: add arg_start/end, env_start/end and exit_code members to /proc/$pid/stat syscalls, x86: add __NR_kcmp syscall fs, proc: introduce /proc/<pid>/task/<tid>/children entry sysctl: make kernel.ns_last_pid control dependent on CHECKPOINT_RESTORE aio/vfs: cleanup of rw_copy_check_uvector() and compat_rw_copy_check_uvector() eventfd: change int to __u64 in eventfd_signal() fs/nls: add Apple NLS pidns: make killed children autoreap pidns: use task_active_pid_ns in do_notify_parent rapidio/tsi721: add DMA engine support rapidio: add DMA engine support for RIO data transfers ipc/mqueue: add rbtree node caching support tools/selftests: add mq_perf_tests ipc/mqueue: strengthen checks on mqueue creation ipc/mqueue: correct mq_attr_ok test ipc/mqueue: improve performance of send/recv selftests: add mq_open_tests ...
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c81
1 files changed, 40 insertions, 41 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d7d711876b6a..616f41a7cde6 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -199,11 +199,6 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
199 return result; 199 return result;
200} 200}
201 201
202struct mm_struct *mm_for_maps(struct task_struct *task)
203{
204 return mm_access(task, PTRACE_MODE_READ);
205}
206
207static int proc_pid_cmdline(struct task_struct *task, char * buffer) 202static int proc_pid_cmdline(struct task_struct *task, char * buffer)
208{ 203{
209 int res = 0; 204 int res = 0;
@@ -243,7 +238,7 @@ out:
243 238
244static int proc_pid_auxv(struct task_struct *task, char *buffer) 239static int proc_pid_auxv(struct task_struct *task, char *buffer)
245{ 240{
246 struct mm_struct *mm = mm_for_maps(task); 241 struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ);
247 int res = PTR_ERR(mm); 242 int res = PTR_ERR(mm);
248 if (mm && !IS_ERR(mm)) { 243 if (mm && !IS_ERR(mm)) {
249 unsigned int nwords = 0; 244 unsigned int nwords = 0;
@@ -679,7 +674,7 @@ static const struct file_operations proc_single_file_operations = {
679 .release = single_release, 674 .release = single_release,
680}; 675};
681 676
682static int mem_open(struct inode* inode, struct file* file) 677static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
683{ 678{
684 struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); 679 struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
685 struct mm_struct *mm; 680 struct mm_struct *mm;
@@ -687,7 +682,7 @@ static int mem_open(struct inode* inode, struct file* file)
687 if (!task) 682 if (!task)
688 return -ESRCH; 683 return -ESRCH;
689 684
690 mm = mm_access(task, PTRACE_MODE_ATTACH); 685 mm = mm_access(task, mode);
691 put_task_struct(task); 686 put_task_struct(task);
692 687
693 if (IS_ERR(mm)) 688 if (IS_ERR(mm))
@@ -707,6 +702,11 @@ static int mem_open(struct inode* inode, struct file* file)
707 return 0; 702 return 0;
708} 703}
709 704
705static int mem_open(struct inode *inode, struct file *file)
706{
707 return __mem_open(inode, file, PTRACE_MODE_ATTACH);
708}
709
710static ssize_t mem_rw(struct file *file, char __user *buf, 710static ssize_t mem_rw(struct file *file, char __user *buf,
711 size_t count, loff_t *ppos, int write) 711 size_t count, loff_t *ppos, int write)
712{ 712{
@@ -803,30 +803,29 @@ static const struct file_operations proc_mem_operations = {
803 .release = mem_release, 803 .release = mem_release,
804}; 804};
805 805
806static int environ_open(struct inode *inode, struct file *file)
807{
808 return __mem_open(inode, file, PTRACE_MODE_READ);
809}
810
806static ssize_t environ_read(struct file *file, char __user *buf, 811static ssize_t environ_read(struct file *file, char __user *buf,
807 size_t count, loff_t *ppos) 812 size_t count, loff_t *ppos)
808{ 813{
809 struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
810 char *page; 814 char *page;
811 unsigned long src = *ppos; 815 unsigned long src = *ppos;
812 int ret = -ESRCH; 816 int ret = 0;
813 struct mm_struct *mm; 817 struct mm_struct *mm = file->private_data;
814 818
815 if (!task) 819 if (!mm)
816 goto out_no_task; 820 return 0;
817 821
818 ret = -ENOMEM;
819 page = (char *)__get_free_page(GFP_TEMPORARY); 822 page = (char *)__get_free_page(GFP_TEMPORARY);
820 if (!page) 823 if (!page)
821 goto out; 824 return -ENOMEM;
822
823
824 mm = mm_for_maps(task);
825 ret = PTR_ERR(mm);
826 if (!mm || IS_ERR(mm))
827 goto out_free;
828 825
829 ret = 0; 826 ret = 0;
827 if (!atomic_inc_not_zero(&mm->mm_users))
828 goto free;
830 while (count > 0) { 829 while (count > 0) {
831 int this_len, retval, max_len; 830 int this_len, retval, max_len;
832 831
@@ -838,7 +837,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
838 max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; 837 max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
839 this_len = (this_len > max_len) ? max_len : this_len; 838 this_len = (this_len > max_len) ? max_len : this_len;
840 839
841 retval = access_process_vm(task, (mm->env_start + src), 840 retval = access_remote_vm(mm, (mm->env_start + src),
842 page, this_len, 0); 841 page, this_len, 0);
843 842
844 if (retval <= 0) { 843 if (retval <= 0) {
@@ -857,19 +856,18 @@ static ssize_t environ_read(struct file *file, char __user *buf,
857 count -= retval; 856 count -= retval;
858 } 857 }
859 *ppos = src; 858 *ppos = src;
860
861 mmput(mm); 859 mmput(mm);
862out_free: 860
861free:
863 free_page((unsigned long) page); 862 free_page((unsigned long) page);
864out:
865 put_task_struct(task);
866out_no_task:
867 return ret; 863 return ret;
868} 864}
869 865
870static const struct file_operations proc_environ_operations = { 866static const struct file_operations proc_environ_operations = {
867 .open = environ_open,
871 .read = environ_read, 868 .read = environ_read,
872 .llseek = generic_file_llseek, 869 .llseek = generic_file_llseek,
870 .release = mem_release,
873}; 871};
874 872
875static ssize_t oom_adjust_read(struct file *file, char __user *buf, 873static ssize_t oom_adjust_read(struct file *file, char __user *buf,
@@ -1850,7 +1848,7 @@ static const struct dentry_operations tid_fd_dentry_operations =
1850static struct dentry *proc_fd_instantiate(struct inode *dir, 1848static struct dentry *proc_fd_instantiate(struct inode *dir,
1851 struct dentry *dentry, struct task_struct *task, const void *ptr) 1849 struct dentry *dentry, struct task_struct *task, const void *ptr)
1852{ 1850{
1853 unsigned fd = *(const unsigned *)ptr; 1851 unsigned fd = (unsigned long)ptr;
1854 struct inode *inode; 1852 struct inode *inode;
1855 struct proc_inode *ei; 1853 struct proc_inode *ei;
1856 struct dentry *error = ERR_PTR(-ENOENT); 1854 struct dentry *error = ERR_PTR(-ENOENT);
@@ -1887,7 +1885,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
1887 if (fd == ~0U) 1885 if (fd == ~0U)
1888 goto out; 1886 goto out;
1889 1887
1890 result = instantiate(dir, dentry, task, &fd); 1888 result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
1891out: 1889out:
1892 put_task_struct(task); 1890 put_task_struct(task);
1893out_no_task: 1891out_no_task:
@@ -1930,21 +1928,22 @@ static int proc_readfd_common(struct file * filp, void * dirent,
1930 fd++, filp->f_pos++) { 1928 fd++, filp->f_pos++) {
1931 char name[PROC_NUMBUF]; 1929 char name[PROC_NUMBUF];
1932 int len; 1930 int len;
1931 int rv;
1933 1932
1934 if (!fcheck_files(files, fd)) 1933 if (!fcheck_files(files, fd))
1935 continue; 1934 continue;
1936 rcu_read_unlock(); 1935 rcu_read_unlock();
1937 1936
1938 len = snprintf(name, sizeof(name), "%d", fd); 1937 len = snprintf(name, sizeof(name), "%d", fd);
1939 if (proc_fill_cache(filp, dirent, filldir, 1938 rv = proc_fill_cache(filp, dirent, filldir,
1940 name, len, instantiate, 1939 name, len, instantiate, p,
1941 p, &fd) < 0) { 1940 (void *)(unsigned long)fd);
1942 rcu_read_lock(); 1941 if (rv < 0)
1943 break; 1942 goto out_fd_loop;
1944 }
1945 rcu_read_lock(); 1943 rcu_read_lock();
1946 } 1944 }
1947 rcu_read_unlock(); 1945 rcu_read_unlock();
1946out_fd_loop:
1948 put_files_struct(files); 1947 put_files_struct(files);
1949 } 1948 }
1950out: 1949out:
@@ -2024,11 +2023,8 @@ static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd)
2024 if (!task) 2023 if (!task)
2025 goto out_notask; 2024 goto out_notask;
2026 2025
2027 if (!ptrace_may_access(task, PTRACE_MODE_READ)) 2026 mm = mm_access(task, PTRACE_MODE_READ);
2028 goto out; 2027 if (IS_ERR_OR_NULL(mm))
2029
2030 mm = get_task_mm(task);
2031 if (!mm)
2032 goto out; 2028 goto out;
2033 2029
2034 if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) { 2030 if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
@@ -2357,7 +2353,7 @@ static const struct inode_operations proc_fd_inode_operations = {
2357static struct dentry *proc_fdinfo_instantiate(struct inode *dir, 2353static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
2358 struct dentry *dentry, struct task_struct *task, const void *ptr) 2354 struct dentry *dentry, struct task_struct *task, const void *ptr)
2359{ 2355{
2360 unsigned fd = *(unsigned *)ptr; 2356 unsigned fd = (unsigned long)ptr;
2361 struct inode *inode; 2357 struct inode *inode;
2362 struct proc_inode *ei; 2358 struct proc_inode *ei;
2363 struct dentry *error = ERR_PTR(-ENOENT); 2359 struct dentry *error = ERR_PTR(-ENOENT);
@@ -3404,6 +3400,9 @@ static const struct pid_entry tid_base_stuff[] = {
3404 ONE("stat", S_IRUGO, proc_tid_stat), 3400 ONE("stat", S_IRUGO, proc_tid_stat),
3405 ONE("statm", S_IRUGO, proc_pid_statm), 3401 ONE("statm", S_IRUGO, proc_pid_statm),
3406 REG("maps", S_IRUGO, proc_tid_maps_operations), 3402 REG("maps", S_IRUGO, proc_tid_maps_operations),
3403#ifdef CONFIG_CHECKPOINT_RESTORE
3404 REG("children", S_IRUGO, proc_tid_children_operations),
3405#endif
3407#ifdef CONFIG_NUMA 3406#ifdef CONFIG_NUMA
3408 REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations), 3407 REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations),
3409#endif 3408#endif