diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Kconfig | 4 | ||||
-rw-r--r-- | fs/proc/base.c | 119 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 3 | ||||
-rw-r--r-- | fs/proc/root.c | 17 | ||||
-rw-r--r-- | fs/proc/softirqs.c | 4 | ||||
-rw-r--r-- | fs/proc/stat.c | 14 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 7 |
7 files changed, 114 insertions, 54 deletions
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index 50f8f0600f06..6a0068841d96 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig | |||
@@ -33,8 +33,8 @@ config PROC_KCORE | |||
33 | depends on PROC_FS && MMU | 33 | depends on PROC_FS && MMU |
34 | 34 | ||
35 | config PROC_VMCORE | 35 | config PROC_VMCORE |
36 | bool "/proc/vmcore support (EXPERIMENTAL)" | 36 | bool "/proc/vmcore support" |
37 | depends on PROC_FS && CRASH_DUMP | 37 | depends on PROC_FS && CRASH_DUMP |
38 | default y | 38 | default y |
39 | help | 39 | help |
40 | Exports the dump image of crashed kernel in ELF format. | 40 | Exports the dump image of crashed kernel in ELF format. |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 8e4addaa5424..f3d02ca461ec 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -226,7 +226,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task) | |||
226 | { | 226 | { |
227 | struct mm_struct *mm; | 227 | struct mm_struct *mm; |
228 | 228 | ||
229 | if (mutex_lock_killable(&task->cred_guard_mutex)) | 229 | if (mutex_lock_killable(&task->signal->cred_guard_mutex)) |
230 | return NULL; | 230 | return NULL; |
231 | 231 | ||
232 | mm = get_task_mm(task); | 232 | mm = get_task_mm(task); |
@@ -235,7 +235,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task) | |||
235 | mmput(mm); | 235 | mmput(mm); |
236 | mm = NULL; | 236 | mm = NULL; |
237 | } | 237 | } |
238 | mutex_unlock(&task->cred_guard_mutex); | 238 | mutex_unlock(&task->signal->cred_guard_mutex); |
239 | 239 | ||
240 | return mm; | 240 | return mm; |
241 | } | 241 | } |
@@ -771,6 +771,8 @@ static const struct file_operations proc_single_file_operations = { | |||
771 | static int mem_open(struct inode* inode, struct file* file) | 771 | static int mem_open(struct inode* inode, struct file* file) |
772 | { | 772 | { |
773 | file->private_data = (void*)((long)current->self_exec_id); | 773 | file->private_data = (void*)((long)current->self_exec_id); |
774 | /* OK to pass negative loff_t, we can catch out-of-range */ | ||
775 | file->f_mode |= FMODE_UNSIGNED_OFFSET; | ||
774 | return 0; | 776 | return 0; |
775 | } | 777 | } |
776 | 778 | ||
@@ -1023,28 +1025,47 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
1023 | memset(buffer, 0, sizeof(buffer)); | 1025 | memset(buffer, 0, sizeof(buffer)); |
1024 | if (count > sizeof(buffer) - 1) | 1026 | if (count > sizeof(buffer) - 1) |
1025 | count = sizeof(buffer) - 1; | 1027 | count = sizeof(buffer) - 1; |
1026 | if (copy_from_user(buffer, buf, count)) | 1028 | if (copy_from_user(buffer, buf, count)) { |
1027 | return -EFAULT; | 1029 | err = -EFAULT; |
1030 | goto out; | ||
1031 | } | ||
1028 | 1032 | ||
1029 | err = strict_strtol(strstrip(buffer), 0, &oom_adjust); | 1033 | err = strict_strtol(strstrip(buffer), 0, &oom_adjust); |
1030 | if (err) | 1034 | if (err) |
1031 | return -EINVAL; | 1035 | goto out; |
1032 | if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) && | 1036 | if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) && |
1033 | oom_adjust != OOM_DISABLE) | 1037 | oom_adjust != OOM_DISABLE) { |
1034 | return -EINVAL; | 1038 | err = -EINVAL; |
1039 | goto out; | ||
1040 | } | ||
1035 | 1041 | ||
1036 | task = get_proc_task(file->f_path.dentry->d_inode); | 1042 | task = get_proc_task(file->f_path.dentry->d_inode); |
1037 | if (!task) | 1043 | if (!task) { |
1038 | return -ESRCH; | 1044 | err = -ESRCH; |
1045 | goto out; | ||
1046 | } | ||
1047 | |||
1048 | task_lock(task); | ||
1049 | if (!task->mm) { | ||
1050 | err = -EINVAL; | ||
1051 | goto err_task_lock; | ||
1052 | } | ||
1053 | |||
1039 | if (!lock_task_sighand(task, &flags)) { | 1054 | if (!lock_task_sighand(task, &flags)) { |
1040 | put_task_struct(task); | 1055 | err = -ESRCH; |
1041 | return -ESRCH; | 1056 | goto err_task_lock; |
1042 | } | 1057 | } |
1043 | 1058 | ||
1044 | if (oom_adjust < task->signal->oom_adj && !capable(CAP_SYS_RESOURCE)) { | 1059 | if (oom_adjust < task->signal->oom_adj && !capable(CAP_SYS_RESOURCE)) { |
1045 | unlock_task_sighand(task, &flags); | 1060 | err = -EACCES; |
1046 | put_task_struct(task); | 1061 | goto err_sighand; |
1047 | return -EACCES; | 1062 | } |
1063 | |||
1064 | if (oom_adjust != task->signal->oom_adj) { | ||
1065 | if (oom_adjust == OOM_DISABLE) | ||
1066 | atomic_inc(&task->mm->oom_disable_count); | ||
1067 | if (task->signal->oom_adj == OOM_DISABLE) | ||
1068 | atomic_dec(&task->mm->oom_disable_count); | ||
1048 | } | 1069 | } |
1049 | 1070 | ||
1050 | /* | 1071 | /* |
@@ -1065,10 +1086,13 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
1065 | else | 1086 | else |
1066 | task->signal->oom_score_adj = (oom_adjust * OOM_SCORE_ADJ_MAX) / | 1087 | task->signal->oom_score_adj = (oom_adjust * OOM_SCORE_ADJ_MAX) / |
1067 | -OOM_DISABLE; | 1088 | -OOM_DISABLE; |
1089 | err_sighand: | ||
1068 | unlock_task_sighand(task, &flags); | 1090 | unlock_task_sighand(task, &flags); |
1091 | err_task_lock: | ||
1092 | task_unlock(task); | ||
1069 | put_task_struct(task); | 1093 | put_task_struct(task); |
1070 | 1094 | out: | |
1071 | return count; | 1095 | return err < 0 ? err : count; |
1072 | } | 1096 | } |
1073 | 1097 | ||
1074 | static const struct file_operations proc_oom_adjust_operations = { | 1098 | static const struct file_operations proc_oom_adjust_operations = { |
@@ -1109,30 +1133,49 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1109 | memset(buffer, 0, sizeof(buffer)); | 1133 | memset(buffer, 0, sizeof(buffer)); |
1110 | if (count > sizeof(buffer) - 1) | 1134 | if (count > sizeof(buffer) - 1) |
1111 | count = sizeof(buffer) - 1; | 1135 | count = sizeof(buffer) - 1; |
1112 | if (copy_from_user(buffer, buf, count)) | 1136 | if (copy_from_user(buffer, buf, count)) { |
1113 | return -EFAULT; | 1137 | err = -EFAULT; |
1138 | goto out; | ||
1139 | } | ||
1114 | 1140 | ||
1115 | err = strict_strtol(strstrip(buffer), 0, &oom_score_adj); | 1141 | err = strict_strtol(strstrip(buffer), 0, &oom_score_adj); |
1116 | if (err) | 1142 | if (err) |
1117 | return -EINVAL; | 1143 | goto out; |
1118 | if (oom_score_adj < OOM_SCORE_ADJ_MIN || | 1144 | if (oom_score_adj < OOM_SCORE_ADJ_MIN || |
1119 | oom_score_adj > OOM_SCORE_ADJ_MAX) | 1145 | oom_score_adj > OOM_SCORE_ADJ_MAX) { |
1120 | return -EINVAL; | 1146 | err = -EINVAL; |
1147 | goto out; | ||
1148 | } | ||
1121 | 1149 | ||
1122 | task = get_proc_task(file->f_path.dentry->d_inode); | 1150 | task = get_proc_task(file->f_path.dentry->d_inode); |
1123 | if (!task) | 1151 | if (!task) { |
1124 | return -ESRCH; | 1152 | err = -ESRCH; |
1153 | goto out; | ||
1154 | } | ||
1155 | |||
1156 | task_lock(task); | ||
1157 | if (!task->mm) { | ||
1158 | err = -EINVAL; | ||
1159 | goto err_task_lock; | ||
1160 | } | ||
1161 | |||
1125 | if (!lock_task_sighand(task, &flags)) { | 1162 | if (!lock_task_sighand(task, &flags)) { |
1126 | put_task_struct(task); | 1163 | err = -ESRCH; |
1127 | return -ESRCH; | 1164 | goto err_task_lock; |
1128 | } | 1165 | } |
1166 | |||
1129 | if (oom_score_adj < task->signal->oom_score_adj && | 1167 | if (oom_score_adj < task->signal->oom_score_adj && |
1130 | !capable(CAP_SYS_RESOURCE)) { | 1168 | !capable(CAP_SYS_RESOURCE)) { |
1131 | unlock_task_sighand(task, &flags); | 1169 | err = -EACCES; |
1132 | put_task_struct(task); | 1170 | goto err_sighand; |
1133 | return -EACCES; | ||
1134 | } | 1171 | } |
1135 | 1172 | ||
1173 | if (oom_score_adj != task->signal->oom_score_adj) { | ||
1174 | if (oom_score_adj == OOM_SCORE_ADJ_MIN) | ||
1175 | atomic_inc(&task->mm->oom_disable_count); | ||
1176 | if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) | ||
1177 | atomic_dec(&task->mm->oom_disable_count); | ||
1178 | } | ||
1136 | task->signal->oom_score_adj = oom_score_adj; | 1179 | task->signal->oom_score_adj = oom_score_adj; |
1137 | /* | 1180 | /* |
1138 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is | 1181 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is |
@@ -1143,14 +1186,19 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1143 | else | 1186 | else |
1144 | task->signal->oom_adj = (oom_score_adj * OOM_ADJUST_MAX) / | 1187 | task->signal->oom_adj = (oom_score_adj * OOM_ADJUST_MAX) / |
1145 | OOM_SCORE_ADJ_MAX; | 1188 | OOM_SCORE_ADJ_MAX; |
1189 | err_sighand: | ||
1146 | unlock_task_sighand(task, &flags); | 1190 | unlock_task_sighand(task, &flags); |
1191 | err_task_lock: | ||
1192 | task_unlock(task); | ||
1147 | put_task_struct(task); | 1193 | put_task_struct(task); |
1148 | return count; | 1194 | out: |
1195 | return err < 0 ? err : count; | ||
1149 | } | 1196 | } |
1150 | 1197 | ||
1151 | static const struct file_operations proc_oom_score_adj_operations = { | 1198 | static const struct file_operations proc_oom_score_adj_operations = { |
1152 | .read = oom_score_adj_read, | 1199 | .read = oom_score_adj_read, |
1153 | .write = oom_score_adj_write, | 1200 | .write = oom_score_adj_write, |
1201 | .llseek = default_llseek, | ||
1154 | }; | 1202 | }; |
1155 | 1203 | ||
1156 | #ifdef CONFIG_AUDITSYSCALL | 1204 | #ifdef CONFIG_AUDITSYSCALL |
@@ -1600,6 +1648,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st | |||
1600 | 1648 | ||
1601 | /* Common stuff */ | 1649 | /* Common stuff */ |
1602 | ei = PROC_I(inode); | 1650 | ei = PROC_I(inode); |
1651 | inode->i_ino = get_next_ino(); | ||
1603 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 1652 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
1604 | inode->i_op = &proc_def_inode_operations; | 1653 | inode->i_op = &proc_def_inode_operations; |
1605 | 1654 | ||
@@ -2039,11 +2088,13 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, | |||
2039 | static const struct file_operations proc_fdinfo_file_operations = { | 2088 | static const struct file_operations proc_fdinfo_file_operations = { |
2040 | .open = nonseekable_open, | 2089 | .open = nonseekable_open, |
2041 | .read = proc_fdinfo_read, | 2090 | .read = proc_fdinfo_read, |
2091 | .llseek = no_llseek, | ||
2042 | }; | 2092 | }; |
2043 | 2093 | ||
2044 | static const struct file_operations proc_fd_operations = { | 2094 | static const struct file_operations proc_fd_operations = { |
2045 | .read = generic_read_dir, | 2095 | .read = generic_read_dir, |
2046 | .readdir = proc_readfd, | 2096 | .readdir = proc_readfd, |
2097 | .llseek = default_llseek, | ||
2047 | }; | 2098 | }; |
2048 | 2099 | ||
2049 | /* | 2100 | /* |
@@ -2112,6 +2163,7 @@ static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir) | |||
2112 | static const struct file_operations proc_fdinfo_operations = { | 2163 | static const struct file_operations proc_fdinfo_operations = { |
2113 | .read = generic_read_dir, | 2164 | .read = generic_read_dir, |
2114 | .readdir = proc_readfdinfo, | 2165 | .readdir = proc_readfdinfo, |
2166 | .llseek = default_llseek, | ||
2115 | }; | 2167 | }; |
2116 | 2168 | ||
2117 | /* | 2169 | /* |
@@ -2302,14 +2354,14 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | |||
2302 | goto out_free; | 2354 | goto out_free; |
2303 | 2355 | ||
2304 | /* Guard against adverse ptrace interaction */ | 2356 | /* Guard against adverse ptrace interaction */ |
2305 | length = mutex_lock_interruptible(&task->cred_guard_mutex); | 2357 | length = mutex_lock_interruptible(&task->signal->cred_guard_mutex); |
2306 | if (length < 0) | 2358 | if (length < 0) |
2307 | goto out_free; | 2359 | goto out_free; |
2308 | 2360 | ||
2309 | length = security_setprocattr(task, | 2361 | length = security_setprocattr(task, |
2310 | (char*)file->f_path.dentry->d_name.name, | 2362 | (char*)file->f_path.dentry->d_name.name, |
2311 | (void*)page, count); | 2363 | (void*)page, count); |
2312 | mutex_unlock(&task->cred_guard_mutex); | 2364 | mutex_unlock(&task->signal->cred_guard_mutex); |
2313 | out_free: | 2365 | out_free: |
2314 | free_page((unsigned long) page); | 2366 | free_page((unsigned long) page); |
2315 | out: | 2367 | out: |
@@ -2343,6 +2395,7 @@ static int proc_attr_dir_readdir(struct file * filp, | |||
2343 | static const struct file_operations proc_attr_dir_operations = { | 2395 | static const struct file_operations proc_attr_dir_operations = { |
2344 | .read = generic_read_dir, | 2396 | .read = generic_read_dir, |
2345 | .readdir = proc_attr_dir_readdir, | 2397 | .readdir = proc_attr_dir_readdir, |
2398 | .llseek = default_llseek, | ||
2346 | }; | 2399 | }; |
2347 | 2400 | ||
2348 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, | 2401 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, |
@@ -2542,6 +2595,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir, | |||
2542 | 2595 | ||
2543 | /* Initialize the inode */ | 2596 | /* Initialize the inode */ |
2544 | ei = PROC_I(inode); | 2597 | ei = PROC_I(inode); |
2598 | inode->i_ino = get_next_ino(); | ||
2545 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 2599 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
2546 | 2600 | ||
2547 | /* | 2601 | /* |
@@ -2751,6 +2805,7 @@ static int proc_tgid_base_readdir(struct file * filp, | |||
2751 | static const struct file_operations proc_tgid_base_operations = { | 2805 | static const struct file_operations proc_tgid_base_operations = { |
2752 | .read = generic_read_dir, | 2806 | .read = generic_read_dir, |
2753 | .readdir = proc_tgid_base_readdir, | 2807 | .readdir = proc_tgid_base_readdir, |
2808 | .llseek = default_llseek, | ||
2754 | }; | 2809 | }; |
2755 | 2810 | ||
2756 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 2811 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ |
@@ -3088,6 +3143,7 @@ static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *den | |||
3088 | static const struct file_operations proc_tid_base_operations = { | 3143 | static const struct file_operations proc_tid_base_operations = { |
3089 | .read = generic_read_dir, | 3144 | .read = generic_read_dir, |
3090 | .readdir = proc_tid_base_readdir, | 3145 | .readdir = proc_tid_base_readdir, |
3146 | .llseek = default_llseek, | ||
3091 | }; | 3147 | }; |
3092 | 3148 | ||
3093 | static const struct inode_operations proc_tid_base_inode_operations = { | 3149 | static const struct inode_operations proc_tid_base_inode_operations = { |
@@ -3324,4 +3380,5 @@ static const struct inode_operations proc_task_inode_operations = { | |||
3324 | static const struct file_operations proc_task_operations = { | 3380 | static const struct file_operations proc_task_operations = { |
3325 | .read = generic_read_dir, | 3381 | .read = generic_read_dir, |
3326 | .readdir = proc_task_readdir, | 3382 | .readdir = proc_task_readdir, |
3383 | .llseek = default_llseek, | ||
3327 | }; | 3384 | }; |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 5be436ea088e..b652cb00906b 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -23,6 +23,8 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, | |||
23 | if (!inode) | 23 | if (!inode) |
24 | goto out; | 24 | goto out; |
25 | 25 | ||
26 | inode->i_ino = get_next_ino(); | ||
27 | |||
26 | sysctl_head_get(head); | 28 | sysctl_head_get(head); |
27 | ei = PROC_I(inode); | 29 | ei = PROC_I(inode); |
28 | ei->sysctl = head; | 30 | ei->sysctl = head; |
@@ -364,6 +366,7 @@ static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct | |||
364 | static const struct file_operations proc_sys_file_operations = { | 366 | static const struct file_operations proc_sys_file_operations = { |
365 | .read = proc_sys_read, | 367 | .read = proc_sys_read, |
366 | .write = proc_sys_write, | 368 | .write = proc_sys_write, |
369 | .llseek = default_llseek, | ||
367 | }; | 370 | }; |
368 | 371 | ||
369 | static const struct file_operations proc_sys_dir_file_operations = { | 372 | static const struct file_operations proc_sys_dir_file_operations = { |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 4258384ed22d..ef9fa8e24ad6 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -35,8 +35,8 @@ static int proc_set_super(struct super_block *sb, void *data) | |||
35 | return set_anon_super(sb, NULL); | 35 | return set_anon_super(sb, NULL); |
36 | } | 36 | } |
37 | 37 | ||
38 | static int proc_get_sb(struct file_system_type *fs_type, | 38 | static struct dentry *proc_mount(struct file_system_type *fs_type, |
39 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 39 | int flags, const char *dev_name, void *data) |
40 | { | 40 | { |
41 | int err; | 41 | int err; |
42 | struct super_block *sb; | 42 | struct super_block *sb; |
@@ -61,14 +61,14 @@ static int proc_get_sb(struct file_system_type *fs_type, | |||
61 | 61 | ||
62 | sb = sget(fs_type, proc_test_super, proc_set_super, ns); | 62 | sb = sget(fs_type, proc_test_super, proc_set_super, ns); |
63 | if (IS_ERR(sb)) | 63 | if (IS_ERR(sb)) |
64 | return PTR_ERR(sb); | 64 | return ERR_CAST(sb); |
65 | 65 | ||
66 | if (!sb->s_root) { | 66 | if (!sb->s_root) { |
67 | sb->s_flags = flags; | 67 | sb->s_flags = flags; |
68 | err = proc_fill_super(sb); | 68 | err = proc_fill_super(sb); |
69 | if (err) { | 69 | if (err) { |
70 | deactivate_locked_super(sb); | 70 | deactivate_locked_super(sb); |
71 | return err; | 71 | return ERR_PTR(err); |
72 | } | 72 | } |
73 | 73 | ||
74 | ei = PROC_I(sb->s_root->d_inode); | 74 | ei = PROC_I(sb->s_root->d_inode); |
@@ -79,11 +79,9 @@ static int proc_get_sb(struct file_system_type *fs_type, | |||
79 | } | 79 | } |
80 | 80 | ||
81 | sb->s_flags |= MS_ACTIVE; | 81 | sb->s_flags |= MS_ACTIVE; |
82 | ns->proc_mnt = mnt; | ||
83 | } | 82 | } |
84 | 83 | ||
85 | simple_set_mnt(mnt, sb); | 84 | return dget(sb->s_root); |
86 | return 0; | ||
87 | } | 85 | } |
88 | 86 | ||
89 | static void proc_kill_sb(struct super_block *sb) | 87 | static void proc_kill_sb(struct super_block *sb) |
@@ -97,7 +95,7 @@ static void proc_kill_sb(struct super_block *sb) | |||
97 | 95 | ||
98 | static struct file_system_type proc_fs_type = { | 96 | static struct file_system_type proc_fs_type = { |
99 | .name = "proc", | 97 | .name = "proc", |
100 | .get_sb = proc_get_sb, | 98 | .mount = proc_mount, |
101 | .kill_sb = proc_kill_sb, | 99 | .kill_sb = proc_kill_sb, |
102 | }; | 100 | }; |
103 | 101 | ||
@@ -115,6 +113,7 @@ void __init proc_root_init(void) | |||
115 | return; | 113 | return; |
116 | } | 114 | } |
117 | 115 | ||
116 | init_pid_ns.proc_mnt = proc_mnt; | ||
118 | proc_symlink("mounts", NULL, "self/mounts"); | 117 | proc_symlink("mounts", NULL, "self/mounts"); |
119 | 118 | ||
120 | proc_net_init(); | 119 | proc_net_init(); |
@@ -179,6 +178,7 @@ static int proc_root_readdir(struct file * filp, | |||
179 | static const struct file_operations proc_root_operations = { | 178 | static const struct file_operations proc_root_operations = { |
180 | .read = generic_read_dir, | 179 | .read = generic_read_dir, |
181 | .readdir = proc_root_readdir, | 180 | .readdir = proc_root_readdir, |
181 | .llseek = default_llseek, | ||
182 | }; | 182 | }; |
183 | 183 | ||
184 | /* | 184 | /* |
@@ -212,6 +212,7 @@ int pid_ns_prepare_proc(struct pid_namespace *ns) | |||
212 | if (IS_ERR(mnt)) | 212 | if (IS_ERR(mnt)) |
213 | return PTR_ERR(mnt); | 213 | return PTR_ERR(mnt); |
214 | 214 | ||
215 | ns->proc_mnt = mnt; | ||
215 | return 0; | 216 | return 0; |
216 | } | 217 | } |
217 | 218 | ||
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c index 1807c2419f17..37994737c983 100644 --- a/fs/proc/softirqs.c +++ b/fs/proc/softirqs.c | |||
@@ -10,13 +10,13 @@ static int show_softirqs(struct seq_file *p, void *v) | |||
10 | { | 10 | { |
11 | int i, j; | 11 | int i, j; |
12 | 12 | ||
13 | seq_printf(p, " "); | 13 | seq_printf(p, " "); |
14 | for_each_possible_cpu(i) | 14 | for_each_possible_cpu(i) |
15 | seq_printf(p, "CPU%-8d", i); | 15 | seq_printf(p, "CPU%-8d", i); |
16 | seq_printf(p, "\n"); | 16 | seq_printf(p, "\n"); |
17 | 17 | ||
18 | for (i = 0; i < NR_SOFTIRQS; i++) { | 18 | for (i = 0; i < NR_SOFTIRQS; i++) { |
19 | seq_printf(p, "%8s:", softirq_to_name[i]); | 19 | seq_printf(p, "%12s:", softirq_to_name[i]); |
20 | for_each_possible_cpu(j) | 20 | for_each_possible_cpu(j) |
21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); | 21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); |
22 | seq_printf(p, "\n"); | 22 | seq_printf(p, "\n"); |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index bf31b03fc275..e15a19c93bae 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -31,7 +31,6 @@ static int show_stat(struct seq_file *p, void *v) | |||
31 | u64 sum_softirq = 0; | 31 | u64 sum_softirq = 0; |
32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | 32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; |
33 | struct timespec boottime; | 33 | struct timespec boottime; |
34 | unsigned int per_irq_sum; | ||
35 | 34 | ||
36 | user = nice = system = idle = iowait = | 35 | user = nice = system = idle = iowait = |
37 | irq = softirq = steal = cputime64_zero; | 36 | irq = softirq = steal = cputime64_zero; |
@@ -52,9 +51,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
52 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); | 51 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); |
53 | guest_nice = cputime64_add(guest_nice, | 52 | guest_nice = cputime64_add(guest_nice, |
54 | kstat_cpu(i).cpustat.guest_nice); | 53 | kstat_cpu(i).cpustat.guest_nice); |
55 | for_each_irq_nr(j) { | 54 | sum += kstat_cpu_irqs_sum(i); |
56 | sum += kstat_irqs_cpu(j, i); | ||
57 | } | ||
58 | sum += arch_irq_stat_cpu(i); | 55 | sum += arch_irq_stat_cpu(i); |
59 | 56 | ||
60 | for (j = 0; j < NR_SOFTIRQS; j++) { | 57 | for (j = 0; j < NR_SOFTIRQS; j++) { |
@@ -110,13 +107,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
110 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 107 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
111 | 108 | ||
112 | /* sum again ? it could be updated? */ | 109 | /* sum again ? it could be updated? */ |
113 | for_each_irq_nr(j) { | 110 | for_each_irq_nr(j) |
114 | per_irq_sum = 0; | 111 | seq_printf(p, " %u", kstat_irqs(j)); |
115 | for_each_possible_cpu(i) | ||
116 | per_irq_sum += kstat_irqs_cpu(j, i); | ||
117 | |||
118 | seq_printf(p, " %u", per_irq_sum); | ||
119 | } | ||
120 | 112 | ||
121 | seq_printf(p, | 113 | seq_printf(p, |
122 | "\nctxt %llu\n" | 114 | "\nctxt %llu\n" |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 1dbca4e8cc16..da6b01d70f01 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -327,6 +327,7 @@ struct mem_size_stats { | |||
327 | unsigned long private_clean; | 327 | unsigned long private_clean; |
328 | unsigned long private_dirty; | 328 | unsigned long private_dirty; |
329 | unsigned long referenced; | 329 | unsigned long referenced; |
330 | unsigned long anonymous; | ||
330 | unsigned long swap; | 331 | unsigned long swap; |
331 | u64 pss; | 332 | u64 pss; |
332 | }; | 333 | }; |
@@ -357,6 +358,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
357 | if (!page) | 358 | if (!page) |
358 | continue; | 359 | continue; |
359 | 360 | ||
361 | if (PageAnon(page)) | ||
362 | mss->anonymous += PAGE_SIZE; | ||
363 | |||
360 | mss->resident += PAGE_SIZE; | 364 | mss->resident += PAGE_SIZE; |
361 | /* Accumulate the size in pages that have been accessed. */ | 365 | /* Accumulate the size in pages that have been accessed. */ |
362 | if (pte_young(ptent) || PageReferenced(page)) | 366 | if (pte_young(ptent) || PageReferenced(page)) |
@@ -410,6 +414,7 @@ static int show_smap(struct seq_file *m, void *v) | |||
410 | "Private_Clean: %8lu kB\n" | 414 | "Private_Clean: %8lu kB\n" |
411 | "Private_Dirty: %8lu kB\n" | 415 | "Private_Dirty: %8lu kB\n" |
412 | "Referenced: %8lu kB\n" | 416 | "Referenced: %8lu kB\n" |
417 | "Anonymous: %8lu kB\n" | ||
413 | "Swap: %8lu kB\n" | 418 | "Swap: %8lu kB\n" |
414 | "KernelPageSize: %8lu kB\n" | 419 | "KernelPageSize: %8lu kB\n" |
415 | "MMUPageSize: %8lu kB\n", | 420 | "MMUPageSize: %8lu kB\n", |
@@ -421,6 +426,7 @@ static int show_smap(struct seq_file *m, void *v) | |||
421 | mss.private_clean >> 10, | 426 | mss.private_clean >> 10, |
422 | mss.private_dirty >> 10, | 427 | mss.private_dirty >> 10, |
423 | mss.referenced >> 10, | 428 | mss.referenced >> 10, |
429 | mss.anonymous >> 10, | ||
424 | mss.swap >> 10, | 430 | mss.swap >> 10, |
425 | vma_kernel_pagesize(vma) >> 10, | 431 | vma_kernel_pagesize(vma) >> 10, |
426 | vma_mmu_pagesize(vma) >> 10); | 432 | vma_mmu_pagesize(vma) >> 10); |
@@ -539,6 +545,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
539 | 545 | ||
540 | const struct file_operations proc_clear_refs_operations = { | 546 | const struct file_operations proc_clear_refs_operations = { |
541 | .write = clear_refs_write, | 547 | .write = clear_refs_write, |
548 | .llseek = noop_llseek, | ||
542 | }; | 549 | }; |
543 | 550 | ||
544 | struct pagemapread { | 551 | struct pagemapread { |