mm, oom: normalize oom scores to oom_score_adj scale only for userspace
[pandora-kernel.git] / fs / proc / base.c
index 57b8159..d7d7118 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/oom.h>
 #include <linux/elf.h>
 #include <linux/pid_namespace.h>
+#include <linux/user_namespace.h>
 #include <linux/fs_struct.h>
 #include <linux/slab.h>
 #include <linux/flex_array.h>
@@ -410,12 +411,13 @@ static const struct file_operations proc_lstats_operations = {
 
 static int proc_oom_score(struct task_struct *task, char *buffer)
 {
+       unsigned long totalpages = totalram_pages + total_swap_pages;
        unsigned long points = 0;
 
        read_lock(&tasklist_lock);
        if (pid_alive(task))
-               points = oom_badness(task, NULL, NULL,
-                                       totalram_pages + total_swap_pages);
+               points = oom_badness(task, NULL, NULL, totalpages) *
+                                               1000 / totalpages;
        read_unlock(&tasklist_lock);
        return sprintf(buffer, "%lu\n", points);
 }
@@ -1561,8 +1563,8 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
        generic_fillattr(inode, stat);
 
        rcu_read_lock();
-       stat->uid = 0;
-       stat->gid = 0;
+       stat->uid = GLOBAL_ROOT_UID;
+       stat->gid = GLOBAL_ROOT_GID;
        task = pid_task(proc_pid(inode), PIDTYPE_PID);
        if (task) {
                if (!has_pid_permissions(pid, task, 2)) {
@@ -1622,8 +1624,8 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
                        inode->i_gid = cred->egid;
                        rcu_read_unlock();
                } else {
-                       inode->i_uid = 0;
-                       inode->i_gid = 0;
+                       inode->i_uid = GLOBAL_ROOT_UID;
+                       inode->i_gid = GLOBAL_ROOT_GID;
                }
                inode->i_mode &= ~(S_ISUID | S_ISGID);
                security_task_to_inode(task, inode);
@@ -1815,8 +1817,8 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
                                        inode->i_gid = cred->egid;
                                        rcu_read_unlock();
                                } else {
-                                       inode->i_uid = 0;
-                                       inode->i_gid = 0;
+                                       inode->i_uid = GLOBAL_ROOT_UID;
+                                       inode->i_gid = GLOBAL_ROOT_GID;
                                }
 
                                i_mode = S_IFLNK;
@@ -2045,8 +2047,8 @@ static int map_files_d_revalidate(struct dentry *dentry, struct nameidata *nd)
                        inode->i_gid = cred->egid;
                        rcu_read_unlock();
                } else {
-                       inode->i_uid = 0;
-                       inode->i_gid = 0;
+                       inode->i_uid = GLOBAL_ROOT_UID;
+                       inode->i_gid = GLOBAL_ROOT_GID;
                }
                security_task_to_inode(task, inode);
                status = 1;
@@ -2924,6 +2926,74 @@ static int proc_tgid_io_accounting(struct task_struct *task, char *buffer)
 }
 #endif /* CONFIG_TASK_IO_ACCOUNTING */
 
+#ifdef CONFIG_USER_NS
+static int proc_id_map_open(struct inode *inode, struct file *file,
+       struct seq_operations *seq_ops)
+{
+       struct user_namespace *ns = NULL;
+       struct task_struct *task;
+       struct seq_file *seq;
+       int ret = -EINVAL;
+
+       task = get_proc_task(inode);
+       if (task) {
+               rcu_read_lock();
+               ns = get_user_ns(task_cred_xxx(task, user_ns));
+               rcu_read_unlock();
+               put_task_struct(task);
+       }
+       if (!ns)
+               goto err;
+
+       ret = seq_open(file, seq_ops);
+       if (ret)
+               goto err_put_ns;
+
+       seq = file->private_data;
+       seq->private = ns;
+
+       return 0;
+err_put_ns:
+       put_user_ns(ns);
+err:
+       return ret;
+}
+
+static int proc_id_map_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq = file->private_data;
+       struct user_namespace *ns = seq->private;
+       put_user_ns(ns);
+       return seq_release(inode, file);
+}
+
+static int proc_uid_map_open(struct inode *inode, struct file *file)
+{
+       return proc_id_map_open(inode, file, &proc_uid_seq_operations);
+}
+
+static int proc_gid_map_open(struct inode *inode, struct file *file)
+{
+       return proc_id_map_open(inode, file, &proc_gid_seq_operations);
+}
+
+static const struct file_operations proc_uid_map_operations = {
+       .open           = proc_uid_map_open,
+       .write          = proc_uid_map_write,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = proc_id_map_release,
+};
+
+static const struct file_operations proc_gid_map_operations = {
+       .open           = proc_gid_map_open,
+       .write          = proc_gid_map_write,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = proc_id_map_release,
+};
+#endif /* CONFIG_USER_NS */
+
 static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
                                struct pid *pid, struct task_struct *task)
 {
@@ -3026,6 +3096,10 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_HARDWALL
        INF("hardwall",   S_IRUGO, proc_pid_hardwall),
 #endif
+#ifdef CONFIG_USER_NS
+       REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
+       REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
+#endif
 };
 
 static int proc_tgid_base_readdir(struct file * filp,
@@ -3381,6 +3455,10 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_HARDWALL
        INF("hardwall",   S_IRUGO, proc_pid_hardwall),
 #endif
+#ifdef CONFIG_USER_NS
+       REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
+       REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
+#endif
 };
 
 static int proc_tid_base_readdir(struct file * filp,