|
@@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk)
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
-static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
|
|
|
+static int proc_cwd_link(struct inode *inode, struct path *path)
|
|
|
{
|
|
|
struct task_struct *task = get_proc_task(inode);
|
|
|
struct fs_struct *fs = NULL;
|
|
@@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
|
|
|
}
|
|
|
if (fs) {
|
|
|
read_lock(&fs->lock);
|
|
|
- *mnt = mntget(fs->pwd.mnt);
|
|
|
- *dentry = dget(fs->pwd.dentry);
|
|
|
+ *path = fs->pwd;
|
|
|
+ path_get(&fs->pwd);
|
|
|
read_unlock(&fs->lock);
|
|
|
result = 0;
|
|
|
put_fs_struct(fs);
|
|
@@ -174,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
|
|
|
+static int proc_root_link(struct inode *inode, struct path *path)
|
|
|
{
|
|
|
struct task_struct *task = get_proc_task(inode);
|
|
|
struct fs_struct *fs = NULL;
|
|
@@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
|
|
|
}
|
|
|
if (fs) {
|
|
|
read_lock(&fs->lock);
|
|
|
- *mnt = mntget(fs->root.mnt);
|
|
|
- *dentry = dget(fs->root.dentry);
|
|
|
+ *path = fs->root;
|
|
|
+ path_get(&fs->root);
|
|
|
read_unlock(&fs->lock);
|
|
|
result = 0;
|
|
|
put_fs_struct(fs);
|
|
@@ -1170,34 +1170,30 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
|
|
|
if (!proc_fd_access_allowed(inode))
|
|
|
goto out;
|
|
|
|
|
|
- error = PROC_I(inode)->op.proc_get_link(inode, &nd->path.dentry,
|
|
|
- &nd->path.mnt);
|
|
|
+ error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
|
|
|
nd->last_type = LAST_BIND;
|
|
|
out:
|
|
|
return ERR_PTR(error);
|
|
|
}
|
|
|
|
|
|
-static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
|
|
|
- char __user *buffer, int buflen)
|
|
|
+static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
|
|
|
{
|
|
|
- struct inode * inode;
|
|
|
char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
|
|
|
- char *path;
|
|
|
+ char *pathname;
|
|
|
int len;
|
|
|
|
|
|
if (!tmp)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- inode = dentry->d_inode;
|
|
|
- path = d_path(dentry, mnt, tmp, PAGE_SIZE);
|
|
|
- len = PTR_ERR(path);
|
|
|
- if (IS_ERR(path))
|
|
|
+ pathname = d_path(path->dentry, path->mnt, tmp, PAGE_SIZE);
|
|
|
+ len = PTR_ERR(pathname);
|
|
|
+ if (IS_ERR(pathname))
|
|
|
goto out;
|
|
|
- len = tmp + PAGE_SIZE - 1 - path;
|
|
|
+ len = tmp + PAGE_SIZE - 1 - pathname;
|
|
|
|
|
|
if (len > buflen)
|
|
|
len = buflen;
|
|
|
- if (copy_to_user(buffer, path, len))
|
|
|
+ if (copy_to_user(buffer, pathname, len))
|
|
|
len = -EFAULT;
|
|
|
out:
|
|
|
free_page((unsigned long)tmp);
|
|
@@ -1208,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
|
|
|
{
|
|
|
int error = -EACCES;
|
|
|
struct inode *inode = dentry->d_inode;
|
|
|
- struct dentry *de;
|
|
|
- struct vfsmount *mnt = NULL;
|
|
|
+ struct path path;
|
|
|
|
|
|
/* Are we allowed to snoop on the tasks file descriptors? */
|
|
|
if (!proc_fd_access_allowed(inode))
|
|
|
goto out;
|
|
|
|
|
|
- error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
|
|
|
+ error = PROC_I(inode)->op.proc_get_link(inode, &path);
|
|
|
if (error)
|
|
|
goto out;
|
|
|
|
|
|
- error = do_proc_readlink(de, mnt, buffer, buflen);
|
|
|
- dput(de);
|
|
|
- mntput(mnt);
|
|
|
+ error = do_proc_readlink(&path, buffer, buflen);
|
|
|
+ path_put(&path);
|
|
|
out:
|
|
|
return error;
|
|
|
}
|
|
@@ -1448,8 +1442,7 @@ out:
|
|
|
|
|
|
#define PROC_FDINFO_MAX 64
|
|
|
|
|
|
-static int proc_fd_info(struct inode *inode, struct dentry **dentry,
|
|
|
- struct vfsmount **mnt, char *info)
|
|
|
+static int proc_fd_info(struct inode *inode, struct path *path, char *info)
|
|
|
{
|
|
|
struct task_struct *task = get_proc_task(inode);
|
|
|
struct files_struct *files = NULL;
|
|
@@ -1468,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
|
|
|
spin_lock(&files->file_lock);
|
|
|
file = fcheck_files(files, fd);
|
|
|
if (file) {
|
|
|
- if (mnt)
|
|
|
- *mnt = mntget(file->f_path.mnt);
|
|
|
- if (dentry)
|
|
|
- *dentry = dget(file->f_path.dentry);
|
|
|
+ if (path) {
|
|
|
+ *path = file->f_path;
|
|
|
+ path_get(&file->f_path);
|
|
|
+ }
|
|
|
if (info)
|
|
|
snprintf(info, PROC_FDINFO_MAX,
|
|
|
"pos:\t%lli\n"
|
|
@@ -1488,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry,
|
|
|
return -ENOENT;
|
|
|
}
|
|
|
|
|
|
-static int proc_fd_link(struct inode *inode, struct dentry **dentry,
|
|
|
- struct vfsmount **mnt)
|
|
|
+static int proc_fd_link(struct inode *inode, struct path *path)
|
|
|
{
|
|
|
- return proc_fd_info(inode, dentry, mnt, NULL);
|
|
|
+ return proc_fd_info(inode, path, NULL);
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
size_t len, loff_t *ppos)
|
|
|
{
|
|
|
char tmp[PROC_FDINFO_MAX];
|
|
|
- int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
|
|
|
+ int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
|
|
|
if (!err)
|
|
|
err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
|
|
|
return err;
|