]> err.no Git - linux-2.6/blobdiff - fs/proc/base.c
[PATCH] remove verify_area(): remove verify_area() from various uaccess.h headers
[linux-2.6] / fs / proc / base.c
index 2eac86d46c519a3b455e9b58159cc06ba88bc727..520978e49e92474f428054785c6c68a1978138a5 100644 (file)
  *  go into icache. We cache the reference to task_struct upon lookup too.
  *  Eventually it should become a filesystem in its own. We don't use the
  *  rest of procfs anymore.
+ *
+ *
+ *  Changelog:
+ *  17-Jan-2005
+ *  Allan Bezerra
+ *  Bruna Moreira <bruna.moreira@indt.org.br>
+ *  Edjard Mota <edjard.mota@indt.org.br>
+ *  Ilias Biris <ilias.biris@indt.org.br>
+ *  Mauricio Lin <mauricio.lin@indt.org.br>
+ *
+ *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
+ *
+ *  A new process specific entry (smaps) included in /proc. It shows the
+ *  size of rss for each memory area. The maps entry lacks information
+ *  about physical memory size (rss) for each mapped file, i.e.,
+ *  rss information for executables and library files.
+ *  This additional information is useful for any tools that need to know
+ *  about physical memory consumption for a process specific library.
+ *
+ *  Changelog:
+ *  21-Feb-2005
+ *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
+ *  Pud inclusion in the page table walking.
+ *
+ *  ChangeLog:
+ *  10-Mar-2005
+ *  10LE Instituto Nokia de Tecnologia - INdT:
+ *  A better way to walks through the page table as suggested by Hugh Dickins.
+ *
+ *  Simo Piiroinen <simo.piiroinen@nokia.com>:
+ *  Smaps information related to shared, private, clean and dirty pages.
+ *
+ *  Paul Mundt <paul.mundt@nokia.com>:
+ *  Overall revision about smaps.
  */
 
 #include <asm/uaccess.h>
@@ -65,8 +99,10 @@ enum pid_directory_inos {
        PROC_TGID_STAT,
        PROC_TGID_STATM,
        PROC_TGID_MAPS,
+       PROC_TGID_NUMA_MAPS,
        PROC_TGID_MOUNTS,
        PROC_TGID_WCHAN,
+       PROC_TGID_SMAPS,
 #ifdef CONFIG_SCHEDSTATS
        PROC_TGID_SCHEDSTAT,
 #endif
@@ -102,8 +138,10 @@ enum pid_directory_inos {
        PROC_TID_STAT,
        PROC_TID_STATM,
        PROC_TID_MAPS,
+       PROC_TID_NUMA_MAPS,
        PROC_TID_MOUNTS,
        PROC_TID_WCHAN,
+       PROC_TID_SMAPS,
 #ifdef CONFIG_SCHEDSTATS
        PROC_TID_SCHEDSTAT,
 #endif
@@ -144,6 +182,9 @@ static struct pid_entry tgid_base_stuff[] = {
        E(PROC_TGID_STAT,      "stat",    S_IFREG|S_IRUGO),
        E(PROC_TGID_STATM,     "statm",   S_IFREG|S_IRUGO),
        E(PROC_TGID_MAPS,      "maps",    S_IFREG|S_IRUGO),
+#ifdef CONFIG_NUMA
+       E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
+#endif
        E(PROC_TGID_MEM,       "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
        E(PROC_TGID_SECCOMP,   "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
@@ -152,6 +193,7 @@ static struct pid_entry tgid_base_stuff[] = {
        E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
        E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
        E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
+       E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
 #ifdef CONFIG_SECURITY
        E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
 #endif
@@ -180,6 +222,9 @@ static struct pid_entry tid_base_stuff[] = {
        E(PROC_TID_STAT,       "stat",    S_IFREG|S_IRUGO),
        E(PROC_TID_STATM,      "statm",   S_IFREG|S_IRUGO),
        E(PROC_TID_MAPS,       "maps",    S_IFREG|S_IRUGO),
+#ifdef CONFIG_NUMA
+       E(PROC_TID_NUMA_MAPS,  "numa_maps",    S_IFREG|S_IRUGO),
+#endif
        E(PROC_TID_MEM,        "mem",     S_IFREG|S_IRUSR|S_IWUSR),
 #ifdef CONFIG_SECCOMP
        E(PROC_TID_SECCOMP,    "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
@@ -188,6 +233,7 @@ static struct pid_entry tid_base_stuff[] = {
        E(PROC_TID_ROOT,       "root",    S_IFLNK|S_IRWXUGO),
        E(PROC_TID_EXE,        "exe",     S_IFLNK|S_IRWXUGO),
        E(PROC_TID_MOUNTS,     "mounts",  S_IFREG|S_IRUGO),
+       E(PROC_TID_SMAPS,      "smaps",   S_IFREG|S_IRUGO),
 #ifdef CONFIG_SECURITY
        E(PROC_TID_ATTR,       "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
 #endif
@@ -314,7 +360,7 @@ static int may_ptrace_attach(struct task_struct *task)
             (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
                goto out;
        rmb();
-       if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
+       if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
                goto out;
        if (security_ptrace(current, task))
                goto out;
@@ -515,6 +561,46 @@ static struct file_operations proc_maps_operations = {
        .release        = seq_release,
 };
 
+#ifdef CONFIG_NUMA
+extern struct seq_operations proc_pid_numa_maps_op;
+static int numa_maps_open(struct inode *inode, struct file *file)
+{
+       struct task_struct *task = proc_task(inode);
+       int ret = seq_open(file, &proc_pid_numa_maps_op);
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               m->private = task;
+       }
+       return ret;
+}
+
+static struct file_operations proc_numa_maps_operations = {
+       .open           = numa_maps_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+#endif
+
+extern struct seq_operations proc_pid_smaps_op;
+static int smaps_open(struct inode *inode, struct file *file)
+{
+       struct task_struct *task = proc_task(inode);
+       int ret = seq_open(file, &proc_pid_smaps_op);
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               m->private = task;
+       }
+       return ret;
+}
+
+static struct file_operations proc_smaps_operations = {
+       .open           = smaps_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
 extern struct seq_operations mounts_op;
 static int mounts_open(struct inode *inode, struct file *file)
 {
@@ -820,7 +906,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
                goto out_free_page;
 
        }
-       length = audit_set_loginuid(task->audit_context, loginuid);
+       length = audit_set_loginuid(task, loginuid);
        if (likely(length == 0))
                length = count;
 
@@ -890,7 +976,7 @@ static struct file_operations proc_seccomp_operations = {
 };
 #endif /* CONFIG_SECCOMP */
 
-static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
        int error = -EACCES;
@@ -907,7 +993,7 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
        error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
        nd->last_type = LAST_BIND;
 out:
-       return error;
+       return ERR_PTR(error);
 }
 
 static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
@@ -1113,7 +1199,9 @@ static int task_dumpable(struct task_struct *task)
        if (mm)
                dumpable = mm->dumpable;
        task_unlock(task);
-       return dumpable;
+       if(dumpable == 1)
+               return 1;
+       return 0;
 }
 
 
@@ -1522,6 +1610,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
                case PROC_TGID_MAPS:
                        inode->i_fop = &proc_maps_operations;
                        break;
+#ifdef CONFIG_NUMA
+               case PROC_TID_NUMA_MAPS:
+               case PROC_TGID_NUMA_MAPS:
+                       inode->i_fop = &proc_numa_maps_operations;
+                       break;
+#endif
                case PROC_TID_MEM:
                case PROC_TGID_MEM:
                        inode->i_op = &proc_mem_inode_operations;
@@ -1537,6 +1631,10 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
                case PROC_TGID_MOUNTS:
                        inode->i_fop = &proc_mounts_operations;
                        break;
+               case PROC_TID_SMAPS:
+               case PROC_TGID_SMAPS:
+                       inode->i_fop = &proc_smaps_operations;
+                       break;
 #ifdef CONFIG_SECURITY
                case PROC_TID_ATTR:
                        inode->i_nlink = 2;
@@ -1690,11 +1788,11 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
        return vfs_readlink(dentry,buffer,buflen,tmp);
 }
 
-static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        char tmp[30];
        sprintf(tmp, "%d", current->tgid);
-       return vfs_follow_link(nd,tmp);
+       return ERR_PTR(vfs_follow_link(nd,tmp));
 }      
 
 static struct inode_operations proc_self_inode_operations = {
@@ -1703,13 +1801,13 @@ static struct inode_operations proc_self_inode_operations = {
 };
 
 /**
- * proc_pid_unhash -  Unhash /proc/<pid> entry from the dcache.
+ * proc_pid_unhash -  Unhash /proc/@pid entry from the dcache.
  * @p: task that should be flushed.
  *
- * Drops the /proc/<pid> dcache entry from the hash chains.
+ * Drops the /proc/@pid dcache entry from the hash chains.
  *
- * Dropping /proc/<pid> entries and detach_pid must be synchroneous,
- * otherwise e.g. /proc/<pid>/exe might point to the wrong executable,
+ * Dropping /proc/@pid entries and detach_pid must be synchroneous,
+ * otherwise e.g. /proc/@pid/exe might point to the wrong executable,
  * if the pid value is immediately reused. This is enforced by
  * - caller must acquire spin_lock(p->proc_lock)
  * - must be called before detach_pid()
@@ -1741,8 +1839,8 @@ struct dentry *proc_pid_unhash(struct task_struct *p)
 }
 
 /**
- * proc_pid_flush - recover memory used by stale /proc/<pid>/x entries
- * @proc_entry: directoy to prune.
+ * proc_pid_flush - recover memory used by stale /proc/@pid/x entries
+ * @proc_dentry: directoy to prune.
  *
  * Shrink the /proc directory that was used by the just killed thread.
  */