diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 7c6b4ec83cb7..88f8edf18258 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->pwdmnt); | 168 | *path = fs->pwd; |
169 | *dentry = dget(fs->pwd); | 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->rootmnt); | 189 | *path = fs->root; |
190 | *dentry = dget(fs->root); | 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); |
@@ -1164,39 +1164,36 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1164 | int error = -EACCES; | 1164 | int error = -EACCES; |
1165 | 1165 | ||
1166 | /* We don't need a base pointer in the /proc filesystem */ | 1166 | /* We don't need a base pointer in the /proc filesystem */ |
1167 | path_release(nd); | 1167 | path_put(&nd->path); |
1168 | 1168 | ||
1169 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1169 | /* Are we allowed to snoop on the tasks file descriptors? */ |
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->dentry, &nd->mnt); | 1173 | error = PROC_I(inode)->op.proc_get_link(inode, &nd->path); |
1174 | nd->last_type = LAST_BIND; | 1174 | nd->last_type = LAST_BIND; |
1175 | out: | 1175 | out: |
1176 | return ERR_PTR(error); | 1176 | return ERR_PTR(error); |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | 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) |
1180 | char __user *buffer, int buflen) | ||
1181 | { | 1180 | { |
1182 | struct inode * inode; | ||
1183 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); | 1181 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); |
1184 | char *path; | 1182 | char *pathname; |
1185 | int len; | 1183 | int len; |
1186 | 1184 | ||
1187 | if (!tmp) | 1185 | if (!tmp) |
1188 | return -ENOMEM; | 1186 | return -ENOMEM; |
1189 | 1187 | ||
1190 | inode = dentry->d_inode; | 1188 | pathname = d_path(path, tmp, PAGE_SIZE); |
1191 | path = d_path(dentry, mnt, tmp, PAGE_SIZE); | 1189 | len = PTR_ERR(pathname); |
1192 | len = PTR_ERR(path); | 1190 | if (IS_ERR(pathname)) |
1193 | if (IS_ERR(path)) | ||
1194 | goto out; | 1191 | goto out; |
1195 | len = tmp + PAGE_SIZE - 1 - path; | 1192 | len = tmp + PAGE_SIZE - 1 - pathname; |
1196 | 1193 | ||
1197 | if (len > buflen) | 1194 | if (len > buflen) |
1198 | len = buflen; | 1195 | len = buflen; |
1199 | if (copy_to_user(buffer, path, len)) | 1196 | if (copy_to_user(buffer, pathname, len)) |
1200 | len = -EFAULT; | 1197 | len = -EFAULT; |
1201 | out: | 1198 | out: |
1202 | free_page((unsigned long)tmp); | 1199 | free_page((unsigned long)tmp); |
@@ -1207,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b | |||
1207 | { | 1204 | { |
1208 | int error = -EACCES; | 1205 | int error = -EACCES; |
1209 | struct inode *inode = dentry->d_inode; | 1206 | struct inode *inode = dentry->d_inode; |
1210 | struct dentry *de; | 1207 | struct path path; |
1211 | struct vfsmount *mnt = NULL; | ||
1212 | 1208 | ||
1213 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1209 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1214 | if (!proc_fd_access_allowed(inode)) | 1210 | if (!proc_fd_access_allowed(inode)) |
1215 | goto out; | 1211 | goto out; |
1216 | 1212 | ||
1217 | error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); | 1213 | error = PROC_I(inode)->op.proc_get_link(inode, &path); |
1218 | if (error) | 1214 | if (error) |
1219 | goto out; | 1215 | goto out; |
1220 | 1216 | ||
1221 | error = do_proc_readlink(de, mnt, buffer, buflen); | 1217 | error = do_proc_readlink(&path, buffer, buflen); |
1222 | dput(de); | 1218 | path_put(&path); |
1223 | mntput(mnt); | ||
1224 | out: | 1219 | out: |
1225 | return error; | 1220 | return error; |
1226 | } | 1221 | } |
@@ -1447,8 +1442,7 @@ out: | |||
1447 | 1442 | ||
1448 | #define PROC_FDINFO_MAX 64 | 1443 | #define PROC_FDINFO_MAX 64 |
1449 | 1444 | ||
1450 | 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) |
1451 | struct vfsmount **mnt, char *info) | ||
1452 | { | 1446 | { |
1453 | struct task_struct *task = get_proc_task(inode); | 1447 | struct task_struct *task = get_proc_task(inode); |
1454 | struct files_struct *files = NULL; | 1448 | struct files_struct *files = NULL; |
@@ -1467,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1467 | spin_lock(&files->file_lock); | 1461 | spin_lock(&files->file_lock); |
1468 | file = fcheck_files(files, fd); | 1462 | file = fcheck_files(files, fd); |
1469 | if (file) { | 1463 | if (file) { |
1470 | if (mnt) | 1464 | if (path) { |
1471 | *mnt = mntget(file->f_path.mnt); | 1465 | *path = file->f_path; |
1472 | if (dentry) | 1466 | path_get(&file->f_path); |
1473 | *dentry = dget(file->f_path.dentry); | 1467 | } |
1474 | if (info) | 1468 | if (info) |
1475 | snprintf(info, PROC_FDINFO_MAX, | 1469 | snprintf(info, PROC_FDINFO_MAX, |
1476 | "pos:\t%lli\n" | 1470 | "pos:\t%lli\n" |
@@ -1487,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1487 | return -ENOENT; | 1481 | return -ENOENT; |
1488 | } | 1482 | } |
1489 | 1483 | ||
1490 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, | 1484 | static int proc_fd_link(struct inode *inode, struct path *path) |
1491 | struct vfsmount **mnt) | ||
1492 | { | 1485 | { |
1493 | return proc_fd_info(inode, dentry, mnt, NULL); | 1486 | return proc_fd_info(inode, path, NULL); |
1494 | } | 1487 | } |
1495 | 1488 | ||
1496 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1489 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) |
@@ -1684,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, | |||
1684 | size_t len, loff_t *ppos) | 1677 | size_t len, loff_t *ppos) |
1685 | { | 1678 | { |
1686 | char tmp[PROC_FDINFO_MAX]; | 1679 | char tmp[PROC_FDINFO_MAX]; |
1687 | 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); |
1688 | if (!err) | 1681 | if (!err) |
1689 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); | 1682 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); |
1690 | return err; | 1683 | return err; |