diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:17:07 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:17:07 -0500 |
commit | e11d57ca0b6dada29007ce3ad3db6c84034a768f (patch) | |
tree | 39ad0c208e2cb3da79f958bd0e9d0d12b8e5f8fe /fs/proc | |
parent | 317495b25ec1f0beb0dbac8ee0dfec59a1addf03 (diff) | |
parent | a2c06ee2fe5b48a71e697bae00c6e7195fc016b6 (diff) |
Merge remote-tracking branch 'airlied/drm-core-next' into drm-nouveau-next
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/Kconfig | 6 | ||||
-rw-r--r-- | fs/proc/Makefile | 1 | ||||
-rw-r--r-- | fs/proc/array.c | 28 | ||||
-rw-r--r-- | fs/proc/base.c | 183 | ||||
-rw-r--r-- | fs/proc/consoles.c | 114 | ||||
-rw-r--r-- | fs/proc/devices.c | 4 | ||||
-rw-r--r-- | fs/proc/generic.c | 21 | ||||
-rw-r--r-- | fs/proc/inode.c | 16 | ||||
-rw-r--r-- | fs/proc/internal.h | 5 | ||||
-rw-r--r-- | fs/proc/kcore.c | 2 | ||||
-rw-r--r-- | fs/proc/meminfo.c | 14 | ||||
-rw-r--r-- | fs/proc/page.c | 16 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 31 | ||||
-rw-r--r-- | fs/proc/proc_tty.c | 26 | ||||
-rw-r--r-- | fs/proc/softirqs.c | 6 | ||||
-rw-r--r-- | fs/proc/stat.c | 2 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 15 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 7 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 2 |
19 files changed, 357 insertions, 142 deletions
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index 6a0068841d96..15af6222f8a4 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig | |||
@@ -1,5 +1,5 @@ | |||
1 | config PROC_FS | 1 | config PROC_FS |
2 | bool "/proc file system support" if EMBEDDED | 2 | bool "/proc file system support" if EXPERT |
3 | default y | 3 | default y |
4 | help | 4 | help |
5 | This is a virtual file system providing information about the status | 5 | This is a virtual file system providing information about the status |
@@ -40,7 +40,7 @@ config PROC_VMCORE | |||
40 | Exports the dump image of crashed kernel in ELF format. | 40 | Exports the dump image of crashed kernel in ELF format. |
41 | 41 | ||
42 | config PROC_SYSCTL | 42 | config PROC_SYSCTL |
43 | bool "Sysctl support (/proc/sys)" if EMBEDDED | 43 | bool "Sysctl support (/proc/sys)" if EXPERT |
44 | depends on PROC_FS | 44 | depends on PROC_FS |
45 | select SYSCTL | 45 | select SYSCTL |
46 | default y | 46 | default y |
@@ -61,7 +61,7 @@ config PROC_SYSCTL | |||
61 | config PROC_PAGE_MONITOR | 61 | config PROC_PAGE_MONITOR |
62 | default y | 62 | default y |
63 | depends on PROC_FS && MMU | 63 | depends on PROC_FS && MMU |
64 | bool "Enable /proc page monitoring" if EMBEDDED | 64 | bool "Enable /proc page monitoring" if EXPERT |
65 | help | 65 | help |
66 | Various /proc files exist to monitor process memory utilization: | 66 | Various /proc files exist to monitor process memory utilization: |
67 | /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap, | 67 | /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap, |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 2758e2afc518..df434c5f28fb 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -10,6 +10,7 @@ proc-$(CONFIG_MMU) := mmu.o task_mmu.o | |||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | proc_tty.o | 11 | proc_tty.o |
12 | proc-y += cmdline.o | 12 | proc-y += cmdline.o |
13 | proc-y += consoles.o | ||
13 | proc-y += cpuinfo.o | 14 | proc-y += cpuinfo.o |
14 | proc-y += devices.o | 15 | proc-y += devices.o |
15 | proc-y += interrupts.o | 16 | proc-y += interrupts.o |
diff --git a/fs/proc/array.c b/fs/proc/array.c index fff6572676ae..df2b703b9d0f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -95,7 +95,7 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) | |||
95 | 95 | ||
96 | get_task_comm(tcomm, p); | 96 | get_task_comm(tcomm, p); |
97 | 97 | ||
98 | seq_printf(m, "Name:\t"); | 98 | seq_puts(m, "Name:\t"); |
99 | end = m->buf + m->size; | 99 | end = m->buf + m->size; |
100 | buf = m->buf + m->count; | 100 | buf = m->buf + m->count; |
101 | name = tcomm; | 101 | name = tcomm; |
@@ -122,7 +122,7 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) | |||
122 | buf++; | 122 | buf++; |
123 | } | 123 | } |
124 | m->count = buf - m->buf; | 124 | m->count = buf - m->buf; |
125 | seq_printf(m, "\n"); | 125 | seq_putc(m, '\n'); |
126 | } | 126 | } |
127 | 127 | ||
128 | /* | 128 | /* |
@@ -208,7 +208,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
208 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); | 208 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); |
209 | put_cred(cred); | 209 | put_cred(cred); |
210 | 210 | ||
211 | seq_printf(m, "\n"); | 211 | seq_putc(m, '\n'); |
212 | } | 212 | } |
213 | 213 | ||
214 | static void render_sigset_t(struct seq_file *m, const char *header, | 214 | static void render_sigset_t(struct seq_file *m, const char *header, |
@@ -216,7 +216,7 @@ static void render_sigset_t(struct seq_file *m, const char *header, | |||
216 | { | 216 | { |
217 | int i; | 217 | int i; |
218 | 218 | ||
219 | seq_printf(m, "%s", header); | 219 | seq_puts(m, header); |
220 | 220 | ||
221 | i = _NSIG; | 221 | i = _NSIG; |
222 | do { | 222 | do { |
@@ -230,7 +230,7 @@ static void render_sigset_t(struct seq_file *m, const char *header, | |||
230 | seq_printf(m, "%x", x); | 230 | seq_printf(m, "%x", x); |
231 | } while (i >= 4); | 231 | } while (i >= 4); |
232 | 232 | ||
233 | seq_printf(m, "\n"); | 233 | seq_putc(m, '\n'); |
234 | } | 234 | } |
235 | 235 | ||
236 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, | 236 | static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, |
@@ -291,12 +291,12 @@ static void render_cap_t(struct seq_file *m, const char *header, | |||
291 | { | 291 | { |
292 | unsigned __capi; | 292 | unsigned __capi; |
293 | 293 | ||
294 | seq_printf(m, "%s", header); | 294 | seq_puts(m, header); |
295 | CAP_FOR_EACH_U32(__capi) { | 295 | CAP_FOR_EACH_U32(__capi) { |
296 | seq_printf(m, "%08x", | 296 | seq_printf(m, "%08x", |
297 | a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); | 297 | a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); |
298 | } | 298 | } |
299 | seq_printf(m, "\n"); | 299 | seq_putc(m, '\n'); |
300 | } | 300 | } |
301 | 301 | ||
302 | static inline void task_cap(struct seq_file *m, struct task_struct *p) | 302 | static inline void task_cap(struct seq_file *m, struct task_struct *p) |
@@ -329,12 +329,12 @@ static inline void task_context_switch_counts(struct seq_file *m, | |||
329 | 329 | ||
330 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) | 330 | static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) |
331 | { | 331 | { |
332 | seq_printf(m, "Cpus_allowed:\t"); | 332 | seq_puts(m, "Cpus_allowed:\t"); |
333 | seq_cpumask(m, &task->cpus_allowed); | 333 | seq_cpumask(m, &task->cpus_allowed); |
334 | seq_printf(m, "\n"); | 334 | seq_putc(m, '\n'); |
335 | seq_printf(m, "Cpus_allowed_list:\t"); | 335 | seq_puts(m, "Cpus_allowed_list:\t"); |
336 | seq_cpumask_list(m, &task->cpus_allowed); | 336 | seq_cpumask_list(m, &task->cpus_allowed); |
337 | seq_printf(m, "\n"); | 337 | seq_putc(m, '\n'); |
338 | } | 338 | } |
339 | 339 | ||
340 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, | 340 | int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
@@ -535,15 +535,15 @@ int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | |||
535 | int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, | 535 | int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, |
536 | struct pid *pid, struct task_struct *task) | 536 | struct pid *pid, struct task_struct *task) |
537 | { | 537 | { |
538 | int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0; | 538 | unsigned long size = 0, resident = 0, shared = 0, text = 0, data = 0; |
539 | struct mm_struct *mm = get_task_mm(task); | 539 | struct mm_struct *mm = get_task_mm(task); |
540 | 540 | ||
541 | if (mm) { | 541 | if (mm) { |
542 | size = task_statm(mm, &shared, &text, &data, &resident); | 542 | size = task_statm(mm, &shared, &text, &data, &resident); |
543 | mmput(mm); | 543 | mmput(mm); |
544 | } | 544 | } |
545 | seq_printf(m, "%d %d %d %d %d %d %d\n", | 545 | seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n", |
546 | size, resident, shared, text, lib, data, 0); | 546 | size, resident, shared, text, data); |
547 | 547 | ||
548 | return 0; | 548 | return 0; |
549 | } | 549 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index f3d02ca461ec..9d096e82b201 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -373,26 +373,20 @@ static int lstats_show_proc(struct seq_file *m, void *v) | |||
373 | return -ESRCH; | 373 | return -ESRCH; |
374 | seq_puts(m, "Latency Top version : v0.1\n"); | 374 | seq_puts(m, "Latency Top version : v0.1\n"); |
375 | for (i = 0; i < 32; i++) { | 375 | for (i = 0; i < 32; i++) { |
376 | if (task->latency_record[i].backtrace[0]) { | 376 | struct latency_record *lr = &task->latency_record[i]; |
377 | if (lr->backtrace[0]) { | ||
377 | int q; | 378 | int q; |
378 | seq_printf(m, "%i %li %li ", | 379 | seq_printf(m, "%i %li %li", |
379 | task->latency_record[i].count, | 380 | lr->count, lr->time, lr->max); |
380 | task->latency_record[i].time, | ||
381 | task->latency_record[i].max); | ||
382 | for (q = 0; q < LT_BACKTRACEDEPTH; q++) { | 381 | for (q = 0; q < LT_BACKTRACEDEPTH; q++) { |
383 | char sym[KSYM_SYMBOL_LEN]; | 382 | unsigned long bt = lr->backtrace[q]; |
384 | char *c; | 383 | if (!bt) |
385 | if (!task->latency_record[i].backtrace[q]) | ||
386 | break; | 384 | break; |
387 | if (task->latency_record[i].backtrace[q] == ULONG_MAX) | 385 | if (bt == ULONG_MAX) |
388 | break; | 386 | break; |
389 | sprint_symbol(sym, task->latency_record[i].backtrace[q]); | 387 | seq_printf(m, " %ps", (void *)bt); |
390 | c = strchr(sym, '+'); | ||
391 | if (c) | ||
392 | *c = 0; | ||
393 | seq_printf(m, "%s ", sym); | ||
394 | } | 388 | } |
395 | seq_printf(m, "\n"); | 389 | seq_putc(m, '\n'); |
396 | } | 390 | } |
397 | 391 | ||
398 | } | 392 | } |
@@ -751,14 +745,7 @@ static int proc_single_show(struct seq_file *m, void *v) | |||
751 | 745 | ||
752 | static int proc_single_open(struct inode *inode, struct file *filp) | 746 | static int proc_single_open(struct inode *inode, struct file *filp) |
753 | { | 747 | { |
754 | int ret; | 748 | return single_open(filp, proc_single_show, inode); |
755 | ret = single_open(filp, proc_single_show, NULL); | ||
756 | if (!ret) { | ||
757 | struct seq_file *m = filp->private_data; | ||
758 | |||
759 | m->private = inode; | ||
760 | } | ||
761 | return ret; | ||
762 | } | 749 | } |
763 | 750 | ||
764 | static const struct file_operations proc_single_file_operations = { | 751 | static const struct file_operations proc_single_file_operations = { |
@@ -1164,7 +1151,7 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1164 | goto err_task_lock; | 1151 | goto err_task_lock; |
1165 | } | 1152 | } |
1166 | 1153 | ||
1167 | if (oom_score_adj < task->signal->oom_score_adj && | 1154 | if (oom_score_adj < task->signal->oom_score_adj_min && |
1168 | !capable(CAP_SYS_RESOURCE)) { | 1155 | !capable(CAP_SYS_RESOURCE)) { |
1169 | err = -EACCES; | 1156 | err = -EACCES; |
1170 | goto err_sighand; | 1157 | goto err_sighand; |
@@ -1177,6 +1164,8 @@ static ssize_t oom_score_adj_write(struct file *file, const char __user *buf, | |||
1177 | atomic_dec(&task->mm->oom_disable_count); | 1164 | atomic_dec(&task->mm->oom_disable_count); |
1178 | } | 1165 | } |
1179 | task->signal->oom_score_adj = oom_score_adj; | 1166 | task->signal->oom_score_adj = oom_score_adj; |
1167 | if (has_capability_noaudit(current, CAP_SYS_RESOURCE)) | ||
1168 | task->signal->oom_score_adj_min = oom_score_adj; | ||
1180 | /* | 1169 | /* |
1181 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is | 1170 | * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is |
1182 | * always attainable. | 1171 | * always attainable. |
@@ -1386,9 +1375,77 @@ sched_write(struct file *file, const char __user *buf, | |||
1386 | 1375 | ||
1387 | static int sched_open(struct inode *inode, struct file *filp) | 1376 | static int sched_open(struct inode *inode, struct file *filp) |
1388 | { | 1377 | { |
1378 | return single_open(filp, sched_show, inode); | ||
1379 | } | ||
1380 | |||
1381 | static const struct file_operations proc_pid_sched_operations = { | ||
1382 | .open = sched_open, | ||
1383 | .read = seq_read, | ||
1384 | .write = sched_write, | ||
1385 | .llseek = seq_lseek, | ||
1386 | .release = single_release, | ||
1387 | }; | ||
1388 | |||
1389 | #endif | ||
1390 | |||
1391 | #ifdef CONFIG_SCHED_AUTOGROUP | ||
1392 | /* | ||
1393 | * Print out autogroup related information: | ||
1394 | */ | ||
1395 | static int sched_autogroup_show(struct seq_file *m, void *v) | ||
1396 | { | ||
1397 | struct inode *inode = m->private; | ||
1398 | struct task_struct *p; | ||
1399 | |||
1400 | p = get_proc_task(inode); | ||
1401 | if (!p) | ||
1402 | return -ESRCH; | ||
1403 | proc_sched_autogroup_show_task(p, m); | ||
1404 | |||
1405 | put_task_struct(p); | ||
1406 | |||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | static ssize_t | ||
1411 | sched_autogroup_write(struct file *file, const char __user *buf, | ||
1412 | size_t count, loff_t *offset) | ||
1413 | { | ||
1414 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1415 | struct task_struct *p; | ||
1416 | char buffer[PROC_NUMBUF]; | ||
1417 | long nice; | ||
1418 | int err; | ||
1419 | |||
1420 | memset(buffer, 0, sizeof(buffer)); | ||
1421 | if (count > sizeof(buffer) - 1) | ||
1422 | count = sizeof(buffer) - 1; | ||
1423 | if (copy_from_user(buffer, buf, count)) | ||
1424 | return -EFAULT; | ||
1425 | |||
1426 | err = strict_strtol(strstrip(buffer), 0, &nice); | ||
1427 | if (err) | ||
1428 | return -EINVAL; | ||
1429 | |||
1430 | p = get_proc_task(inode); | ||
1431 | if (!p) | ||
1432 | return -ESRCH; | ||
1433 | |||
1434 | err = nice; | ||
1435 | err = proc_sched_autogroup_set_nice(p, &err); | ||
1436 | if (err) | ||
1437 | count = err; | ||
1438 | |||
1439 | put_task_struct(p); | ||
1440 | |||
1441 | return count; | ||
1442 | } | ||
1443 | |||
1444 | static int sched_autogroup_open(struct inode *inode, struct file *filp) | ||
1445 | { | ||
1389 | int ret; | 1446 | int ret; |
1390 | 1447 | ||
1391 | ret = single_open(filp, sched_show, NULL); | 1448 | ret = single_open(filp, sched_autogroup_show, NULL); |
1392 | if (!ret) { | 1449 | if (!ret) { |
1393 | struct seq_file *m = filp->private_data; | 1450 | struct seq_file *m = filp->private_data; |
1394 | 1451 | ||
@@ -1397,15 +1454,15 @@ static int sched_open(struct inode *inode, struct file *filp) | |||
1397 | return ret; | 1454 | return ret; |
1398 | } | 1455 | } |
1399 | 1456 | ||
1400 | static const struct file_operations proc_pid_sched_operations = { | 1457 | static const struct file_operations proc_pid_sched_autogroup_operations = { |
1401 | .open = sched_open, | 1458 | .open = sched_autogroup_open, |
1402 | .read = seq_read, | 1459 | .read = seq_read, |
1403 | .write = sched_write, | 1460 | .write = sched_autogroup_write, |
1404 | .llseek = seq_lseek, | 1461 | .llseek = seq_lseek, |
1405 | .release = single_release, | 1462 | .release = single_release, |
1406 | }; | 1463 | }; |
1407 | 1464 | ||
1408 | #endif | 1465 | #endif /* CONFIG_SCHED_AUTOGROUP */ |
1409 | 1466 | ||
1410 | static ssize_t comm_write(struct file *file, const char __user *buf, | 1467 | static ssize_t comm_write(struct file *file, const char __user *buf, |
1411 | size_t count, loff_t *offset) | 1468 | size_t count, loff_t *offset) |
@@ -1454,15 +1511,7 @@ static int comm_show(struct seq_file *m, void *v) | |||
1454 | 1511 | ||
1455 | static int comm_open(struct inode *inode, struct file *filp) | 1512 | static int comm_open(struct inode *inode, struct file *filp) |
1456 | { | 1513 | { |
1457 | int ret; | 1514 | return single_open(filp, comm_show, inode); |
1458 | |||
1459 | ret = single_open(filp, comm_show, NULL); | ||
1460 | if (!ret) { | ||
1461 | struct seq_file *m = filp->private_data; | ||
1462 | |||
1463 | m->private = inode; | ||
1464 | } | ||
1465 | return ret; | ||
1466 | } | 1515 | } |
1467 | 1516 | ||
1468 | static const struct file_operations proc_pid_set_comm_operations = { | 1517 | static const struct file_operations proc_pid_set_comm_operations = { |
@@ -1574,7 +1623,7 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) | |||
1574 | if (!tmp) | 1623 | if (!tmp) |
1575 | return -ENOMEM; | 1624 | return -ENOMEM; |
1576 | 1625 | ||
1577 | pathname = d_path_with_unreachable(path, tmp, PAGE_SIZE); | 1626 | pathname = d_path(path, tmp, PAGE_SIZE); |
1578 | len = PTR_ERR(pathname); | 1627 | len = PTR_ERR(pathname); |
1579 | if (IS_ERR(pathname)) | 1628 | if (IS_ERR(pathname)) |
1580 | goto out; | 1629 | goto out; |
@@ -1719,10 +1768,16 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat | |||
1719 | */ | 1768 | */ |
1720 | static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) | 1769 | static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) |
1721 | { | 1770 | { |
1722 | struct inode *inode = dentry->d_inode; | 1771 | struct inode *inode; |
1723 | struct task_struct *task = get_proc_task(inode); | 1772 | struct task_struct *task; |
1724 | const struct cred *cred; | 1773 | const struct cred *cred; |
1725 | 1774 | ||
1775 | if (nd && nd->flags & LOOKUP_RCU) | ||
1776 | return -ECHILD; | ||
1777 | |||
1778 | inode = dentry->d_inode; | ||
1779 | task = get_proc_task(inode); | ||
1780 | |||
1726 | if (task) { | 1781 | if (task) { |
1727 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || | 1782 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
1728 | task_dumpable(task)) { | 1783 | task_dumpable(task)) { |
@@ -1744,7 +1799,7 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1744 | return 0; | 1799 | return 0; |
1745 | } | 1800 | } |
1746 | 1801 | ||
1747 | static int pid_delete_dentry(struct dentry * dentry) | 1802 | static int pid_delete_dentry(const struct dentry * dentry) |
1748 | { | 1803 | { |
1749 | /* Is the task we represent dead? | 1804 | /* Is the task we represent dead? |
1750 | * If so, then don't put the dentry on the lru list, | 1805 | * If so, then don't put the dentry on the lru list, |
@@ -1888,12 +1943,19 @@ static int proc_fd_link(struct inode *inode, struct path *path) | |||
1888 | 1943 | ||
1889 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | 1944 | static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) |
1890 | { | 1945 | { |
1891 | struct inode *inode = dentry->d_inode; | 1946 | struct inode *inode; |
1892 | struct task_struct *task = get_proc_task(inode); | 1947 | struct task_struct *task; |
1893 | int fd = proc_fd(inode); | 1948 | int fd; |
1894 | struct files_struct *files; | 1949 | struct files_struct *files; |
1895 | const struct cred *cred; | 1950 | const struct cred *cred; |
1896 | 1951 | ||
1952 | if (nd && nd->flags & LOOKUP_RCU) | ||
1953 | return -ECHILD; | ||
1954 | |||
1955 | inode = dentry->d_inode; | ||
1956 | task = get_proc_task(inode); | ||
1957 | fd = proc_fd(inode); | ||
1958 | |||
1897 | if (task) { | 1959 | if (task) { |
1898 | files = get_files_struct(task); | 1960 | files = get_files_struct(task); |
1899 | if (files) { | 1961 | if (files) { |
@@ -1969,7 +2031,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, | |||
1969 | inode->i_op = &proc_pid_link_inode_operations; | 2031 | inode->i_op = &proc_pid_link_inode_operations; |
1970 | inode->i_size = 64; | 2032 | inode->i_size = 64; |
1971 | ei->op.proc_get_link = proc_fd_link; | 2033 | ei->op.proc_get_link = proc_fd_link; |
1972 | dentry->d_op = &tid_fd_dentry_operations; | 2034 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
1973 | d_add(dentry, inode); | 2035 | d_add(dentry, inode); |
1974 | /* Close the race of the process dying before we return the dentry */ | 2036 | /* Close the race of the process dying before we return the dentry */ |
1975 | if (tid_fd_revalidate(dentry, NULL)) | 2037 | if (tid_fd_revalidate(dentry, NULL)) |
@@ -2101,11 +2163,13 @@ static const struct file_operations proc_fd_operations = { | |||
2101 | * /proc/pid/fd needs a special permission handler so that a process can still | 2163 | * /proc/pid/fd needs a special permission handler so that a process can still |
2102 | * access /proc/self/fd after it has executed a setuid(). | 2164 | * access /proc/self/fd after it has executed a setuid(). |
2103 | */ | 2165 | */ |
2104 | static int proc_fd_permission(struct inode *inode, int mask) | 2166 | static int proc_fd_permission(struct inode *inode, int mask, unsigned int flags) |
2105 | { | 2167 | { |
2106 | int rv; | 2168 | int rv; |
2107 | 2169 | ||
2108 | rv = generic_permission(inode, mask, NULL); | 2170 | if (flags & IPERM_FLAG_RCU) |
2171 | return -ECHILD; | ||
2172 | rv = generic_permission(inode, mask, flags, NULL); | ||
2109 | if (rv == 0) | 2173 | if (rv == 0) |
2110 | return 0; | 2174 | return 0; |
2111 | if (task_pid(current) == proc_pid(inode)) | 2175 | if (task_pid(current) == proc_pid(inode)) |
@@ -2137,7 +2201,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | |||
2137 | ei->fd = fd; | 2201 | ei->fd = fd; |
2138 | inode->i_mode = S_IFREG | S_IRUSR; | 2202 | inode->i_mode = S_IFREG | S_IRUSR; |
2139 | inode->i_fop = &proc_fdinfo_file_operations; | 2203 | inode->i_fop = &proc_fdinfo_file_operations; |
2140 | dentry->d_op = &tid_fd_dentry_operations; | 2204 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
2141 | d_add(dentry, inode); | 2205 | d_add(dentry, inode); |
2142 | /* Close the race of the process dying before we return the dentry */ | 2206 | /* Close the race of the process dying before we return the dentry */ |
2143 | if (tid_fd_revalidate(dentry, NULL)) | 2207 | if (tid_fd_revalidate(dentry, NULL)) |
@@ -2196,7 +2260,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir, | |||
2196 | if (p->fop) | 2260 | if (p->fop) |
2197 | inode->i_fop = p->fop; | 2261 | inode->i_fop = p->fop; |
2198 | ei->op = p->op; | 2262 | ei->op = p->op; |
2199 | dentry->d_op = &pid_dentry_operations; | 2263 | d_set_d_op(dentry, &pid_dentry_operations); |
2200 | d_add(dentry, inode); | 2264 | d_add(dentry, inode); |
2201 | /* Close the race of the process dying before we return the dentry */ | 2265 | /* Close the race of the process dying before we return the dentry */ |
2202 | if (pid_revalidate(dentry, NULL)) | 2266 | if (pid_revalidate(dentry, NULL)) |
@@ -2563,8 +2627,14 @@ static const struct pid_entry proc_base_stuff[] = { | |||
2563 | */ | 2627 | */ |
2564 | static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) | 2628 | static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) |
2565 | { | 2629 | { |
2566 | struct inode *inode = dentry->d_inode; | 2630 | struct inode *inode; |
2567 | struct task_struct *task = get_proc_task(inode); | 2631 | struct task_struct *task; |
2632 | |||
2633 | if (nd->flags & LOOKUP_RCU) | ||
2634 | return -ECHILD; | ||
2635 | |||
2636 | inode = dentry->d_inode; | ||
2637 | task = get_proc_task(inode); | ||
2568 | if (task) { | 2638 | if (task) { |
2569 | put_task_struct(task); | 2639 | put_task_struct(task); |
2570 | return 1; | 2640 | return 1; |
@@ -2615,7 +2685,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir, | |||
2615 | if (p->fop) | 2685 | if (p->fop) |
2616 | inode->i_fop = p->fop; | 2686 | inode->i_fop = p->fop; |
2617 | ei->op = p->op; | 2687 | ei->op = p->op; |
2618 | dentry->d_op = &proc_base_dentry_operations; | 2688 | d_set_d_op(dentry, &proc_base_dentry_operations); |
2619 | d_add(dentry, inode); | 2689 | d_add(dentry, inode); |
2620 | error = NULL; | 2690 | error = NULL; |
2621 | out: | 2691 | out: |
@@ -2733,6 +2803,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2733 | #ifdef CONFIG_SCHED_DEBUG | 2803 | #ifdef CONFIG_SCHED_DEBUG |
2734 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2804 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2735 | #endif | 2805 | #endif |
2806 | #ifdef CONFIG_SCHED_AUTOGROUP | ||
2807 | REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations), | ||
2808 | #endif | ||
2736 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), | 2809 | REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), |
2737 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2810 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2738 | INF("syscall", S_IRUSR, proc_pid_syscall), | 2811 | INF("syscall", S_IRUSR, proc_pid_syscall), |
@@ -2926,7 +2999,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, | |||
2926 | inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff, | 2999 | inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff, |
2927 | ARRAY_SIZE(tgid_base_stuff)); | 3000 | ARRAY_SIZE(tgid_base_stuff)); |
2928 | 3001 | ||
2929 | dentry->d_op = &pid_dentry_operations; | 3002 | d_set_d_op(dentry, &pid_dentry_operations); |
2930 | 3003 | ||
2931 | d_add(dentry, inode); | 3004 | d_add(dentry, inode); |
2932 | /* Close the race of the process dying before we return the dentry */ | 3005 | /* Close the race of the process dying before we return the dentry */ |
@@ -3169,7 +3242,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir, | |||
3169 | inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff, | 3242 | inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff, |
3170 | ARRAY_SIZE(tid_base_stuff)); | 3243 | ARRAY_SIZE(tid_base_stuff)); |
3171 | 3244 | ||
3172 | dentry->d_op = &pid_dentry_operations; | 3245 | d_set_d_op(dentry, &pid_dentry_operations); |
3173 | 3246 | ||
3174 | d_add(dentry, inode); | 3247 | d_add(dentry, inode); |
3175 | /* Close the race of the process dying before we return the dentry */ | 3248 | /* Close the race of the process dying before we return the dentry */ |
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c new file mode 100644 index 000000000000..b701eaa482bf --- /dev/null +++ b/fs/proc/consoles.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Werner Fink, Jiri Slaby | ||
3 | * | ||
4 | * Licensed under GPLv2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/console.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/proc_fs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | #include <linux/tty_driver.h> | ||
12 | |||
13 | /* | ||
14 | * This is handler for /proc/consoles | ||
15 | */ | ||
16 | static int show_console_dev(struct seq_file *m, void *v) | ||
17 | { | ||
18 | static const struct { | ||
19 | short flag; | ||
20 | char name; | ||
21 | } con_flags[] = { | ||
22 | { CON_ENABLED, 'E' }, | ||
23 | { CON_CONSDEV, 'C' }, | ||
24 | { CON_BOOT, 'B' }, | ||
25 | { CON_PRINTBUFFER, 'p' }, | ||
26 | { CON_BRL, 'b' }, | ||
27 | { CON_ANYTIME, 'a' }, | ||
28 | }; | ||
29 | char flags[ARRAY_SIZE(con_flags) + 1]; | ||
30 | struct console *con = v; | ||
31 | unsigned int a; | ||
32 | int len; | ||
33 | dev_t dev = 0; | ||
34 | |||
35 | if (con->device) { | ||
36 | const struct tty_driver *driver; | ||
37 | int index; | ||
38 | driver = con->device(con, &index); | ||
39 | if (driver) { | ||
40 | dev = MKDEV(driver->major, driver->minor_start); | ||
41 | dev += index; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | for (a = 0; a < ARRAY_SIZE(con_flags); a++) | ||
46 | flags[a] = (con->flags & con_flags[a].flag) ? | ||
47 | con_flags[a].name : ' '; | ||
48 | flags[a] = 0; | ||
49 | |||
50 | seq_printf(m, "%s%d%n", con->name, con->index, &len); | ||
51 | len = 21 - len; | ||
52 | if (len < 1) | ||
53 | len = 1; | ||
54 | seq_printf(m, "%*c%c%c%c (%s)", len, ' ', con->read ? 'R' : '-', | ||
55 | con->write ? 'W' : '-', con->unblank ? 'U' : '-', | ||
56 | flags); | ||
57 | if (dev) | ||
58 | seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); | ||
59 | |||
60 | seq_printf(m, "\n"); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
66 | { | ||
67 | struct console *con; | ||
68 | loff_t off = 0; | ||
69 | |||
70 | console_lock(); | ||
71 | for_each_console(con) | ||
72 | if (off++ == *pos) | ||
73 | break; | ||
74 | |||
75 | return con; | ||
76 | } | ||
77 | |||
78 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
79 | { | ||
80 | struct console *con = v; | ||
81 | ++*pos; | ||
82 | return con->next; | ||
83 | } | ||
84 | |||
85 | static void c_stop(struct seq_file *m, void *v) | ||
86 | { | ||
87 | console_unlock(); | ||
88 | } | ||
89 | |||
90 | static const struct seq_operations consoles_op = { | ||
91 | .start = c_start, | ||
92 | .next = c_next, | ||
93 | .stop = c_stop, | ||
94 | .show = show_console_dev | ||
95 | }; | ||
96 | |||
97 | static int consoles_open(struct inode *inode, struct file *file) | ||
98 | { | ||
99 | return seq_open(file, &consoles_op); | ||
100 | } | ||
101 | |||
102 | static const struct file_operations proc_consoles_operations = { | ||
103 | .open = consoles_open, | ||
104 | .read = seq_read, | ||
105 | .llseek = seq_lseek, | ||
106 | .release = seq_release, | ||
107 | }; | ||
108 | |||
109 | static int __init proc_consoles_init(void) | ||
110 | { | ||
111 | proc_create("consoles", 0, NULL, &proc_consoles_operations); | ||
112 | return 0; | ||
113 | } | ||
114 | module_init(proc_consoles_init); | ||
diff --git a/fs/proc/devices.c b/fs/proc/devices.c index 59ee7da959c9..b14347167c35 100644 --- a/fs/proc/devices.c +++ b/fs/proc/devices.c | |||
@@ -9,14 +9,14 @@ static int devinfo_show(struct seq_file *f, void *v) | |||
9 | 9 | ||
10 | if (i < CHRDEV_MAJOR_HASH_SIZE) { | 10 | if (i < CHRDEV_MAJOR_HASH_SIZE) { |
11 | if (i == 0) | 11 | if (i == 0) |
12 | seq_printf(f, "Character devices:\n"); | 12 | seq_puts(f, "Character devices:\n"); |
13 | chrdev_show(f, i); | 13 | chrdev_show(f, i); |
14 | } | 14 | } |
15 | #ifdef CONFIG_BLOCK | 15 | #ifdef CONFIG_BLOCK |
16 | else { | 16 | else { |
17 | i -= CHRDEV_MAJOR_HASH_SIZE; | 17 | i -= CHRDEV_MAJOR_HASH_SIZE; |
18 | if (i == 0) | 18 | if (i == 0) |
19 | seq_printf(f, "\nBlock devices:\n"); | 19 | seq_puts(f, "\nBlock devices:\n"); |
20 | blkdev_show(f, i); | 20 | blkdev_show(f, i); |
21 | } | 21 | } |
22 | #endif | 22 | #endif |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index dd29f0337661..01e07f2a188f 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -400,7 +400,7 @@ static const struct inode_operations proc_link_inode_operations = { | |||
400 | * smarter: we could keep a "volatile" flag in the | 400 | * smarter: we could keep a "volatile" flag in the |
401 | * inode to indicate which ones to keep. | 401 | * inode to indicate which ones to keep. |
402 | */ | 402 | */ |
403 | static int proc_delete_dentry(struct dentry * dentry) | 403 | static int proc_delete_dentry(const struct dentry * dentry) |
404 | { | 404 | { |
405 | return 1; | 405 | return 1; |
406 | } | 406 | } |
@@ -425,13 +425,10 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
425 | if (de->namelen != dentry->d_name.len) | 425 | if (de->namelen != dentry->d_name.len) |
426 | continue; | 426 | continue; |
427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
428 | unsigned int ino; | ||
429 | |||
430 | ino = de->low_ino; | ||
431 | pde_get(de); | 428 | pde_get(de); |
432 | spin_unlock(&proc_subdir_lock); | 429 | spin_unlock(&proc_subdir_lock); |
433 | error = -EINVAL; | 430 | error = -EINVAL; |
434 | inode = proc_get_inode(dir->i_sb, ino, de); | 431 | inode = proc_get_inode(dir->i_sb, de); |
435 | goto out_unlock; | 432 | goto out_unlock; |
436 | } | 433 | } |
437 | } | 434 | } |
@@ -439,7 +436,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
439 | out_unlock: | 436 | out_unlock: |
440 | 437 | ||
441 | if (inode) { | 438 | if (inode) { |
442 | dentry->d_op = &proc_dentry_operations; | 439 | d_set_d_op(dentry, &proc_dentry_operations); |
443 | d_add(dentry, inode); | 440 | d_add(dentry, inode); |
444 | return NULL; | 441 | return NULL; |
445 | } | 442 | } |
@@ -768,12 +765,7 @@ EXPORT_SYMBOL(proc_create_data); | |||
768 | 765 | ||
769 | static void free_proc_entry(struct proc_dir_entry *de) | 766 | static void free_proc_entry(struct proc_dir_entry *de) |
770 | { | 767 | { |
771 | unsigned int ino = de->low_ino; | 768 | release_inode_number(de->low_ino); |
772 | |||
773 | if (ino < PROC_DYNAMIC_FIRST) | ||
774 | return; | ||
775 | |||
776 | release_inode_number(ino); | ||
777 | 769 | ||
778 | if (S_ISLNK(de->mode)) | 770 | if (S_ISLNK(de->mode)) |
779 | kfree(de->data); | 771 | kfree(de->data); |
@@ -834,12 +826,9 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | |||
834 | 826 | ||
835 | wait_for_completion(de->pde_unload_completion); | 827 | wait_for_completion(de->pde_unload_completion); |
836 | 828 | ||
837 | goto continue_removing; | 829 | spin_lock(&de->pde_unload_lock); |
838 | } | 830 | } |
839 | spin_unlock(&de->pde_unload_lock); | ||
840 | 831 | ||
841 | continue_removing: | ||
842 | spin_lock(&de->pde_unload_lock); | ||
843 | while (!list_empty(&de->pde_openers)) { | 832 | while (!list_empty(&de->pde_openers)) { |
844 | struct pde_opener *pdeo; | 833 | struct pde_opener *pdeo; |
845 | 834 | ||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 3ddb6068177c..176ce4cda68a 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -65,11 +65,18 @@ static struct inode *proc_alloc_inode(struct super_block *sb) | |||
65 | return inode; | 65 | return inode; |
66 | } | 66 | } |
67 | 67 | ||
68 | static void proc_destroy_inode(struct inode *inode) | 68 | static void proc_i_callback(struct rcu_head *head) |
69 | { | 69 | { |
70 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
71 | INIT_LIST_HEAD(&inode->i_dentry); | ||
70 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); | 72 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); |
71 | } | 73 | } |
72 | 74 | ||
75 | static void proc_destroy_inode(struct inode *inode) | ||
76 | { | ||
77 | call_rcu(&inode->i_rcu, proc_i_callback); | ||
78 | } | ||
79 | |||
73 | static void init_once(void *foo) | 80 | static void init_once(void *foo) |
74 | { | 81 | { |
75 | struct proc_inode *ei = (struct proc_inode *) foo; | 82 | struct proc_inode *ei = (struct proc_inode *) foo; |
@@ -409,12 +416,11 @@ static const struct file_operations proc_reg_file_ops_no_compat = { | |||
409 | }; | 416 | }; |
410 | #endif | 417 | #endif |
411 | 418 | ||
412 | struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | 419 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) |
413 | struct proc_dir_entry *de) | ||
414 | { | 420 | { |
415 | struct inode * inode; | 421 | struct inode * inode; |
416 | 422 | ||
417 | inode = iget_locked(sb, ino); | 423 | inode = iget_locked(sb, de->low_ino); |
418 | if (!inode) | 424 | if (!inode) |
419 | return NULL; | 425 | return NULL; |
420 | if (inode->i_state & I_NEW) { | 426 | if (inode->i_state & I_NEW) { |
@@ -464,7 +470,7 @@ int proc_fill_super(struct super_block *s) | |||
464 | s->s_time_gran = 1; | 470 | s->s_time_gran = 1; |
465 | 471 | ||
466 | pde_get(&proc_root); | 472 | pde_get(&proc_root); |
467 | root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root); | 473 | root_inode = proc_get_inode(s, &proc_root); |
468 | if (!root_inode) | 474 | if (!root_inode) |
469 | goto out_no_root; | 475 | goto out_no_root; |
470 | root_inode->i_uid = 0; | 476 | root_inode->i_uid = 0; |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1f24a3eddd12..9ad561ded409 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -96,7 +96,8 @@ extern spinlock_t proc_subdir_lock; | |||
96 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); | 96 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); |
97 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); | 97 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); |
98 | unsigned long task_vsize(struct mm_struct *); | 98 | unsigned long task_vsize(struct mm_struct *); |
99 | int task_statm(struct mm_struct *, int *, int *, int *, int *); | 99 | unsigned long task_statm(struct mm_struct *, |
100 | unsigned long *, unsigned long *, unsigned long *, unsigned long *); | ||
100 | void task_mem(struct seq_file *, struct mm_struct *); | 101 | void task_mem(struct seq_file *, struct mm_struct *); |
101 | 102 | ||
102 | static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) | 103 | static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) |
@@ -108,7 +109,7 @@ void pde_put(struct proc_dir_entry *pde); | |||
108 | 109 | ||
109 | extern struct vfsmount *proc_mnt; | 110 | extern struct vfsmount *proc_mnt; |
110 | int proc_fill_super(struct super_block *); | 111 | int proc_fill_super(struct super_block *); |
111 | struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *); | 112 | struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); |
112 | 113 | ||
113 | /* | 114 | /* |
114 | * These are generic /proc routines that use the internal | 115 | * These are generic /proc routines that use the internal |
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 6f37c391468d..d245cb23dd72 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -558,7 +558,7 @@ static int open_kcore(struct inode *inode, struct file *filp) | |||
558 | static const struct file_operations proc_kcore_operations = { | 558 | static const struct file_operations proc_kcore_operations = { |
559 | .read = read_kcore, | 559 | .read = read_kcore, |
560 | .open = open_kcore, | 560 | .open = open_kcore, |
561 | .llseek = generic_file_llseek, | 561 | .llseek = default_llseek, |
562 | }; | 562 | }; |
563 | 563 | ||
564 | #ifdef CONFIG_MEMORY_HOTPLUG | 564 | #ifdef CONFIG_MEMORY_HOTPLUG |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index a65239cfd97e..ed257d141568 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -101,6 +101,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
101 | #ifdef CONFIG_MEMORY_FAILURE | 101 | #ifdef CONFIG_MEMORY_FAILURE |
102 | "HardwareCorrupted: %5lu kB\n" | 102 | "HardwareCorrupted: %5lu kB\n" |
103 | #endif | 103 | #endif |
104 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
105 | "AnonHugePages: %8lu kB\n" | ||
106 | #endif | ||
104 | , | 107 | , |
105 | K(i.totalram), | 108 | K(i.totalram), |
106 | K(i.freeram), | 109 | K(i.freeram), |
@@ -128,7 +131,12 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
128 | K(i.freeswap), | 131 | K(i.freeswap), |
129 | K(global_page_state(NR_FILE_DIRTY)), | 132 | K(global_page_state(NR_FILE_DIRTY)), |
130 | K(global_page_state(NR_WRITEBACK)), | 133 | K(global_page_state(NR_WRITEBACK)), |
131 | K(global_page_state(NR_ANON_PAGES)), | 134 | K(global_page_state(NR_ANON_PAGES) |
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
137 | HPAGE_PMD_NR | ||
138 | #endif | ||
139 | ), | ||
132 | K(global_page_state(NR_FILE_MAPPED)), | 140 | K(global_page_state(NR_FILE_MAPPED)), |
133 | K(global_page_state(NR_SHMEM)), | 141 | K(global_page_state(NR_SHMEM)), |
134 | K(global_page_state(NR_SLAB_RECLAIMABLE) + | 142 | K(global_page_state(NR_SLAB_RECLAIMABLE) + |
@@ -151,6 +159,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
151 | #ifdef CONFIG_MEMORY_FAILURE | 159 | #ifdef CONFIG_MEMORY_FAILURE |
152 | ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) | 160 | ,atomic_long_read(&mce_bad_pages) << (PAGE_SHIFT - 10) |
153 | #endif | 161 | #endif |
162 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
163 | ,K(global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | ||
164 | HPAGE_PMD_NR) | ||
165 | #endif | ||
154 | ); | 166 | ); |
155 | 167 | ||
156 | hugetlb_report_meminfo(m); | 168 | hugetlb_report_meminfo(m); |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 3b8b45660331..6d8e6a9e93ab 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -40,7 +40,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, | |||
40 | ppage = pfn_to_page(pfn); | 40 | ppage = pfn_to_page(pfn); |
41 | else | 41 | else |
42 | ppage = NULL; | 42 | ppage = NULL; |
43 | if (!ppage) | 43 | if (!ppage || PageSlab(ppage)) |
44 | pcount = 0; | 44 | pcount = 0; |
45 | else | 45 | else |
46 | pcount = page_mapcount(ppage); | 46 | pcount = page_mapcount(ppage); |
@@ -116,15 +116,17 @@ u64 stable_page_flags(struct page *page) | |||
116 | if (PageHuge(page)) | 116 | if (PageHuge(page)) |
117 | u |= 1 << KPF_HUGE; | 117 | u |= 1 << KPF_HUGE; |
118 | 118 | ||
119 | u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); | ||
120 | |||
121 | /* | 119 | /* |
122 | * Caveats on high order pages: | 120 | * Caveats on high order pages: page->_count will only be set |
123 | * PG_buddy will only be set on the head page; SLUB/SLQB do the same | 121 | * -1 on the head page; SLUB/SLQB do the same for PG_slab; |
124 | * for PG_slab; SLOB won't set PG_slab at all on compound pages. | 122 | * SLOB won't set PG_slab at all on compound pages. |
125 | */ | 123 | */ |
124 | if (PageBuddy(page)) | ||
125 | u |= 1 << KPF_BUDDY; | ||
126 | |||
127 | u |= kpf_copy_bit(k, KPF_LOCKED, PG_locked); | ||
128 | |||
126 | u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); | 129 | u |= kpf_copy_bit(k, KPF_SLAB, PG_slab); |
127 | u |= kpf_copy_bit(k, KPF_BUDDY, PG_buddy); | ||
128 | 130 | ||
129 | u |= kpf_copy_bit(k, KPF_ERROR, PG_error); | 131 | u |= kpf_copy_bit(k, KPF_ERROR, PG_error); |
130 | u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); | 132 | u |= kpf_copy_bit(k, KPF_DIRTY, PG_dirty); |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index b652cb00906b..09a1f92a34ef 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/sysctl.h> | 5 | #include <linux/sysctl.h> |
6 | #include <linux/proc_fs.h> | 6 | #include <linux/proc_fs.h> |
7 | #include <linux/security.h> | 7 | #include <linux/security.h> |
8 | #include <linux/namei.h> | ||
8 | #include "internal.h" | 9 | #include "internal.h" |
9 | 10 | ||
10 | static const struct dentry_operations proc_sys_dentry_operations; | 11 | static const struct dentry_operations proc_sys_dentry_operations; |
@@ -120,7 +121,7 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, | |||
120 | goto out; | 121 | goto out; |
121 | 122 | ||
122 | err = NULL; | 123 | err = NULL; |
123 | dentry->d_op = &proc_sys_dentry_operations; | 124 | d_set_d_op(dentry, &proc_sys_dentry_operations); |
124 | d_add(dentry, inode); | 125 | d_add(dentry, inode); |
125 | 126 | ||
126 | out: | 127 | out: |
@@ -201,7 +202,7 @@ static int proc_sys_fill_cache(struct file *filp, void *dirent, | |||
201 | dput(child); | 202 | dput(child); |
202 | return -ENOMEM; | 203 | return -ENOMEM; |
203 | } else { | 204 | } else { |
204 | child->d_op = &proc_sys_dentry_operations; | 205 | d_set_d_op(child, &proc_sys_dentry_operations); |
205 | d_add(child, inode); | 206 | d_add(child, inode); |
206 | } | 207 | } |
207 | } else { | 208 | } else { |
@@ -294,7 +295,7 @@ out: | |||
294 | return ret; | 295 | return ret; |
295 | } | 296 | } |
296 | 297 | ||
297 | static int proc_sys_permission(struct inode *inode, int mask) | 298 | static int proc_sys_permission(struct inode *inode, int mask,unsigned int flags) |
298 | { | 299 | { |
299 | /* | 300 | /* |
300 | * sysctl entries that are not writeable, | 301 | * sysctl entries that are not writeable, |
@@ -304,6 +305,9 @@ static int proc_sys_permission(struct inode *inode, int mask) | |||
304 | struct ctl_table *table; | 305 | struct ctl_table *table; |
305 | int error; | 306 | int error; |
306 | 307 | ||
308 | if (flags & IPERM_FLAG_RCU) | ||
309 | return -ECHILD; | ||
310 | |||
307 | /* Executable files are not allowed under /proc/sys/ */ | 311 | /* Executable files are not allowed under /proc/sys/ */ |
308 | if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) | 312 | if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) |
309 | return -EACCES; | 313 | return -EACCES; |
@@ -389,23 +393,30 @@ static const struct inode_operations proc_sys_dir_operations = { | |||
389 | 393 | ||
390 | static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) | 394 | static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) |
391 | { | 395 | { |
396 | if (nd->flags & LOOKUP_RCU) | ||
397 | return -ECHILD; | ||
392 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; | 398 | return !PROC_I(dentry->d_inode)->sysctl->unregistering; |
393 | } | 399 | } |
394 | 400 | ||
395 | static int proc_sys_delete(struct dentry *dentry) | 401 | static int proc_sys_delete(const struct dentry *dentry) |
396 | { | 402 | { |
397 | return !!PROC_I(dentry->d_inode)->sysctl->unregistering; | 403 | return !!PROC_I(dentry->d_inode)->sysctl->unregistering; |
398 | } | 404 | } |
399 | 405 | ||
400 | static int proc_sys_compare(struct dentry *dir, struct qstr *qstr, | 406 | static int proc_sys_compare(const struct dentry *parent, |
401 | struct qstr *name) | 407 | const struct inode *pinode, |
408 | const struct dentry *dentry, const struct inode *inode, | ||
409 | unsigned int len, const char *str, const struct qstr *name) | ||
402 | { | 410 | { |
403 | struct dentry *dentry = container_of(qstr, struct dentry, d_name); | 411 | /* Although proc doesn't have negative dentries, rcu-walk means |
404 | if (qstr->len != name->len) | 412 | * that inode here can be NULL */ |
413 | if (!inode) | ||
414 | return 0; | ||
415 | if (name->len != len) | ||
405 | return 1; | 416 | return 1; |
406 | if (memcmp(qstr->name, name->name, name->len)) | 417 | if (memcmp(name->name, str, len)) |
407 | return 1; | 418 | return 1; |
408 | return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl); | 419 | return !sysctl_is_seen(PROC_I(inode)->sysctl); |
409 | } | 420 | } |
410 | 421 | ||
411 | static const struct dentry_operations proc_sys_dentry_operations = { | 422 | static const struct dentry_operations proc_sys_dentry_operations = { |
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 83adcc869437..cb761f010300 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -36,27 +36,27 @@ static void show_tty_range(struct seq_file *m, struct tty_driver *p, | |||
36 | } | 36 | } |
37 | switch (p->type) { | 37 | switch (p->type) { |
38 | case TTY_DRIVER_TYPE_SYSTEM: | 38 | case TTY_DRIVER_TYPE_SYSTEM: |
39 | seq_printf(m, "system"); | 39 | seq_puts(m, "system"); |
40 | if (p->subtype == SYSTEM_TYPE_TTY) | 40 | if (p->subtype == SYSTEM_TYPE_TTY) |
41 | seq_printf(m, ":/dev/tty"); | 41 | seq_puts(m, ":/dev/tty"); |
42 | else if (p->subtype == SYSTEM_TYPE_SYSCONS) | 42 | else if (p->subtype == SYSTEM_TYPE_SYSCONS) |
43 | seq_printf(m, ":console"); | 43 | seq_puts(m, ":console"); |
44 | else if (p->subtype == SYSTEM_TYPE_CONSOLE) | 44 | else if (p->subtype == SYSTEM_TYPE_CONSOLE) |
45 | seq_printf(m, ":vtmaster"); | 45 | seq_puts(m, ":vtmaster"); |
46 | break; | 46 | break; |
47 | case TTY_DRIVER_TYPE_CONSOLE: | 47 | case TTY_DRIVER_TYPE_CONSOLE: |
48 | seq_printf(m, "console"); | 48 | seq_puts(m, "console"); |
49 | break; | 49 | break; |
50 | case TTY_DRIVER_TYPE_SERIAL: | 50 | case TTY_DRIVER_TYPE_SERIAL: |
51 | seq_printf(m, "serial"); | 51 | seq_puts(m, "serial"); |
52 | break; | 52 | break; |
53 | case TTY_DRIVER_TYPE_PTY: | 53 | case TTY_DRIVER_TYPE_PTY: |
54 | if (p->subtype == PTY_TYPE_MASTER) | 54 | if (p->subtype == PTY_TYPE_MASTER) |
55 | seq_printf(m, "pty:master"); | 55 | seq_puts(m, "pty:master"); |
56 | else if (p->subtype == PTY_TYPE_SLAVE) | 56 | else if (p->subtype == PTY_TYPE_SLAVE) |
57 | seq_printf(m, "pty:slave"); | 57 | seq_puts(m, "pty:slave"); |
58 | else | 58 | else |
59 | seq_printf(m, "pty"); | 59 | seq_puts(m, "pty"); |
60 | break; | 60 | break; |
61 | default: | 61 | default: |
62 | seq_printf(m, "type:%d.%d", p->type, p->subtype); | 62 | seq_printf(m, "type:%d.%d", p->type, p->subtype); |
@@ -74,19 +74,19 @@ static int show_tty_driver(struct seq_file *m, void *v) | |||
74 | /* pseudo-drivers first */ | 74 | /* pseudo-drivers first */ |
75 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty"); | 75 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/tty", "tty"); |
76 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0); | 76 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 0); |
77 | seq_printf(m, "system:/dev/tty\n"); | 77 | seq_puts(m, "system:/dev/tty\n"); |
78 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console"); | 78 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/console", "console"); |
79 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1); | 79 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 1); |
80 | seq_printf(m, "system:console\n"); | 80 | seq_puts(m, "system:console\n"); |
81 | #ifdef CONFIG_UNIX98_PTYS | 81 | #ifdef CONFIG_UNIX98_PTYS |
82 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx"); | 82 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/ptmx", "ptmx"); |
83 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2); | 83 | seq_printf(m, "%3d %7d ", TTYAUX_MAJOR, 2); |
84 | seq_printf(m, "system\n"); | 84 | seq_puts(m, "system\n"); |
85 | #endif | 85 | #endif |
86 | #ifdef CONFIG_VT | 86 | #ifdef CONFIG_VT |
87 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0"); | 87 | seq_printf(m, "%-20s /dev/%-8s ", "/dev/vc/0", "vc/0"); |
88 | seq_printf(m, "%3d %7d ", TTY_MAJOR, 0); | 88 | seq_printf(m, "%3d %7d ", TTY_MAJOR, 0); |
89 | seq_printf(m, "system:vtmaster\n"); | 89 | seq_puts(m, "system:vtmaster\n"); |
90 | #endif | 90 | #endif |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c index 37994737c983..62604be9f58d 100644 --- a/fs/proc/softirqs.c +++ b/fs/proc/softirqs.c | |||
@@ -10,16 +10,16 @@ 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_puts(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_putc(p, '\n'); |
17 | 17 | ||
18 | for (i = 0; i < NR_SOFTIRQS; i++) { | 18 | for (i = 0; i < NR_SOFTIRQS; i++) { |
19 | seq_printf(p, "%12s:", 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_putc(p, '\n'); |
23 | } | 23 | } |
24 | return 0; | 24 | return 0; |
25 | } | 25 | } |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index e15a19c93bae..1cffa2b8a2fc 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -126,7 +126,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
126 | 126 | ||
127 | for (i = 0; i < NR_SOFTIRQS; i++) | 127 | for (i = 0; i < NR_SOFTIRQS; i++) |
128 | seq_printf(p, " %u", per_softirq_sums[i]); | 128 | seq_printf(p, " %u", per_softirq_sums[i]); |
129 | seq_printf(p, "\n"); | 129 | seq_putc(p, '\n'); |
130 | 130 | ||
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index da6b01d70f01..60b914860f81 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -66,8 +66,9 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
66 | return PAGE_SIZE * mm->total_vm; | 66 | return PAGE_SIZE * mm->total_vm; |
67 | } | 67 | } |
68 | 68 | ||
69 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 69 | unsigned long task_statm(struct mm_struct *mm, |
70 | int *data, int *resident) | 70 | unsigned long *shared, unsigned long *text, |
71 | unsigned long *data, unsigned long *resident) | ||
71 | { | 72 | { |
72 | *shared = get_mm_counter(mm, MM_FILEPAGES); | 73 | *shared = get_mm_counter(mm, MM_FILEPAGES); |
73 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) | 74 | *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) |
@@ -417,7 +418,8 @@ static int show_smap(struct seq_file *m, void *v) | |||
417 | "Anonymous: %8lu kB\n" | 418 | "Anonymous: %8lu kB\n" |
418 | "Swap: %8lu kB\n" | 419 | "Swap: %8lu kB\n" |
419 | "KernelPageSize: %8lu kB\n" | 420 | "KernelPageSize: %8lu kB\n" |
420 | "MMUPageSize: %8lu kB\n", | 421 | "MMUPageSize: %8lu kB\n" |
422 | "Locked: %8lu kB\n", | ||
421 | (vma->vm_end - vma->vm_start) >> 10, | 423 | (vma->vm_end - vma->vm_start) >> 10, |
422 | mss.resident >> 10, | 424 | mss.resident >> 10, |
423 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), | 425 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), |
@@ -429,7 +431,9 @@ static int show_smap(struct seq_file *m, void *v) | |||
429 | mss.anonymous >> 10, | 431 | mss.anonymous >> 10, |
430 | mss.swap >> 10, | 432 | mss.swap >> 10, |
431 | vma_kernel_pagesize(vma) >> 10, | 433 | vma_kernel_pagesize(vma) >> 10, |
432 | vma_mmu_pagesize(vma) >> 10); | 434 | vma_mmu_pagesize(vma) >> 10, |
435 | (vma->vm_flags & VM_LOCKED) ? | ||
436 | (unsigned long)(mss.pss >> (10 + PSS_SHIFT)) : 0); | ||
433 | 437 | ||
434 | if (m->count < m->size) /* vma is copied successfully */ | 438 | if (m->count < m->size) /* vma is copied successfully */ |
435 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; | 439 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; |
@@ -706,6 +710,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask, | |||
706 | * skip over unmapped regions. | 710 | * skip over unmapped regions. |
707 | */ | 711 | */ |
708 | #define PAGEMAP_WALK_SIZE (PMD_SIZE) | 712 | #define PAGEMAP_WALK_SIZE (PMD_SIZE) |
713 | #define PAGEMAP_WALK_MASK (PMD_MASK) | ||
709 | static ssize_t pagemap_read(struct file *file, char __user *buf, | 714 | static ssize_t pagemap_read(struct file *file, char __user *buf, |
710 | size_t count, loff_t *ppos) | 715 | size_t count, loff_t *ppos) |
711 | { | 716 | { |
@@ -776,7 +781,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
776 | unsigned long end; | 781 | unsigned long end; |
777 | 782 | ||
778 | pm.pos = 0; | 783 | pm.pos = 0; |
779 | end = start_vaddr + PAGEMAP_WALK_SIZE; | 784 | end = (start_vaddr + PAGEMAP_WALK_SIZE) & PAGEMAP_WALK_MASK; |
780 | /* overflow ? */ | 785 | /* overflow ? */ |
781 | if (end < start_vaddr || end > end_vaddr) | 786 | if (end < start_vaddr || end > end_vaddr) |
782 | end = end_vaddr; | 787 | end = end_vaddr; |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index cb6306e63843..b535d3e5d5f1 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -92,13 +92,14 @@ unsigned long task_vsize(struct mm_struct *mm) | |||
92 | return vsize; | 92 | return vsize; |
93 | } | 93 | } |
94 | 94 | ||
95 | int task_statm(struct mm_struct *mm, int *shared, int *text, | 95 | unsigned long task_statm(struct mm_struct *mm, |
96 | int *data, int *resident) | 96 | unsigned long *shared, unsigned long *text, |
97 | unsigned long *data, unsigned long *resident) | ||
97 | { | 98 | { |
98 | struct vm_area_struct *vma; | 99 | struct vm_area_struct *vma; |
99 | struct vm_region *region; | 100 | struct vm_region *region; |
100 | struct rb_node *p; | 101 | struct rb_node *p; |
101 | int size = kobjsize(mm); | 102 | unsigned long size = kobjsize(mm); |
102 | 103 | ||
103 | down_read(&mm->mmap_sem); | 104 | down_read(&mm->mmap_sem); |
104 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { | 105 | for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) { |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 2367fb3f70bc..74802bc5ded9 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -499,7 +499,7 @@ static int __init parse_crash_elf64_headers(void) | |||
499 | /* Do some basic Verification. */ | 499 | /* Do some basic Verification. */ |
500 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | 500 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || |
501 | (ehdr.e_type != ET_CORE) || | 501 | (ehdr.e_type != ET_CORE) || |
502 | !vmcore_elf_check_arch(&ehdr) || | 502 | !vmcore_elf64_check_arch(&ehdr) || |
503 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || | 503 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || |
504 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | 504 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || |
505 | ehdr.e_version != EV_CURRENT || | 505 | ehdr.e_version != EV_CURRENT || |