Commit e4dc1b14 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds

Use list_head in binfmt handling

Switch single-linked binfmt formats list to usual list_head's.  This leads
to one-liners in register_binfmt() and unregister_binfmt().  The downside
is one pointer more in struct linux_binfmt.  This is not a problem, since
the set of registered binfmts on typical box is very small -- (ELF +
something distro enabled for you).

Test-booted, played with executable .txt files, modprobe/rmmod binfmt_misc.
Signed-off-by: default avatarAlexey Dobriyan <adobriyan@sw.ru>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent deba0f49
...@@ -47,8 +47,11 @@ static int irix_core_dump(long signr, struct pt_regs * regs, ...@@ -47,8 +47,11 @@ static int irix_core_dump(long signr, struct pt_regs * regs,
struct file *file); struct file *file);
static struct linux_binfmt irix_format = { static struct linux_binfmt irix_format = {
NULL, THIS_MODULE, load_irix_binary, load_irix_library, .module = THIS_MODULE,
irix_core_dump, PAGE_SIZE .load_binary = load_irix_binary,
.load_shlib = load_irix_library,
.core_dump = irix_core_dump,
.min_coredump = PAGE_SIZE,
}; };
/* Debugging routines. */ /* Debugging routines. */
......
...@@ -38,8 +38,11 @@ static int load_aout32_library(struct file*); ...@@ -38,8 +38,11 @@ static int load_aout32_library(struct file*);
static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
static struct linux_binfmt aout32_format = { static struct linux_binfmt aout32_format = {
NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump, .module = THIS_MODULE,
PAGE_SIZE .load_binary = load_aout32_binary,
.load_shlib = load_aout32_library,
.core_dump = aout32_core_dump,
.min_coredump = PAGE_SIZE,
}; };
static void set_brk(unsigned long start, unsigned long end) static void set_brk(unsigned long start, unsigned long end)
......
...@@ -66,27 +66,15 @@ int suid_dumpable = 0; ...@@ -66,27 +66,15 @@ int suid_dumpable = 0;
EXPORT_SYMBOL(suid_dumpable); EXPORT_SYMBOL(suid_dumpable);
/* The maximal length of core_pattern is also specified in sysctl.c */ /* The maximal length of core_pattern is also specified in sysctl.c */
static struct linux_binfmt *formats; static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock); static DEFINE_RWLOCK(binfmt_lock);
int register_binfmt(struct linux_binfmt * fmt) int register_binfmt(struct linux_binfmt * fmt)
{ {
struct linux_binfmt ** tmp = &formats;
if (!fmt) if (!fmt)
return -EINVAL; return -EINVAL;
if (fmt->next)
return -EBUSY;
write_lock(&binfmt_lock); write_lock(&binfmt_lock);
while (*tmp) { list_add(&fmt->lh, &formats);
if (fmt == *tmp) {
write_unlock(&binfmt_lock);
return -EBUSY;
}
tmp = &(*tmp)->next;
}
fmt->next = formats;
formats = fmt;
write_unlock(&binfmt_lock); write_unlock(&binfmt_lock);
return 0; return 0;
} }
...@@ -95,20 +83,10 @@ EXPORT_SYMBOL(register_binfmt); ...@@ -95,20 +83,10 @@ EXPORT_SYMBOL(register_binfmt);
int unregister_binfmt(struct linux_binfmt * fmt) int unregister_binfmt(struct linux_binfmt * fmt)
{ {
struct linux_binfmt ** tmp = &formats;
write_lock(&binfmt_lock); write_lock(&binfmt_lock);
while (*tmp) { list_del(&fmt->lh);
if (fmt == *tmp) {
*tmp = fmt->next;
fmt->next = NULL;
write_unlock(&binfmt_lock); write_unlock(&binfmt_lock);
return 0; return 0;
}
tmp = &(*tmp)->next;
}
write_unlock(&binfmt_lock);
return -EINVAL;
} }
EXPORT_SYMBOL(unregister_binfmt); EXPORT_SYMBOL(unregister_binfmt);
...@@ -155,7 +133,7 @@ asmlinkage long sys_uselib(const char __user * library) ...@@ -155,7 +133,7 @@ asmlinkage long sys_uselib(const char __user * library)
struct linux_binfmt * fmt; struct linux_binfmt * fmt;
read_lock(&binfmt_lock); read_lock(&binfmt_lock);
for (fmt = formats ; fmt ; fmt = fmt->next) { list_for_each_entry(fmt, &formats, lh) {
if (!fmt->load_shlib) if (!fmt->load_shlib)
continue; continue;
if (!try_module_get(fmt->module)) if (!try_module_get(fmt->module))
...@@ -1284,7 +1262,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -1284,7 +1262,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
retval = -ENOENT; retval = -ENOENT;
for (try=0; try<2; try++) { for (try=0; try<2; try++) {
read_lock(&binfmt_lock); read_lock(&binfmt_lock);
for (fmt = formats ; fmt ; fmt = fmt->next) { list_for_each_entry(fmt, &formats, lh) {
int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary; int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
if (!fn) if (!fn)
continue; continue;
......
...@@ -63,7 +63,7 @@ struct linux_binprm{ ...@@ -63,7 +63,7 @@ struct linux_binprm{
* linux accepts. * linux accepts.
*/ */
struct linux_binfmt { struct linux_binfmt {
struct linux_binfmt * next; struct list_head lh;
struct module *module; struct module *module;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(struct file *); int (*load_shlib)(struct file *);
......
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