aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c60
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/task_mmu.c6
-rw-r--r--fs/proc/task_nommu.c6
-rw-r--r--include/linux/proc_fs.h2
5 files changed, 34 insertions, 42 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 080f1f6eda61..47338d92db51 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk)
153 return count; 153 return count;
154} 154}
155 155
156static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 156static int proc_cwd_link(struct inode *inode, struct path *path)
157{ 157{
158 struct task_struct *task = get_proc_task(inode); 158 struct task_struct *task = get_proc_task(inode);
159 struct fs_struct *fs = NULL; 159 struct fs_struct *fs = NULL;
@@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
165 } 165 }
166 if (fs) { 166 if (fs) {
167 read_lock(&fs->lock); 167 read_lock(&fs->lock);
168 *mnt = mntget(fs->pwd.mnt); 168 *path = fs->pwd;
169 *dentry = dget(fs->pwd.dentry); 169 path_get(&fs->pwd);
170 read_unlock(&fs->lock); 170 read_unlock(&fs->lock);
171 result = 0; 171 result = 0;
172 put_fs_struct(fs); 172 put_fs_struct(fs);
@@ -174,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
174 return result; 174 return result;
175} 175}
176 176
177static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 177static int proc_root_link(struct inode *inode, struct path *path)
178{ 178{
179 struct task_struct *task = get_proc_task(inode); 179 struct task_struct *task = get_proc_task(inode);
180 struct fs_struct *fs = NULL; 180 struct fs_struct *fs = NULL;
@@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
186 } 186 }
187 if (fs) { 187 if (fs) {
188 read_lock(&fs->lock); 188 read_lock(&fs->lock);
189 *mnt = mntget(fs->root.mnt); 189 *path = fs->root;
190 *dentry = dget(fs->root.dentry); 190 path_get(&fs->root);
191 read_unlock(&fs->lock); 191 read_unlock(&fs->lock);
192 result = 0; 192 result = 0;
193 put_fs_struct(fs); 193 put_fs_struct(fs);
@@ -1170,34 +1170,30 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
1170 if (!proc_fd_access_allowed(inode)) 1170 if (!proc_fd_access_allowed(inode))
1171 goto out; 1171 goto out;
1172 1172
1173 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path.dentry, 1173 error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
1174 &nd->path.mnt);
1175 nd->last_type = LAST_BIND; 1174 nd->last_type = LAST_BIND;
1176out: 1175out:
1177 return ERR_PTR(error); 1176 return ERR_PTR(error);
1178} 1177}
1179 1178
1180static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, 1179static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
1181 char __user *buffer, int buflen)
1182{ 1180{
1183 struct inode * inode;
1184 char *tmp = (char*)__get_free_page(GFP_TEMPORARY); 1181 char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
1185 char *path; 1182 char *pathname;
1186 int len; 1183 int len;
1187 1184
1188 if (!tmp) 1185 if (!tmp)
1189 return -ENOMEM; 1186 return -ENOMEM;
1190 1187
1191 inode = dentry->d_inode; 1188 pathname = d_path(path->dentry, path->mnt, tmp, PAGE_SIZE);
1192 path = d_path(dentry, mnt, tmp, PAGE_SIZE); 1189 len = PTR_ERR(pathname);
1193 len = PTR_ERR(path); 1190 if (IS_ERR(pathname))
1194 if (IS_ERR(path))
1195 goto out; 1191 goto out;
1196 len = tmp + PAGE_SIZE - 1 - path; 1192 len = tmp + PAGE_SIZE - 1 - pathname;
1197 1193
1198 if (len > buflen) 1194 if (len > buflen)
1199 len = buflen; 1195 len = buflen;
1200 if (copy_to_user(buffer, path, len)) 1196 if (copy_to_user(buffer, pathname, len))
1201 len = -EFAULT; 1197 len = -EFAULT;
1202 out: 1198 out:
1203 free_page((unsigned long)tmp); 1199 free_page((unsigned long)tmp);
@@ -1208,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
1208{ 1204{
1209 int error = -EACCES; 1205 int error = -EACCES;
1210 struct inode *inode = dentry->d_inode; 1206 struct inode *inode = dentry->d_inode;
1211 struct dentry *de; 1207 struct path path;
1212 struct vfsmount *mnt = NULL;
1213 1208
1214 /* Are we allowed to snoop on the tasks file descriptors? */ 1209 /* Are we allowed to snoop on the tasks file descriptors? */
1215 if (!proc_fd_access_allowed(inode)) 1210 if (!proc_fd_access_allowed(inode))
1216 goto out; 1211 goto out;
1217 1212
1218 error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); 1213 error = PROC_I(inode)->op.proc_get_link(inode, &path);
1219 if (error) 1214 if (error)
1220 goto out; 1215 goto out;
1221 1216
1222 error = do_proc_readlink(de, mnt, buffer, buflen); 1217 error = do_proc_readlink(&path, buffer, buflen);
1223 dput(de); 1218 path_put(&path);
1224 mntput(mnt);
1225out: 1219out:
1226 return error; 1220 return error;
1227} 1221}
@@ -1448,8 +1442,7 @@ out:
1448 1442
1449#define PROC_FDINFO_MAX 64 1443#define PROC_FDINFO_MAX 64
1450 1444
1451static int proc_fd_info(struct inode *inode, struct dentry **dentry, 1445static int proc_fd_info(struct inode *inode, struct path *path, char *info)
1452 struct vfsmount **mnt, char *info)
1453{ 1446{
1454 struct task_struct *task = get_proc_task(inode); 1447 struct task_struct *task = get_proc_task(inode);
1455 struct files_struct *files = NULL; 1448 struct files_struct *files = NULL;
@@ -1468,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
1468 spin_lock(&files->file_lock); 1461 spin_lock(&files->file_lock);
1469 file = fcheck_files(files, fd); 1462 file = fcheck_files(files, fd);
1470 if (file) { 1463 if (file) {
1471 if (mnt) 1464 if (path) {
1472 *mnt = mntget(file->f_path.mnt); 1465 *path = file->f_path;
1473 if (dentry) 1466 path_get(&file->f_path);
1474 *dentry = dget(file->f_path.dentry); 1467 }
1475 if (info) 1468 if (info)
1476 snprintf(info, PROC_FDINFO_MAX, 1469 snprintf(info, PROC_FDINFO_MAX,
1477 "pos:\t%lli\n" 1470 "pos:\t%lli\n"
@@ -1488,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
1488 return -ENOENT; 1481 return -ENOENT;
1489} 1482}
1490 1483
1491static int proc_fd_link(struct inode *inode, struct dentry **dentry, 1484static int proc_fd_link(struct inode *inode, struct path *path)
1492 struct vfsmount **mnt)
1493{ 1485{
1494 return proc_fd_info(inode, dentry, mnt, NULL); 1486 return proc_fd_info(inode, path, NULL);
1495} 1487}
1496 1488
1497static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) 1489static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1685,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
1685 size_t len, loff_t *ppos) 1677 size_t len, loff_t *ppos)
1686{ 1678{
1687 char tmp[PROC_FDINFO_MAX]; 1679 char tmp[PROC_FDINFO_MAX];
1688 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); 1680 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
1689 if (!err) 1681 if (!err)
1690 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); 1682 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
1691 return err; 1683 return err;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index ea496ffeabe7..1c81c8f1aeed 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -48,7 +48,7 @@ extern int maps_protect;
48 48
49extern void create_seq_entry(char *name, mode_t mode, 49extern void create_seq_entry(char *name, mode_t mode,
50 const struct file_operations *f); 50 const struct file_operations *f);
51extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); 51extern int proc_exe_link(struct inode *, struct path *);
52extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, 52extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
53 struct pid *pid, struct task_struct *task); 53 struct pid *pid, struct task_struct *task);
54extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, 54extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index ae4d3f2c8cb2..4c4f99fb1bfc 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -75,7 +75,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
75 return mm->total_vm; 75 return mm->total_vm;
76} 76}
77 77
78int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 78int proc_exe_link(struct inode *inode, struct path *path)
79{ 79{
80 struct vm_area_struct * vma; 80 struct vm_area_struct * vma;
81 int result = -ENOENT; 81 int result = -ENOENT;
@@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
98 } 98 }
99 99
100 if (vma) { 100 if (vma) {
101 *mnt = mntget(vma->vm_file->f_path.mnt); 101 *path = vma->vm_file->f_path;
102 *dentry = dget(vma->vm_file->f_path.dentry); 102 path_get(&vma->vm_file->f_path);
103 result = 0; 103 result = 0;
104 } 104 }
105 105
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index abfc6f5e56ca..8011528518bd 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -103,7 +103,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
103 return size; 103 return size;
104} 104}
105 105
106int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 106int proc_exe_link(struct inode *inode, struct path *path)
107{ 107{
108 struct vm_list_struct *vml; 108 struct vm_list_struct *vml;
109 struct vm_area_struct *vma; 109 struct vm_area_struct *vma;
@@ -126,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
126 } 126 }
127 127
128 if (vma) { 128 if (vma) {
129 *mnt = mntget(vma->vm_file->f_path.mnt); 129 *path = vma->vm_file->f_path;
130 *dentry = dget(vma->vm_file->f_path.dentry); 130 path_get(&vma->vm_file->f_path);
131 result = 0; 131 result = 0;
132 } 132 }
133 133
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index d6a4f69bdc92..d9a9e718ad19 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -269,7 +269,7 @@ extern void kclist_add(struct kcore_list *, void *, size_t);
269#endif 269#endif
270 270
271union proc_op { 271union proc_op {
272 int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); 272 int (*proc_get_link)(struct inode *, struct path *);
273 int (*proc_read)(struct task_struct *task, char *page); 273 int (*proc_read)(struct task_struct *task, char *page);
274 int (*proc_show)(struct seq_file *m, 274 int (*proc_show)(struct seq_file *m,
275 struct pid_namespace *ns, struct pid *pid, 275 struct pid_namespace *ns, struct pid *pid,