[PATCH] Simplify proc/devices and fix early termination regression
[linux-2.6.git] / fs / proc / proc_misc.c
1 /*
2  *  linux/fs/proc/proc_misc.c
3  *
4  *  linux/fs/proc/array.c
5  *  Copyright (C) 1992  by Linus Torvalds
6  *  based on ideas by Darren Senn
7  *
8  *  This used to be the part of array.c. See the rest of history and credits
9  *  there. I took this into a separate file and switched the thing to generic
10  *  proc_file_inode_operations, leaving in array.c only per-process stuff.
11  *  Inumbers allocation made dynamic (via create_proc_entry()).  AV, May 1999.
12  *
13  * Changes:
14  * Fulton Green      :  Encapsulated position metric calculations.
15  *                      <kernel@FultonGreen.com>
16  */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/time.h>
21 #include <linux/kernel.h>
22 #include <linux/kernel_stat.h>
23 #include <linux/fs.h>
24 #include <linux/tty.h>
25 #include <linux/string.h>
26 #include <linux/mman.h>
27 #include <linux/proc_fs.h>
28 #include <linux/ioport.h>
29 #include <linux/config.h>
30 #include <linux/mm.h>
31 #include <linux/mmzone.h>
32 #include <linux/pagemap.h>
33 #include <linux/swap.h>
34 #include <linux/slab.h>
35 #include <linux/smp.h>
36 #include <linux/signal.h>
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/smp_lock.h>
40 #include <linux/seq_file.h>
41 #include <linux/times.h>
42 #include <linux/profile.h>
43 #include <linux/blkdev.h>
44 #include <linux/hugetlb.h>
45 #include <linux/jiffies.h>
46 #include <linux/sysrq.h>
47 #include <linux/vmalloc.h>
48 #include <linux/crash_dump.h>
49 #include <asm/uaccess.h>
50 #include <asm/pgtable.h>
51 #include <asm/io.h>
52 #include <asm/tlb.h>
53 #include <asm/div64.h>
54 #include "internal.h"
55
56 #define LOAD_INT(x) ((x) >> FSHIFT)
57 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
58 /*
59  * Warning: stuff below (imported functions) assumes that its output will fit
60  * into one page. For some of those functions it may be wrong. Moreover, we
61  * have a way to deal with that gracefully. Right now I used straightforward
62  * wrappers, but this needs further analysis wrt potential overflows.
63  */
64 extern int get_hardware_list(char *);
65 extern int get_stram_list(char *);
66 extern int get_filesystem_list(char *);
67 extern int get_exec_domain_list(char *);
68 extern int get_dma_list(char *);
69 extern int get_locks_status (char *, char **, off_t, int);
70
71 static int proc_calc_metrics(char *page, char **start, off_t off,
72                                  int count, int *eof, int len)
73 {
74         if (len <= off+count) *eof = 1;
75         *start = page + off;
76         len -= off;
77         if (len>count) len = count;
78         if (len<0) len = 0;
79         return len;
80 }
81
82 static int loadavg_read_proc(char *page, char **start, off_t off,
83                                  int count, int *eof, void *data)
84 {
85         int a, b, c;
86         int len;
87
88         a = avenrun[0] + (FIXED_1/200);
89         b = avenrun[1] + (FIXED_1/200);
90         c = avenrun[2] + (FIXED_1/200);
91         len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
92                 LOAD_INT(a), LOAD_FRAC(a),
93                 LOAD_INT(b), LOAD_FRAC(b),
94                 LOAD_INT(c), LOAD_FRAC(c),
95                 nr_running(), nr_threads, last_pid);
96         return proc_calc_metrics(page, start, off, count, eof, len);
97 }
98
99 static int uptime_read_proc(char *page, char **start, off_t off,
100                                  int count, int *eof, void *data)
101 {
102         struct timespec uptime;
103         struct timespec idle;
104         int len;
105         cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
106
107         do_posix_clock_monotonic_gettime(&uptime);
108         cputime_to_timespec(idletime, &idle);
109         len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
110                         (unsigned long) uptime.tv_sec,
111                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
112                         (unsigned long) idle.tv_sec,
113                         (idle.tv_nsec / (NSEC_PER_SEC / 100)));
114
115         return proc_calc_metrics(page, start, off, count, eof, len);
116 }
117
118 static int meminfo_read_proc(char *page, char **start, off_t off,
119                                  int count, int *eof, void *data)
120 {
121         struct sysinfo i;
122         int len;
123         struct page_state ps;
124         unsigned long inactive;
125         unsigned long active;
126         unsigned long free;
127         unsigned long committed;
128         unsigned long allowed;
129         struct vmalloc_info vmi;
130         long cached;
131
132         get_page_state(&ps);
133         get_zone_counts(&active, &inactive, &free);
134
135 /*
136  * display in kilobytes.
137  */
138 #define K(x) ((x) << (PAGE_SHIFT - 10))
139         si_meminfo(&i);
140         si_swapinfo(&i);
141         committed = atomic_read(&vm_committed_space);
142         allowed = ((totalram_pages - hugetlb_total_pages())
143                 * sysctl_overcommit_ratio / 100) + total_swap_pages;
144
145         cached = get_page_cache_size() - total_swapcache_pages - i.bufferram;
146         if (cached < 0)
147                 cached = 0;
148
149         get_vmalloc_info(&vmi);
150
151         /*
152          * Tagged format, for easy grepping and expansion.
153          */
154         len = sprintf(page,
155                 "MemTotal:     %8lu kB\n"
156                 "MemFree:      %8lu kB\n"
157                 "Buffers:      %8lu kB\n"
158                 "Cached:       %8lu kB\n"
159                 "SwapCached:   %8lu kB\n"
160                 "Active:       %8lu kB\n"
161                 "Inactive:     %8lu kB\n"
162                 "HighTotal:    %8lu kB\n"
163                 "HighFree:     %8lu kB\n"
164                 "LowTotal:     %8lu kB\n"
165                 "LowFree:      %8lu kB\n"
166                 "SwapTotal:    %8lu kB\n"
167                 "SwapFree:     %8lu kB\n"
168                 "Dirty:        %8lu kB\n"
169                 "Writeback:    %8lu kB\n"
170                 "Mapped:       %8lu kB\n"
171                 "Slab:         %8lu kB\n"
172                 "CommitLimit:  %8lu kB\n"
173                 "Committed_AS: %8lu kB\n"
174                 "PageTables:   %8lu kB\n"
175                 "VmallocTotal: %8lu kB\n"
176                 "VmallocUsed:  %8lu kB\n"
177                 "VmallocChunk: %8lu kB\n",
178                 K(i.totalram),
179                 K(i.freeram),
180                 K(i.bufferram),
181                 K(cached),
182                 K(total_swapcache_pages),
183                 K(active),
184                 K(inactive),
185                 K(i.totalhigh),
186                 K(i.freehigh),
187                 K(i.totalram-i.totalhigh),
188                 K(i.freeram-i.freehigh),
189                 K(i.totalswap),
190                 K(i.freeswap),
191                 K(ps.nr_dirty),
192                 K(ps.nr_writeback),
193                 K(ps.nr_mapped),
194                 K(ps.nr_slab),
195                 K(allowed),
196                 K(committed),
197                 K(ps.nr_page_table_pages),
198                 (unsigned long)VMALLOC_TOTAL >> 10,
199                 vmi.used >> 10,
200                 vmi.largest_chunk >> 10
201                 );
202
203                 len += hugetlb_report_meminfo(page + len);
204
205         return proc_calc_metrics(page, start, off, count, eof, len);
206 #undef K
207 }
208
209 extern struct seq_operations fragmentation_op;
210 static int fragmentation_open(struct inode *inode, struct file *file)
211 {
212         (void)inode;
213         return seq_open(file, &fragmentation_op);
214 }
215
216 static struct file_operations fragmentation_file_operations = {
217         .open           = fragmentation_open,
218         .read           = seq_read,
219         .llseek         = seq_lseek,
220         .release        = seq_release,
221 };
222
223 extern struct seq_operations zoneinfo_op;
224 static int zoneinfo_open(struct inode *inode, struct file *file)
225 {
226         return seq_open(file, &zoneinfo_op);
227 }
228
229 static struct file_operations proc_zoneinfo_file_operations = {
230         .open           = zoneinfo_open,
231         .read           = seq_read,
232         .llseek         = seq_lseek,
233         .release        = seq_release,
234 };
235
236 static int version_read_proc(char *page, char **start, off_t off,
237                                  int count, int *eof, void *data)
238 {
239         int len;
240
241         strcpy(page, linux_banner);
242         len = strlen(page);
243         return proc_calc_metrics(page, start, off, count, eof, len);
244 }
245
246 extern struct seq_operations cpuinfo_op;
247 static int cpuinfo_open(struct inode *inode, struct file *file)
248 {
249         return seq_open(file, &cpuinfo_op);
250 }
251
252 static struct file_operations proc_cpuinfo_operations = {
253         .open           = cpuinfo_open,
254         .read           = seq_read,
255         .llseek         = seq_lseek,
256         .release        = seq_release,
257 };
258
259 static int devinfo_show(struct seq_file *f, void *v)
260 {
261         int i = *(loff_t *) v;
262
263         if (i < CHRDEV_MAJOR_HASH_SIZE) {
264                 if (i == 0)
265                         seq_printf(f, "Character devices:\n");
266                 chrdev_show(f, i);
267         } else {
268                 i -= CHRDEV_MAJOR_HASH_SIZE;
269                 if (i == 0)
270                         seq_printf(f, "\nBlock devices:\n");
271                 blkdev_show(f, i);
272         }
273         return 0;
274 }
275
276 static void *devinfo_start(struct seq_file *f, loff_t *pos)
277 {
278         if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
279                 return pos;
280         return NULL;
281 }
282
283 static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
284 {
285         (*pos)++;
286         if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
287                 return NULL;
288         return pos;
289 }
290
291 static void devinfo_stop(struct seq_file *f, void *v)
292 {
293         /* Nothing to do */
294 }
295
296 static struct seq_operations devinfo_ops = {
297         .start = devinfo_start,
298         .next  = devinfo_next,
299         .stop  = devinfo_stop,
300         .show  = devinfo_show
301 };
302
303 static int devinfo_open(struct inode *inode, struct file *filp)
304 {
305         return seq_open(filp, &devinfo_ops);
306 }
307
308 static struct file_operations proc_devinfo_operations = {
309         .open           = devinfo_open,
310         .read           = seq_read,
311         .llseek         = seq_lseek,
312         .release        = seq_release,
313 };
314
315 extern struct seq_operations vmstat_op;
316 static int vmstat_open(struct inode *inode, struct file *file)
317 {
318         return seq_open(file, &vmstat_op);
319 }
320 static struct file_operations proc_vmstat_file_operations = {
321         .open           = vmstat_open,
322         .read           = seq_read,
323         .llseek         = seq_lseek,
324         .release        = seq_release,
325 };
326
327 #ifdef CONFIG_PROC_HARDWARE
328 static int hardware_read_proc(char *page, char **start, off_t off,
329                                  int count, int *eof, void *data)
330 {
331         int len = get_hardware_list(page);
332         return proc_calc_metrics(page, start, off, count, eof, len);
333 }
334 #endif
335
336 #ifdef CONFIG_STRAM_PROC
337 static int stram_read_proc(char *page, char **start, off_t off,
338                                  int count, int *eof, void *data)
339 {
340         int len = get_stram_list(page);
341         return proc_calc_metrics(page, start, off, count, eof, len);
342 }
343 #endif
344
345 extern struct seq_operations partitions_op;
346 static int partitions_open(struct inode *inode, struct file *file)
347 {
348         return seq_open(file, &partitions_op);
349 }
350 static struct file_operations proc_partitions_operations = {
351         .open           = partitions_open,
352         .read           = seq_read,
353         .llseek         = seq_lseek,
354         .release        = seq_release,
355 };
356
357 extern struct seq_operations diskstats_op;
358 static int diskstats_open(struct inode *inode, struct file *file)
359 {
360         return seq_open(file, &diskstats_op);
361 }
362 static struct file_operations proc_diskstats_operations = {
363         .open           = diskstats_open,
364         .read           = seq_read,
365         .llseek         = seq_lseek,
366         .release        = seq_release,
367 };
368
369 #ifdef CONFIG_MODULES
370 extern struct seq_operations modules_op;
371 static int modules_open(struct inode *inode, struct file *file)
372 {
373         return seq_open(file, &modules_op);
374 }
375 static struct file_operations proc_modules_operations = {
376         .open           = modules_open,
377         .read           = seq_read,
378         .llseek         = seq_lseek,
379         .release        = seq_release,
380 };
381 #endif
382
383 #ifdef CONFIG_SLAB
384 extern struct seq_operations slabinfo_op;
385 extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
386 static int slabinfo_open(struct inode *inode, struct file *file)
387 {
388         return seq_open(file, &slabinfo_op);
389 }
390 static struct file_operations proc_slabinfo_operations = {
391         .open           = slabinfo_open,
392         .read           = seq_read,
393         .write          = slabinfo_write,
394         .llseek         = seq_lseek,
395         .release        = seq_release,
396 };
397
398 #ifdef CONFIG_DEBUG_SLAB_LEAK
399 extern struct seq_operations slabstats_op;
400 static int slabstats_open(struct inode *inode, struct file *file)
401 {
402         unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
403         int ret = -ENOMEM;
404         if (n) {
405                 ret = seq_open(file, &slabstats_op);
406                 if (!ret) {
407                         struct seq_file *m = file->private_data;
408                         *n = PAGE_SIZE / (2 * sizeof(unsigned long));
409                         m->private = n;
410                         n = NULL;
411                 }
412                 kfree(n);
413         }
414         return ret;
415 }
416
417 static int slabstats_release(struct inode *inode, struct file *file)
418 {
419         struct seq_file *m = file->private_data;
420         kfree(m->private);
421         return seq_release(inode, file);
422 }
423
424 static struct file_operations proc_slabstats_operations = {
425         .open           = slabstats_open,
426         .read           = seq_read,
427         .llseek         = seq_lseek,
428         .release        = slabstats_release,
429 };
430 #endif
431 #endif
432
433 static int show_stat(struct seq_file *p, void *v)
434 {
435         int i;
436         unsigned long jif;
437         cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
438         u64 sum = 0;
439
440         user = nice = system = idle = iowait =
441                 irq = softirq = steal = cputime64_zero;
442         jif = - wall_to_monotonic.tv_sec;
443         if (wall_to_monotonic.tv_nsec)
444                 --jif;
445
446         for_each_possible_cpu(i) {
447                 int j;
448
449                 user = cputime64_add(user, kstat_cpu(i).cpustat.user);
450                 nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
451                 system = cputime64_add(system, kstat_cpu(i).cpustat.system);
452                 idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
453                 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
454                 irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
455                 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
456                 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
457                 for (j = 0 ; j < NR_IRQS ; j++)
458                         sum += kstat_cpu(i).irqs[j];
459         }
460
461         seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu\n",
462                 (unsigned long long)cputime64_to_clock_t(user),
463                 (unsigned long long)cputime64_to_clock_t(nice),
464                 (unsigned long long)cputime64_to_clock_t(system),
465                 (unsigned long long)cputime64_to_clock_t(idle),
466                 (unsigned long long)cputime64_to_clock_t(iowait),
467                 (unsigned long long)cputime64_to_clock_t(irq),
468                 (unsigned long long)cputime64_to_clock_t(softirq),
469                 (unsigned long long)cputime64_to_clock_t(steal));
470         for_each_online_cpu(i) {
471
472                 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
473                 user = kstat_cpu(i).cpustat.user;
474                 nice = kstat_cpu(i).cpustat.nice;
475                 system = kstat_cpu(i).cpustat.system;
476                 idle = kstat_cpu(i).cpustat.idle;
477                 iowait = kstat_cpu(i).cpustat.iowait;
478                 irq = kstat_cpu(i).cpustat.irq;
479                 softirq = kstat_cpu(i).cpustat.softirq;
480                 steal = kstat_cpu(i).cpustat.steal;
481                 seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
482                         i,
483                         (unsigned long long)cputime64_to_clock_t(user),
484                         (unsigned long long)cputime64_to_clock_t(nice),
485                         (unsigned long long)cputime64_to_clock_t(system),
486                         (unsigned long long)cputime64_to_clock_t(idle),
487                         (unsigned long long)cputime64_to_clock_t(iowait),
488                         (unsigned long long)cputime64_to_clock_t(irq),
489                         (unsigned long long)cputime64_to_clock_t(softirq),
490                         (unsigned long long)cputime64_to_clock_t(steal));
491         }
492         seq_printf(p, "intr %llu", (unsigned long long)sum);
493
494 #if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
495         for (i = 0; i < NR_IRQS; i++)
496                 seq_printf(p, " %u", kstat_irqs(i));
497 #endif
498
499         seq_printf(p,
500                 "\nctxt %llu\n"
501                 "btime %lu\n"
502                 "processes %lu\n"
503                 "procs_running %lu\n"
504                 "procs_blocked %lu\n",
505                 nr_context_switches(),
506                 (unsigned long)jif,
507                 total_forks,
508                 nr_running(),
509                 nr_iowait());
510
511         return 0;
512 }
513
514 static int stat_open(struct inode *inode, struct file *file)
515 {
516         unsigned size = 4096 * (1 + num_possible_cpus() / 32);
517         char *buf;
518         struct seq_file *m;
519         int res;
520
521         /* don't ask for more than the kmalloc() max size, currently 128 KB */
522         if (size > 128 * 1024)
523                 size = 128 * 1024;
524         buf = kmalloc(size, GFP_KERNEL);
525         if (!buf)
526                 return -ENOMEM;
527
528         res = single_open(file, show_stat, NULL);
529         if (!res) {
530                 m = file->private_data;
531                 m->buf = buf;
532                 m->size = size;
533         } else
534                 kfree(buf);
535         return res;
536 }
537 static struct file_operations proc_stat_operations = {
538         .open           = stat_open,
539         .read           = seq_read,
540         .llseek         = seq_lseek,
541         .release        = single_release,
542 };
543
544 /*
545  * /proc/interrupts
546  */
547 static void *int_seq_start(struct seq_file *f, loff_t *pos)
548 {
549         return (*pos <= NR_IRQS) ? pos : NULL;
550 }
551
552 static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
553 {
554         (*pos)++;
555         if (*pos > NR_IRQS)
556                 return NULL;
557         return pos;
558 }
559
560 static void int_seq_stop(struct seq_file *f, void *v)
561 {
562         /* Nothing to do */
563 }
564
565
566 extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */
567 static struct seq_operations int_seq_ops = {
568         .start = int_seq_start,
569         .next  = int_seq_next,
570         .stop  = int_seq_stop,
571         .show  = show_interrupts
572 };
573
574 static int interrupts_open(struct inode *inode, struct file *filp)
575 {
576         return seq_open(filp, &int_seq_ops);
577 }
578
579 static struct file_operations proc_interrupts_operations = {
580         .open           = interrupts_open,
581         .read           = seq_read,
582         .llseek         = seq_lseek,
583         .release        = seq_release,
584 };
585
586 static int filesystems_read_proc(char *page, char **start, off_t off,
587                                  int count, int *eof, void *data)
588 {
589         int len = get_filesystem_list(page);
590         return proc_calc_metrics(page, start, off, count, eof, len);
591 }
592
593 static int cmdline_read_proc(char *page, char **start, off_t off,
594                                  int count, int *eof, void *data)
595 {
596         int len;
597
598         len = sprintf(page, "%s\n", saved_command_line);
599         return proc_calc_metrics(page, start, off, count, eof, len);
600 }
601
602 static int locks_read_proc(char *page, char **start, off_t off,
603                                  int count, int *eof, void *data)
604 {
605         int len = get_locks_status(page, start, off, count);
606
607         if (len < count)
608                 *eof = 1;
609         return len;
610 }
611
612 static int execdomains_read_proc(char *page, char **start, off_t off,
613                                  int count, int *eof, void *data)
614 {
615         int len = get_exec_domain_list(page);
616         return proc_calc_metrics(page, start, off, count, eof, len);
617 }
618
619 #ifdef CONFIG_MAGIC_SYSRQ
620 /*
621  * writing 'C' to /proc/sysrq-trigger is like sysrq-C
622  */
623 static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
624                                    size_t count, loff_t *ppos)
625 {
626         if (count) {
627                 char c;
628
629                 if (get_user(c, buf))
630                         return -EFAULT;
631                 __handle_sysrq(c, NULL, NULL, 0);
632         }
633         return count;
634 }
635
636 static struct file_operations proc_sysrq_trigger_operations = {
637         .write          = write_sysrq_trigger,
638 };
639 #endif
640
641 struct proc_dir_entry *proc_root_kcore;
642
643 void create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
644 {
645         struct proc_dir_entry *entry;
646         entry = create_proc_entry(name, mode, NULL);
647         if (entry)
648                 entry->proc_fops = f;
649 }
650
651 void __init proc_misc_init(void)
652 {
653         struct proc_dir_entry *entry;
654         static struct {
655                 char *name;
656                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
657         } *p, simple_ones[] = {
658                 {"loadavg",     loadavg_read_proc},
659                 {"uptime",      uptime_read_proc},
660                 {"meminfo",     meminfo_read_proc},
661                 {"version",     version_read_proc},
662 #ifdef CONFIG_PROC_HARDWARE
663                 {"hardware",    hardware_read_proc},
664 #endif
665 #ifdef CONFIG_STRAM_PROC
666                 {"stram",       stram_read_proc},
667 #endif
668                 {"filesystems", filesystems_read_proc},
669                 {"cmdline",     cmdline_read_proc},
670                 {"locks",       locks_read_proc},
671                 {"execdomains", execdomains_read_proc},
672                 {NULL,}
673         };
674         for (p = simple_ones; p->name; p++)
675                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
676
677         proc_symlink("mounts", NULL, "self/mounts");
678
679         /* And now for trickier ones */
680         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
681         if (entry)
682                 entry->proc_fops = &proc_kmsg_operations;
683         create_seq_entry("devices", 0, &proc_devinfo_operations);
684         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
685         create_seq_entry("partitions", 0, &proc_partitions_operations);
686         create_seq_entry("stat", 0, &proc_stat_operations);
687         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
688 #ifdef CONFIG_SLAB
689         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
690 #ifdef CONFIG_DEBUG_SLAB_LEAK
691         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
692 #endif
693 #endif
694         create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
695         create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
696         create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
697         create_seq_entry("diskstats", 0, &proc_diskstats_operations);
698 #ifdef CONFIG_MODULES
699         create_seq_entry("modules", 0, &proc_modules_operations);
700 #endif
701 #ifdef CONFIG_SCHEDSTATS
702         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
703 #endif
704 #ifdef CONFIG_PROC_KCORE
705         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
706         if (proc_root_kcore) {
707                 proc_root_kcore->proc_fops = &proc_kcore_operations;
708                 proc_root_kcore->size =
709                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
710         }
711 #endif
712 #ifdef CONFIG_PROC_VMCORE
713         proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL);
714         if (proc_vmcore)
715                 proc_vmcore->proc_fops = &proc_vmcore_operations;
716 #endif
717 #ifdef CONFIG_MAGIC_SYSRQ
718         entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
719         if (entry)
720                 entry->proc_fops = &proc_sysrq_trigger_operations;
721 #endif
722 }