diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 183 |
1 files changed, 95 insertions, 88 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 33537487f5ab..88f8edf18258 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -88,10 +88,6 @@ | |||
88 | * in /proc for a task before it execs a suid executable. | 88 | * in /proc for a task before it execs a suid executable. |
89 | */ | 89 | */ |
90 | 90 | ||
91 | |||
92 | /* Worst case buffer size needed for holding an integer. */ | ||
93 | #define PROC_NUMBUF 13 | ||
94 | |||
95 | struct pid_entry { | 91 | struct pid_entry { |
96 | char *name; | 92 | char *name; |
97 | int len; | 93 | int len; |
@@ -125,6 +121,10 @@ struct pid_entry { | |||
125 | NOD(NAME, (S_IFREG|(MODE)), \ | 121 | NOD(NAME, (S_IFREG|(MODE)), \ |
126 | NULL, &proc_info_file_operations, \ | 122 | NULL, &proc_info_file_operations, \ |
127 | { .proc_read = &proc_##OTYPE } ) | 123 | { .proc_read = &proc_##OTYPE } ) |
124 | #define ONE(NAME, MODE, OTYPE) \ | ||
125 | NOD(NAME, (S_IFREG|(MODE)), \ | ||
126 | NULL, &proc_single_file_operations, \ | ||
127 | { .proc_show = &proc_##OTYPE } ) | ||
128 | 128 | ||
129 | int maps_protect; | 129 | int maps_protect; |
130 | EXPORT_SYMBOL(maps_protect); | 130 | EXPORT_SYMBOL(maps_protect); |
@@ -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); |
@@ -506,7 +506,7 @@ static const struct inode_operations proc_def_inode_operations = { | |||
506 | .setattr = proc_setattr, | 506 | .setattr = proc_setattr, |
507 | }; | 507 | }; |
508 | 508 | ||
509 | extern struct seq_operations mounts_op; | 509 | extern const struct seq_operations mounts_op; |
510 | struct proc_mounts { | 510 | struct proc_mounts { |
511 | struct seq_file m; | 511 | struct seq_file m; |
512 | int event; | 512 | int event; |
@@ -585,7 +585,7 @@ static const struct file_operations proc_mounts_operations = { | |||
585 | .poll = mounts_poll, | 585 | .poll = mounts_poll, |
586 | }; | 586 | }; |
587 | 587 | ||
588 | extern struct seq_operations mountstats_op; | 588 | extern const struct seq_operations mountstats_op; |
589 | static int mountstats_open(struct inode *inode, struct file *file) | 589 | static int mountstats_open(struct inode *inode, struct file *file) |
590 | { | 590 | { |
591 | int ret = seq_open(file, &mountstats_op); | 591 | int ret = seq_open(file, &mountstats_op); |
@@ -662,6 +662,45 @@ static const struct file_operations proc_info_file_operations = { | |||
662 | .read = proc_info_read, | 662 | .read = proc_info_read, |
663 | }; | 663 | }; |
664 | 664 | ||
665 | static int proc_single_show(struct seq_file *m, void *v) | ||
666 | { | ||
667 | struct inode *inode = m->private; | ||
668 | struct pid_namespace *ns; | ||
669 | struct pid *pid; | ||
670 | struct task_struct *task; | ||
671 | int ret; | ||
672 | |||
673 | ns = inode->i_sb->s_fs_info; | ||
674 | pid = proc_pid(inode); | ||
675 | task = get_pid_task(pid, PIDTYPE_PID); | ||
676 | if (!task) | ||
677 | return -ESRCH; | ||
678 | |||
679 | ret = PROC_I(inode)->op.proc_show(m, ns, pid, task); | ||
680 | |||
681 | put_task_struct(task); | ||
682 | return ret; | ||
683 | } | ||
684 | |||
685 | static int proc_single_open(struct inode *inode, struct file *filp) | ||
686 | { | ||
687 | int ret; | ||
688 | ret = single_open(filp, proc_single_show, NULL); | ||
689 | if (!ret) { | ||
690 | struct seq_file *m = filp->private_data; | ||
691 | |||
692 | m->private = inode; | ||
693 | } | ||
694 | return ret; | ||
695 | } | ||
696 | |||
697 | static const struct file_operations proc_single_file_operations = { | ||
698 | .open = proc_single_open, | ||
699 | .read = seq_read, | ||
700 | .llseek = seq_lseek, | ||
701 | .release = single_release, | ||
702 | }; | ||
703 | |||
665 | static int mem_open(struct inode* inode, struct file* file) | 704 | static int mem_open(struct inode* inode, struct file* file) |
666 | { | 705 | { |
667 | file->private_data = (void*)((long)current->self_exec_id); | 706 | file->private_data = (void*)((long)current->self_exec_id); |
@@ -787,7 +826,7 @@ out_no_task: | |||
787 | } | 826 | } |
788 | #endif | 827 | #endif |
789 | 828 | ||
790 | static loff_t mem_lseek(struct file * file, loff_t offset, int orig) | 829 | loff_t mem_lseek(struct file *file, loff_t offset, int orig) |
791 | { | 830 | { |
792 | switch (orig) { | 831 | switch (orig) { |
793 | case 0: | 832 | case 0: |
@@ -935,42 +974,6 @@ static const struct file_operations proc_oom_adjust_operations = { | |||
935 | .write = oom_adjust_write, | 974 | .write = oom_adjust_write, |
936 | }; | 975 | }; |
937 | 976 | ||
938 | #ifdef CONFIG_MMU | ||
939 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, | ||
940 | size_t count, loff_t *ppos) | ||
941 | { | ||
942 | struct task_struct *task; | ||
943 | char buffer[PROC_NUMBUF], *end; | ||
944 | struct mm_struct *mm; | ||
945 | |||
946 | memset(buffer, 0, sizeof(buffer)); | ||
947 | if (count > sizeof(buffer) - 1) | ||
948 | count = sizeof(buffer) - 1; | ||
949 | if (copy_from_user(buffer, buf, count)) | ||
950 | return -EFAULT; | ||
951 | if (!simple_strtol(buffer, &end, 0)) | ||
952 | return -EINVAL; | ||
953 | if (*end == '\n') | ||
954 | end++; | ||
955 | task = get_proc_task(file->f_path.dentry->d_inode); | ||
956 | if (!task) | ||
957 | return -ESRCH; | ||
958 | mm = get_task_mm(task); | ||
959 | if (mm) { | ||
960 | clear_refs_smap(mm); | ||
961 | mmput(mm); | ||
962 | } | ||
963 | put_task_struct(task); | ||
964 | if (end - buffer == 0) | ||
965 | return -EIO; | ||
966 | return end - buffer; | ||
967 | } | ||
968 | |||
969 | static struct file_operations proc_clear_refs_operations = { | ||
970 | .write = clear_refs_write, | ||
971 | }; | ||
972 | #endif | ||
973 | |||
974 | #ifdef CONFIG_AUDITSYSCALL | 977 | #ifdef CONFIG_AUDITSYSCALL |
975 | #define TMPBUFLEN 21 | 978 | #define TMPBUFLEN 21 |
976 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | 979 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, |
@@ -1161,39 +1164,36 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1161 | int error = -EACCES; | 1164 | int error = -EACCES; |
1162 | 1165 | ||
1163 | /* We don't need a base pointer in the /proc filesystem */ | 1166 | /* We don't need a base pointer in the /proc filesystem */ |
1164 | path_release(nd); | 1167 | path_put(&nd->path); |
1165 | 1168 | ||
1166 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1169 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1167 | if (!proc_fd_access_allowed(inode)) | 1170 | if (!proc_fd_access_allowed(inode)) |
1168 | goto out; | 1171 | goto out; |
1169 | 1172 | ||
1170 | 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); |
1171 | nd->last_type = LAST_BIND; | 1174 | nd->last_type = LAST_BIND; |
1172 | out: | 1175 | out: |
1173 | return ERR_PTR(error); | 1176 | return ERR_PTR(error); |
1174 | } | 1177 | } |
1175 | 1178 | ||
1176 | 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) |
1177 | char __user *buffer, int buflen) | ||
1178 | { | 1180 | { |
1179 | struct inode * inode; | ||
1180 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); | 1181 | char *tmp = (char*)__get_free_page(GFP_TEMPORARY); |
1181 | char *path; | 1182 | char *pathname; |
1182 | int len; | 1183 | int len; |
1183 | 1184 | ||
1184 | if (!tmp) | 1185 | if (!tmp) |
1185 | return -ENOMEM; | 1186 | return -ENOMEM; |
1186 | 1187 | ||
1187 | inode = dentry->d_inode; | 1188 | pathname = d_path(path, tmp, PAGE_SIZE); |
1188 | path = d_path(dentry, mnt, tmp, PAGE_SIZE); | 1189 | len = PTR_ERR(pathname); |
1189 | len = PTR_ERR(path); | 1190 | if (IS_ERR(pathname)) |
1190 | if (IS_ERR(path)) | ||
1191 | goto out; | 1191 | goto out; |
1192 | len = tmp + PAGE_SIZE - 1 - path; | 1192 | len = tmp + PAGE_SIZE - 1 - pathname; |
1193 | 1193 | ||
1194 | if (len > buflen) | 1194 | if (len > buflen) |
1195 | len = buflen; | 1195 | len = buflen; |
1196 | if (copy_to_user(buffer, path, len)) | 1196 | if (copy_to_user(buffer, pathname, len)) |
1197 | len = -EFAULT; | 1197 | len = -EFAULT; |
1198 | out: | 1198 | out: |
1199 | free_page((unsigned long)tmp); | 1199 | free_page((unsigned long)tmp); |
@@ -1204,20 +1204,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b | |||
1204 | { | 1204 | { |
1205 | int error = -EACCES; | 1205 | int error = -EACCES; |
1206 | struct inode *inode = dentry->d_inode; | 1206 | struct inode *inode = dentry->d_inode; |
1207 | struct dentry *de; | 1207 | struct path path; |
1208 | struct vfsmount *mnt = NULL; | ||
1209 | 1208 | ||
1210 | /* Are we allowed to snoop on the tasks file descriptors? */ | 1209 | /* Are we allowed to snoop on the tasks file descriptors? */ |
1211 | if (!proc_fd_access_allowed(inode)) | 1210 | if (!proc_fd_access_allowed(inode)) |
1212 | goto out; | 1211 | goto out; |
1213 | 1212 | ||
1214 | error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); | 1213 | error = PROC_I(inode)->op.proc_get_link(inode, &path); |
1215 | if (error) | 1214 | if (error) |
1216 | goto out; | 1215 | goto out; |
1217 | 1216 | ||
1218 | error = do_proc_readlink(de, mnt, buffer, buflen); | 1217 | error = do_proc_readlink(&path, buffer, buflen); |
1219 | dput(de); | 1218 | path_put(&path); |
1220 | mntput(mnt); | ||
1221 | out: | 1219 | out: |
1222 | return error; | 1220 | return error; |
1223 | } | 1221 | } |
@@ -1444,8 +1442,7 @@ out: | |||
1444 | 1442 | ||
1445 | #define PROC_FDINFO_MAX 64 | 1443 | #define PROC_FDINFO_MAX 64 |
1446 | 1444 | ||
1447 | 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) |
1448 | struct vfsmount **mnt, char *info) | ||
1449 | { | 1446 | { |
1450 | struct task_struct *task = get_proc_task(inode); | 1447 | struct task_struct *task = get_proc_task(inode); |
1451 | struct files_struct *files = NULL; | 1448 | struct files_struct *files = NULL; |
@@ -1464,10 +1461,10 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1464 | spin_lock(&files->file_lock); | 1461 | spin_lock(&files->file_lock); |
1465 | file = fcheck_files(files, fd); | 1462 | file = fcheck_files(files, fd); |
1466 | if (file) { | 1463 | if (file) { |
1467 | if (mnt) | 1464 | if (path) { |
1468 | *mnt = mntget(file->f_path.mnt); | 1465 | *path = file->f_path; |
1469 | if (dentry) | 1466 | path_get(&file->f_path); |
1470 | *dentry = dget(file->f_path.dentry); | 1467 | } |
1471 | if (info) | 1468 | if (info) |
1472 | snprintf(info, PROC_FDINFO_MAX, | 1469 | snprintf(info, PROC_FDINFO_MAX, |
1473 | "pos:\t%lli\n" | 1470 | "pos:\t%lli\n" |
@@ -1484,10 +1481,9 @@ static int proc_fd_info(struct inode *inode, struct dentry **dentry, | |||
1484 | return -ENOENT; | 1481 | return -ENOENT; |
1485 | } | 1482 | } |
1486 | 1483 | ||
1487 | static int proc_fd_link(struct inode *inode, struct dentry **dentry, | 1484 | static int proc_fd_link(struct inode *inode, struct path *path) |
1488 | struct vfsmount **mnt) | ||
1489 | { | 1485 | { |
1490 | return proc_fd_info(inode, dentry, mnt, NULL); | 1486 | return proc_fd_info(inode, path, NULL); |
1491 | } | 1487 | } |
1492 | 1488 | ||
1493 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1489 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) |
@@ -1681,7 +1677,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, | |||
1681 | size_t len, loff_t *ppos) | 1677 | size_t len, loff_t *ppos) |
1682 | { | 1678 | { |
1683 | char tmp[PROC_FDINFO_MAX]; | 1679 | char tmp[PROC_FDINFO_MAX]; |
1684 | 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); |
1685 | if (!err) | 1681 | if (!err) |
1686 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); | 1682 | err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); |
1687 | return err; | 1683 | return err; |
@@ -2098,15 +2094,23 @@ static const struct file_operations proc_coredump_filter_operations = { | |||
2098 | static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | 2094 | static int proc_self_readlink(struct dentry *dentry, char __user *buffer, |
2099 | int buflen) | 2095 | int buflen) |
2100 | { | 2096 | { |
2097 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2098 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2101 | char tmp[PROC_NUMBUF]; | 2099 | char tmp[PROC_NUMBUF]; |
2102 | sprintf(tmp, "%d", task_tgid_vnr(current)); | 2100 | if (!tgid) |
2101 | return -ENOENT; | ||
2102 | sprintf(tmp, "%d", tgid); | ||
2103 | return vfs_readlink(dentry,buffer,buflen,tmp); | 2103 | return vfs_readlink(dentry,buffer,buflen,tmp); |
2104 | } | 2104 | } |
2105 | 2105 | ||
2106 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 2106 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
2107 | { | 2107 | { |
2108 | struct pid_namespace *ns = dentry->d_sb->s_fs_info; | ||
2109 | pid_t tgid = task_tgid_nr_ns(current, ns); | ||
2108 | char tmp[PROC_NUMBUF]; | 2110 | char tmp[PROC_NUMBUF]; |
2109 | sprintf(tmp, "%d", task_tgid_vnr(current)); | 2111 | if (!tgid) |
2112 | return ERR_PTR(-ENOENT); | ||
2113 | sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); | ||
2110 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 2114 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
2111 | } | 2115 | } |
2112 | 2116 | ||
@@ -2271,14 +2275,14 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2271 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2275 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), |
2272 | REG("environ", S_IRUSR, environ), | 2276 | REG("environ", S_IRUSR, environ), |
2273 | INF("auxv", S_IRUSR, pid_auxv), | 2277 | INF("auxv", S_IRUSR, pid_auxv), |
2274 | INF("status", S_IRUGO, pid_status), | 2278 | ONE("status", S_IRUGO, pid_status), |
2275 | INF("limits", S_IRUSR, pid_limits), | 2279 | INF("limits", S_IRUSR, pid_limits), |
2276 | #ifdef CONFIG_SCHED_DEBUG | 2280 | #ifdef CONFIG_SCHED_DEBUG |
2277 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2281 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2278 | #endif | 2282 | #endif |
2279 | INF("cmdline", S_IRUGO, pid_cmdline), | 2283 | INF("cmdline", S_IRUGO, pid_cmdline), |
2280 | INF("stat", S_IRUGO, tgid_stat), | 2284 | ONE("stat", S_IRUGO, tgid_stat), |
2281 | INF("statm", S_IRUGO, pid_statm), | 2285 | ONE("statm", S_IRUGO, pid_statm), |
2282 | REG("maps", S_IRUGO, maps), | 2286 | REG("maps", S_IRUGO, maps), |
2283 | #ifdef CONFIG_NUMA | 2287 | #ifdef CONFIG_NUMA |
2284 | REG("numa_maps", S_IRUGO, numa_maps), | 2288 | REG("numa_maps", S_IRUGO, numa_maps), |
@@ -2289,9 +2293,10 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2289 | LNK("exe", exe), | 2293 | LNK("exe", exe), |
2290 | REG("mounts", S_IRUGO, mounts), | 2294 | REG("mounts", S_IRUGO, mounts), |
2291 | REG("mountstats", S_IRUSR, mountstats), | 2295 | REG("mountstats", S_IRUSR, mountstats), |
2292 | #ifdef CONFIG_MMU | 2296 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2293 | REG("clear_refs", S_IWUSR, clear_refs), | 2297 | REG("clear_refs", S_IWUSR, clear_refs), |
2294 | REG("smaps", S_IRUGO, smaps), | 2298 | REG("smaps", S_IRUGO, smaps), |
2299 | REG("pagemap", S_IRUSR, pagemap), | ||
2295 | #endif | 2300 | #endif |
2296 | #ifdef CONFIG_SECURITY | 2301 | #ifdef CONFIG_SECURITY |
2297 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), | 2302 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), |
@@ -2360,7 +2365,8 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) | |||
2360 | name.len = snprintf(buf, sizeof(buf), "%d", pid); | 2365 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2361 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); | 2366 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); |
2362 | if (dentry) { | 2367 | if (dentry) { |
2363 | shrink_dcache_parent(dentry); | 2368 | if (!(current->flags & PF_EXITING)) |
2369 | shrink_dcache_parent(dentry); | ||
2364 | d_drop(dentry); | 2370 | d_drop(dentry); |
2365 | dput(dentry); | 2371 | dput(dentry); |
2366 | } | 2372 | } |
@@ -2600,14 +2606,14 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2600 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2606 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), |
2601 | REG("environ", S_IRUSR, environ), | 2607 | REG("environ", S_IRUSR, environ), |
2602 | INF("auxv", S_IRUSR, pid_auxv), | 2608 | INF("auxv", S_IRUSR, pid_auxv), |
2603 | INF("status", S_IRUGO, pid_status), | 2609 | ONE("status", S_IRUGO, pid_status), |
2604 | INF("limits", S_IRUSR, pid_limits), | 2610 | INF("limits", S_IRUSR, pid_limits), |
2605 | #ifdef CONFIG_SCHED_DEBUG | 2611 | #ifdef CONFIG_SCHED_DEBUG |
2606 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2612 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2607 | #endif | 2613 | #endif |
2608 | INF("cmdline", S_IRUGO, pid_cmdline), | 2614 | INF("cmdline", S_IRUGO, pid_cmdline), |
2609 | INF("stat", S_IRUGO, tid_stat), | 2615 | ONE("stat", S_IRUGO, tid_stat), |
2610 | INF("statm", S_IRUGO, pid_statm), | 2616 | ONE("statm", S_IRUGO, pid_statm), |
2611 | REG("maps", S_IRUGO, maps), | 2617 | REG("maps", S_IRUGO, maps), |
2612 | #ifdef CONFIG_NUMA | 2618 | #ifdef CONFIG_NUMA |
2613 | REG("numa_maps", S_IRUGO, numa_maps), | 2619 | REG("numa_maps", S_IRUGO, numa_maps), |
@@ -2617,9 +2623,10 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2617 | LNK("root", root), | 2623 | LNK("root", root), |
2618 | LNK("exe", exe), | 2624 | LNK("exe", exe), |
2619 | REG("mounts", S_IRUGO, mounts), | 2625 | REG("mounts", S_IRUGO, mounts), |
2620 | #ifdef CONFIG_MMU | 2626 | #ifdef CONFIG_PROC_PAGE_MONITOR |
2621 | REG("clear_refs", S_IWUSR, clear_refs), | 2627 | REG("clear_refs", S_IWUSR, clear_refs), |
2622 | REG("smaps", S_IRUGO, smaps), | 2628 | REG("smaps", S_IRUGO, smaps), |
2629 | REG("pagemap", S_IRUSR, pagemap), | ||
2623 | #endif | 2630 | #endif |
2624 | #ifdef CONFIG_SECURITY | 2631 | #ifdef CONFIG_SECURITY |
2625 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), | 2632 | DIR("attr", S_IRUGO|S_IXUGO, attr_dir), |