Commit d6b7a72c authored by Alexander Viro's avatar Alexander Viro Committed by David S. Miller

[PATCH] /proc/modules cleanup (seq_file, again)

	/proc/modules switched to use of seq_file, cleaned up.
parent 62dfe539
......@@ -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);
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment