]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] /proc/modules cleanup (seq_file, again)
authorAlexander Viro <viro@math.psu.edu>
Sat, 9 Feb 2002 14:18:08 +0000 (06:18 -0800)
committerDavid S. Miller <davem@redhat.com>
Sat, 9 Feb 2002 14:18:08 +0000 (06:18 -0800)
/proc/modules switched to use of seq_file, cleaned up.

fs/proc/proc_misc.c
kernel/module.c

index dbcbec45128642e4b22343b6bb39645b96b70830..b176467ff76599715b7edcc4bb9c2caa37da95e2 100644 (file)
@@ -50,9 +50,6 @@
  * have a way to deal with that gracefully. Right now I used straightforward
  * wrappers, but this needs further analysis wrt potential overflows.
  */
-#ifdef CONFIG_MODULES
-extern int get_module_list(char *);
-#endif
 extern int get_device_list(char *);
 extern int get_partition_list(char *, char **, off_t, int);
 extern int get_filesystem_list(char *);
@@ -203,13 +200,17 @@ static struct file_operations proc_cpuinfo_operations = {
 };
 
 #ifdef CONFIG_MODULES
-static int modules_read_proc(char *page, char **start, off_t off,
-                                int count, int *eof, void *data)
+extern struct seq_operations modules_op;
+static int modules_open(struct inode *inode, struct file *file)
 {
-       int len = get_module_list(page);
-       return proc_calc_metrics(page, start, off, count, eof, len);
+       return seq_open(file, &modules_op);
 }
-
+static struct file_operations proc_modules_operations = {
+       open:           modules_open,
+       read:           seq_read,
+       llseek:         seq_lseek,
+       release:        seq_release,
+};
 extern struct seq_operations ksyms_op;
 static int ksyms_open(struct inode *inode, struct file *file)
 {
@@ -535,9 +536,6 @@ void __init proc_misc_init(void)
                {"uptime",      uptime_read_proc},
                {"meminfo",     meminfo_read_proc},
                {"version",     version_read_proc},
-#ifdef CONFIG_MODULES
-               {"modules",     modules_read_proc},
-#endif
                {"stat",        kstat_read_proc},
                {"devices",     devices_read_proc},
                {"partitions",  partitions_read_proc},
@@ -567,6 +565,7 @@ void __init proc_misc_init(void)
        create_seq_entry("interrupts", 0, &proc_interrupts_operations);
        create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
 #ifdef CONFIG_MODULES
+       create_seq_entry("modules", 0, &proc_modules_operations);
        create_seq_entry("ksyms", 0, &proc_ksyms_operations);
 #endif
        proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
index 9d310463bfdbc107f7612f9a6bc0406ca767dd35..d0ed467083f9d6600f23977e135613b3a5b0ea83 100644 (file)
@@ -1075,84 +1075,67 @@ free_module(struct module *mod, int tag_freed)
 /*
  * Called by the /proc file system to return a current list of modules.
  */
-
-int get_module_list(char *p)
+static void *m_start(struct seq_file *m, loff_t *pos)
 {
-       size_t left = PAGE_SIZE;
-       struct module *mod;
-       char tmpstr[64];
-       struct module_ref *ref;
-
-       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
-               long len;
-               const char *q;
-
-#define safe_copy_str(str, len)                                                \
-               do {                                                    \
-                       if (left < len)                                 \
-                               goto fini;                              \
-                       memcpy(p, str, len); p += len, left -= len;     \
-               } while (0)
-#define safe_copy_cstr(str)    safe_copy_str(str, sizeof(str)-1)
-
-               len = strlen(mod->name);
-               safe_copy_str(mod->name, len);
-
-               if ((len = 20 - len) > 0) {
-                       if (left < len)
-                               goto fini;
-                       memset(p, ' ', len);
-                       p += len;
-                       left -= len;
-               }
-
-               len = sprintf(tmpstr, "%8lu", mod->size);
-               safe_copy_str(tmpstr, len);
-
-               if (mod->flags & MOD_RUNNING) {
-                       len = sprintf(tmpstr, "%4ld",
-                                     (mod_member_present(mod, can_unload)
-                                      && mod->can_unload
-                                      ? -1L : (long)atomic_read(&mod->uc.usecount)));
-                       safe_copy_str(tmpstr, len);
-               }
+       struct module *v;
+       loff_t n = *pos;
+       lock_kernel();
+       for (v = module_list; v && n--; v = v->next)
+               ;
+       return v;
+}
+static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+{
+       struct module *v = p;
+       (*pos)++;
+       return v->next;
+}
+static void m_stop(struct seq_file *m, void *p)
+{
+       unlock_kernel();
+}
+static int m_show(struct seq_file *m, void *p)
+{
+       struct module *mod = p;
+       struct module_ref *ref = mod->refs;
 
-               if (mod->flags & MOD_DELETED)
-                       safe_copy_cstr(" (deleted)");
-               else if (mod->flags & MOD_RUNNING) {
-                       if (mod->flags & MOD_AUTOCLEAN)
-                               safe_copy_cstr(" (autoclean)");
-                       if (!(mod->flags & MOD_USED_ONCE))
-                               safe_copy_cstr(" (unused)");
-               }
-               else if (mod->flags & MOD_INITIALIZING)
-                       safe_copy_cstr(" (initializing)");
-               else
-                       safe_copy_cstr(" (uninitialized)");
-
-               if ((ref = mod->refs) != NULL) {
-                       safe_copy_cstr(" [");
-                       while (1) {
-                               q = ref->ref->name;
-                               len = strlen(q);
-                               safe_copy_str(q, len);
-
-                               if ((ref = ref->next_ref) != NULL)
-                                       safe_copy_cstr(" ");
-                               else
-                                       break;
-                       }
-                       safe_copy_cstr("]");
-               }
-               safe_copy_cstr("\n");
+       if (mod == &kernel_module)
+               return 0;
 
-#undef safe_copy_str
-#undef safe_copy_cstr
+       seq_printf(m, "%-20s%8lu", mod->name, mod->size);
+       if (mod->flags & MOD_RUNNING)
+               seq_printf(m, "%4ld",
+                             (mod_member_present(mod, can_unload)
+                              && mod->can_unload
+                              ? -1L : (long)atomic_read(&mod->uc.usecount)));
+
+       if (mod->flags & MOD_DELETED)
+               seq_puts(m, " (deleted)");
+       else if (mod->flags & MOD_RUNNING) {
+               if (mod->flags & MOD_AUTOCLEAN)
+                       seq_puts(m, " (autoclean)");
+               if (!(mod->flags & MOD_USED_ONCE))
+                       seq_puts(m, " (unused)");
+       } else if (mod->flags & MOD_INITIALIZING)
+               seq_puts(m, " (initializing)");
+       else
+               seq_puts(m, " (uninitialized)");
+       if (ref) {
+               char c;
+               seq_putc(m, ' ');
+               for (c = '[' ; ref; c = ' ', ref = ref->next_ref)
+                       seq_printf(m, "%c%s", c, ref->ref->name);
+               seq_putc(m, ']');
        }
-
-fini:
-       return PAGE_SIZE - left;
+       seq_putc(m, '\n');
+       return 0;
 }
+struct seq_operations modules_op = {
+       start:  m_start,
+       next:   m_next,
+       stop:   m_stop,
+       show:   m_show
+};
 
 /*
  * Called by the /proc file system to return a current list of ksyms.