Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@math.psu.edu>2002-02-09 06:18:08 -0800
committerDavid S. Miller <davem@redhat.com>2002-02-09 06:18:08 -0800
commitd6b7a72c56ebd4583f61752e130ae5242b925a53 (patch)
tree8b3f687708fed378252abff6adeec6a0f49582a4
parent62dfe539b9080f51c3a2c36e92152cbe8fba9911 (diff)
[PATCH] /proc/modules cleanup (seq_file, again)
/proc/modules switched to use of seq_file, cleaned up.
-rw-r--r--fs/proc/proc_misc.c21
-rw-r--r--kernel/module.c129
2 files changed, 66 insertions, 84 deletions
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index dbcbec451286..b176467ff765 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -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);
diff --git a/kernel/module.c b/kernel/module.c
index 9d310463bfdb..d0ed467083f9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -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.