[PATCH] fix linux banner format string
[linux-2.6.git] / fs / proc / proc_misc.c
index 1edce0c..b37ce33 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/mman.h>
 #include <linux/proc_fs.h>
 #include <linux/ioport.h>
-#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
 #include <linux/times.h>
 #include <linux/profile.h>
+#include <linux/utsname.h>
 #include <linux/blkdev.h>
 #include <linux/hugetlb.h>
 #include <linux/jiffies.h>
 #include <linux/sysrq.h>
 #include <linux/vmalloc.h>
 #include <linux/crash_dump.h>
+#include <linux/pid_namespace.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -92,7 +93,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
                LOAD_INT(a), LOAD_FRAC(a),
                LOAD_INT(b), LOAD_FRAC(b),
                LOAD_INT(c), LOAD_FRAC(c),
-               nr_running(), nr_threads, last_pid);
+               nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
@@ -120,7 +121,6 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
 {
        struct sysinfo i;
        int len;
-       struct page_state ps;
        unsigned long inactive;
        unsigned long active;
        unsigned long free;
@@ -129,7 +129,6 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
        struct vmalloc_info vmi;
        long cached;
 
-       get_page_state(&ps);
        get_zone_counts(&active, &inactive, &free);
 
 /*
@@ -142,7 +141,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
        allowed = ((totalram_pages - hugetlb_total_pages())
                * sysctl_overcommit_ratio / 100) + total_swap_pages;
 
-       cached = get_page_cache_size() - total_swapcache_pages - i.bufferram;
+       cached = global_page_state(NR_FILE_PAGES) -
+                       total_swapcache_pages - i.bufferram;
        if (cached < 0)
                cached = 0;
 
@@ -159,19 +159,26 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                "SwapCached:   %8lu kB\n"
                "Active:       %8lu kB\n"
                "Inactive:     %8lu kB\n"
+#ifdef CONFIG_HIGHMEM
                "HighTotal:    %8lu kB\n"
                "HighFree:     %8lu kB\n"
                "LowTotal:     %8lu kB\n"
                "LowFree:      %8lu kB\n"
+#endif
                "SwapTotal:    %8lu kB\n"
                "SwapFree:     %8lu kB\n"
                "Dirty:        %8lu kB\n"
                "Writeback:    %8lu kB\n"
+               "AnonPages:    %8lu kB\n"
                "Mapped:       %8lu kB\n"
                "Slab:         %8lu kB\n"
+               "SReclaimable: %8lu kB\n"
+               "SUnreclaim:   %8lu kB\n"
+               "PageTables:   %8lu kB\n"
+               "NFS_Unstable: %8lu kB\n"
+               "Bounce:       %8lu kB\n"
                "CommitLimit:  %8lu kB\n"
                "Committed_AS: %8lu kB\n"
-               "PageTables:   %8lu kB\n"
                "VmallocTotal: %8lu kB\n"
                "VmallocUsed:  %8lu kB\n"
                "VmallocChunk: %8lu kB\n",
@@ -182,19 +189,27 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                K(total_swapcache_pages),
                K(active),
                K(inactive),
+#ifdef CONFIG_HIGHMEM
                K(i.totalhigh),
                K(i.freehigh),
                K(i.totalram-i.totalhigh),
                K(i.freeram-i.freehigh),
+#endif
                K(i.totalswap),
                K(i.freeswap),
-               K(ps.nr_dirty),
-               K(ps.nr_writeback),
-               K(ps.nr_mapped),
-               K(ps.nr_slab),
+               K(global_page_state(NR_FILE_DIRTY)),
+               K(global_page_state(NR_WRITEBACK)),
+               K(global_page_state(NR_ANON_PAGES)),
+               K(global_page_state(NR_FILE_MAPPED)),
+               K(global_page_state(NR_SLAB_RECLAIMABLE) +
+                               global_page_state(NR_SLAB_UNRECLAIMABLE)),
+               K(global_page_state(NR_SLAB_RECLAIMABLE)),
+               K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
+               K(global_page_state(NR_PAGETABLE)),
+               K(global_page_state(NR_UNSTABLE_NFS)),
+               K(global_page_state(NR_BOUNCE)),
                K(allowed),
                K(committed),
-               K(ps.nr_page_table_pages),
                (unsigned long)VMALLOC_TOTAL >> 10,
                vmi.used >> 10,
                vmi.largest_chunk >> 10
@@ -238,8 +253,10 @@ static int version_read_proc(char *page, char **start, off_t off,
 {
        int len;
 
-       strcpy(page, linux_banner);
-       len = strlen(page);
+       len = snprintf(page, PAGE_SIZE, linux_proc_banner,
+               utsname()->sysname,
+               utsname()->release,
+               utsname()->version);
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
@@ -249,144 +266,63 @@ static int cpuinfo_open(struct inode *inode, struct file *file)
        return seq_open(file, &cpuinfo_op);
 }
 
-enum devinfo_states {
-       CHR_HDR,
-       CHR_LIST,
-       BLK_HDR,
-       BLK_LIST,
-       DEVINFO_DONE
-};
-
-struct devinfo_state {
-       void *chrdev;
-       void *blkdev;
-       unsigned int num_records;
-       unsigned int cur_record;
-       enum devinfo_states state;
+static struct file_operations proc_cpuinfo_operations = {
+       .open           = cpuinfo_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
 };
 
-static void *devinfo_start(struct seq_file *f, loff_t *pos)
+static int devinfo_show(struct seq_file *f, void *v)
 {
-       struct devinfo_state *info = f->private;
+       int i = *(loff_t *) v;
 
-       if (*pos) {
-               if ((info) && (*pos <= info->num_records))
-                       return info;
-               return NULL;
+       if (i < CHRDEV_MAJOR_HASH_SIZE) {
+               if (i == 0)
+                       seq_printf(f, "Character devices:\n");
+               chrdev_show(f, i);
+       }
+#ifdef CONFIG_BLOCK
+       else {
+               i -= CHRDEV_MAJOR_HASH_SIZE;
+               if (i == 0)
+                       seq_printf(f, "\nBlock devices:\n");
+               blkdev_show(f, i);
        }
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
-       f->private = info;
-       info->chrdev = acquire_chrdev_list();
-       info->blkdev = acquire_blkdev_list();
-       info->state = CHR_HDR;
-       info->num_records = count_chrdev_list();
-       info->num_records += count_blkdev_list();
-       info->num_records += 2; /* Character and Block headers */
-       *pos = 1;
-       info->cur_record = *pos;
-       return info;
+#endif
+       return 0;
 }
 
-static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
+static void *devinfo_start(struct seq_file *f, loff_t *pos)
 {
-       int idummy;
-       char *ndummy;
-       struct devinfo_state *info = f->private;
-
-       switch (info->state) {
-               case CHR_HDR:
-                       info->state = CHR_LIST;
-                       (*pos)++;
-                       /*fallthrough*/
-               case CHR_LIST:
-                       if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
-                               /*
-                                * The character dev list is complete
-                                */
-                               info->state = BLK_HDR;
-                       } else {
-                               info->chrdev = get_next_chrdev(info->chrdev);
-                       }
-                       (*pos)++;
-                       break;
-               case BLK_HDR:
-                       info->state = BLK_LIST;
-                       (*pos)++;
-                       /*fallthrough*/
-               case BLK_LIST:
-                       if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
-                               /*
-                                * The block dev list is complete
-                                */
-                               info->state = DEVINFO_DONE;
-                       } else {
-                               info->blkdev = get_next_blkdev(info->blkdev);
-                       }
-                       (*pos)++;
-                       break;
-               case DEVINFO_DONE:
-                       (*pos)++;
-                       info->cur_record = *pos;
-                       info = NULL;
-                       break;
-               default:
-                       break;
-       }
-       if (info)
-               info->cur_record = *pos;
-       return info;
+       if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
+               return pos;
+       return NULL;
 }
 
-static void devinfo_stop(struct seq_file *f, void *v)
+static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
 {
-       struct devinfo_state *info = f->private;
-
-       if (info) {
-               release_chrdev_list(info->chrdev);
-               release_blkdev_list(info->blkdev);
-               f->private = NULL;
-               kfree(info);
-       }
+       (*pos)++;
+       if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
+               return NULL;
+       return pos;
 }
 
-static int devinfo_show(struct seq_file *f, void *arg)
-{
-       int major;
-       char *name;
-       struct devinfo_state *info = f->private;
-
-       switch(info->state) {
-               case CHR_HDR:
-                       seq_printf(f,"Character devices:\n");
-                       /* fallthrough */
-               case CHR_LIST:
-                       if (!get_chrdev_info(info->chrdev,&major,&name))
-                               seq_printf(f,"%3d %s\n",major,name);
-                       break;
-               case BLK_HDR:
-                       seq_printf(f,"\nBlock devices:\n");
-                       /* fallthrough */
-               case BLK_LIST:
-                       if (!get_blkdev_info(info->blkdev,&major,&name))
-                               seq_printf(f,"%3d %s\n",major,name);
-                       break;
-               default:
-                       break;
-       }
-
-       return 0;
+static void devinfo_stop(struct seq_file *f, void *v)
+{
+       /* Nothing to do */
 }
 
-static  struct seq_operations devinfo_op = {
-       .start  = devinfo_start,
-       .next   = devinfo_next,
-       .stop   = devinfo_stop,
-       .show   = devinfo_show,
+static struct seq_operations devinfo_ops = {
+       .start = devinfo_start,
+       .next  = devinfo_next,
+       .stop  = devinfo_stop,
+       .show  = devinfo_show
 };
 
-static int devinfo_open(struct inode *inode, struct file *file)
+static int devinfo_open(struct inode *inode, struct file *filp)
 {
-       return seq_open(file, &devinfo_op);
+       return seq_open(filp, &devinfo_ops);
 }
 
 static struct file_operations proc_devinfo_operations = {
@@ -396,13 +332,6 @@ static struct file_operations proc_devinfo_operations = {
        .release        = seq_release,
 };
 
-static struct file_operations proc_cpuinfo_operations = {
-       .open           = cpuinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
 extern struct seq_operations vmstat_op;
 static int vmstat_open(struct inode *inode, struct file *file)
 {
@@ -433,6 +362,7 @@ static int stram_read_proc(char *page, char **start, off_t off,
 }
 #endif
 
+#ifdef CONFIG_BLOCK
 extern struct seq_operations partitions_op;
 static int partitions_open(struct inode *inode, struct file *file)
 {
@@ -456,6 +386,7 @@ static struct file_operations proc_diskstats_operations = {
        .llseek         = seq_lseek,
        .release        = seq_release,
 };
+#endif
 
 #ifdef CONFIG_MODULES
 extern struct seq_operations modules_op;
@@ -719,7 +650,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
 
                if (get_user(c, buf))
                        return -EFAULT;
-               __handle_sysrq(c, NULL, NULL, 0);
+               __handle_sysrq(c, NULL, 0);
        }
        return count;
 }
@@ -731,7 +662,7 @@ static struct file_operations proc_sysrq_trigger_operations = {
 
 struct proc_dir_entry *proc_root_kcore;
 
-void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
+void create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
 {
        struct proc_dir_entry *entry;
        entry = create_proc_entry(name, mode, NULL);
@@ -768,12 +699,16 @@ void __init proc_misc_init(void)
        proc_symlink("mounts", NULL, "self/mounts");
 
        /* And now for trickier ones */
+#ifdef CONFIG_PRINTK
        entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
        if (entry)
                entry->proc_fops = &proc_kmsg_operations;
+#endif
        create_seq_entry("devices", 0, &proc_devinfo_operations);
        create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+#ifdef CONFIG_BLOCK
        create_seq_entry("partitions", 0, &proc_partitions_operations);
+#endif
        create_seq_entry("stat", 0, &proc_stat_operations);
        create_seq_entry("interrupts", 0, &proc_interrupts_operations);
 #ifdef CONFIG_SLAB
@@ -785,7 +720,9 @@ void __init proc_misc_init(void)
        create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
        create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
        create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
+#ifdef CONFIG_BLOCK
        create_seq_entry("diskstats", 0, &proc_diskstats_operations);
+#endif
 #ifdef CONFIG_MODULES
        create_seq_entry("modules", 0, &proc_modules_operations);
 #endif