Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / fs / proc / namespaces.c
index 995e8e98237d40027dbe424e3781befad6243b1e..c9eac4563fa8ab497dfbc492d4d63f2c6105df9b 100644 (file)
@@ -1,10 +1,6 @@
 #include <linux/proc_fs.h>
 #include <linux/nsproxy.h>
-#include <linux/sched.h>
 #include <linux/ptrace.h>
-#include <linux/fs_struct.h>
-#include <linux/mount.h>
-#include <linux/path.h>
 #include <linux/namei.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
@@ -34,138 +30,45 @@ static const struct proc_ns_operations *ns_entries[] = {
        &mntns_operations,
 };
 
-static const struct file_operations ns_file_operations = {
-       .llseek         = no_llseek,
-};
-
-static const struct inode_operations ns_inode_operations = {
-       .setattr        = proc_setattr,
-};
-
-static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
-{
-       struct inode *inode = dentry->d_inode;
-       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns.ns_ops;
-
-       return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
-               ns_ops->name, inode->i_ino);
-}
-
-const struct dentry_operations ns_dentry_operations =
-{
-       .d_delete       = always_delete_dentry,
-       .d_dname        = ns_dname,
-};
-
-static struct dentry *proc_ns_get_dentry(struct super_block *sb,
-       struct task_struct *task, const struct proc_ns_operations *ns_ops)
-{
-       struct dentry *dentry, *result;
-       struct inode *inode;
-       struct proc_inode *ei;
-       struct qstr qname = { .name = "", };
-       struct ns_common *ns;
-
-       ns = ns_ops->get(task);
-       if (!ns)
-               return ERR_PTR(-ENOENT);
-
-       dentry = d_alloc_pseudo(sb, &qname);
-       if (!dentry) {
-               ns_ops->put(ns);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       inode = iget_locked(sb, ns->inum);
-       if (!inode) {
-               dput(dentry);
-               ns_ops->put(ns);
-               return ERR_PTR(-ENOMEM);
-       }
-
-       ei = PROC_I(inode);
-       if (inode->i_state & I_NEW) {
-               inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-               inode->i_op = &ns_inode_operations;
-               inode->i_mode = S_IFREG | S_IRUGO;
-               inode->i_fop = &ns_file_operations;
-               ei->ns.ns_ops = ns_ops;
-               ei->ns.ns = ns;
-               unlock_new_inode(inode);
-       } else {
-               ns_ops->put(ns);
-       }
-
-       d_set_d_op(dentry, &ns_dentry_operations);
-       result = d_instantiate_unique(dentry, inode);
-       if (result) {
-               dput(dentry);
-               dentry = result;
-       }
-
-       return dentry;
-}
-
 static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
-       struct super_block *sb = inode->i_sb;
-       struct proc_inode *ei = PROC_I(inode);
+       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
        struct task_struct *task;
        struct path ns_path;
        void *error = ERR_PTR(-EACCES);
 
        task = get_proc_task(inode);
        if (!task)
-               goto out;
+               return error;
 
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
-               goto out_put_task;
-
-       ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops);
-       if (IS_ERR(ns_path.dentry)) {
-               error = ERR_CAST(ns_path.dentry);
-               goto out_put_task;
+       if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+               error = ns_get_path(&ns_path, task, ns_ops);
+               if (!error)
+                       nd_jump_link(nd, &ns_path);
        }
-
-       ns_path.mnt = mntget(nd->path.mnt);
-       nd_jump_link(nd, &ns_path);
-       error = NULL;
-
-out_put_task:
        put_task_struct(task);
-out:
        return error;
 }
 
 static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
        struct inode *inode = dentry->d_inode;
-       struct proc_inode *ei = PROC_I(inode);
-       const struct proc_ns_operations *ns_ops = ei->ns.ns_ops;
+       const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
        struct task_struct *task;
-       struct ns_common *ns;
        char name[50];
        int res = -EACCES;
 
        task = get_proc_task(inode);
        if (!task)
-               goto out;
-
-       if (!ptrace_may_access(task, PTRACE_MODE_READ))
-               goto out_put_task;
+               return res;
 
-       res = -ENOENT;
-       ns = ns_ops->get(task);
-       if (!ns)
-               goto out_put_task;
-
-       snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns->inum);
-       res = readlink_copy(buffer, buflen, name);
-       ns_ops->put(ns);
-out_put_task:
+       if (ptrace_may_access(task, PTRACE_MODE_READ)) {
+               res = ns_get_name(name, sizeof(name), task, ns_ops);
+               if (res >= 0)
+                       res = readlink_copy(buffer, buflen, name);
+       }
        put_task_struct(task);
-out:
        return res;
 }
 
@@ -189,7 +92,7 @@ static int proc_ns_instantiate(struct inode *dir,
        ei = PROC_I(inode);
        inode->i_mode = S_IFLNK|S_IRWXUGO;
        inode->i_op = &proc_ns_link_inode_operations;
-       ei->ns.ns_ops = ns_ops;
+       ei->ns_ops = ns_ops;
 
        d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
@@ -267,31 +170,3 @@ const struct inode_operations proc_ns_dir_inode_operations = {
        .getattr        = pid_getattr,
        .setattr        = proc_setattr,
 };
-
-struct file *proc_ns_fget(int fd)
-{
-       struct file *file;
-
-       file = fget(fd);
-       if (!file)
-               return ERR_PTR(-EBADF);
-
-       if (file->f_op != &ns_file_operations)
-               goto out_invalid;
-
-       return file;
-
-out_invalid:
-       fput(file);
-       return ERR_PTR(-EINVAL);
-}
-
-struct proc_ns *get_proc_ns(struct inode *inode)
-{
-       return &PROC_I(inode)->ns;
-}
-
-bool proc_ns_inode(struct inode *inode)
-{
-       return inode->i_fop == &ns_file_operations;
-}
This page took 0.046273 seconds and 5 git commands to generate.