diff options
-rw-r--r-- | fs/proc/base.c | 60 | ||||
-rw-r--r-- | fs/proc/internal.h | 2 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 6 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 6 | ||||
-rw-r--r-- | include/linux/proc_fs.h | 2 |
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 | ||
156 | static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 156 | static 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 | ||
177 | static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 177 | static 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; |
1176 | out: | 1175 | out: |
1177 | return ERR_PTR(error); | 1176 | return ERR_PTR(error); |
1178 | } | 1177 | } |
1179 | 1178 | ||
1180 | static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, | 1179 | static 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); | ||
1225 | out: | 1219 | out: |
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 | ||
1451 | static int proc_fd_info(struct inode *inode, struct dentry **dentry, | 1445 | static 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 | ||
1491 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, | 1484 | static 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 | ||
1497 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1489 | static 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 | ||
49 | extern void create_seq_entry(char *name, mode_t mode, | 49 | extern void create_seq_entry(char *name, mode_t mode, |
50 | const struct file_operations *f); | 50 | const struct file_operations *f); |
51 | extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); | 51 | extern int proc_exe_link(struct inode *, struct path *); |
52 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, | 52 | extern 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); |
54 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | 54 | extern 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 | ||
78 | int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 78 | int 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 | ||
106 | int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) | 106 | int 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 | ||
271 | union proc_op { | 271 | union 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, |