aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@sw.ru>2007-10-17 02:26:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:42:46 -0400
commite4dc1b14d8dc57c3975bf69740e4f5cda6bfba09 (patch)
tree084771b19ecb4335c31cdd91093f7a02b7861e69
parentdeba0f49b9345f885a53a077623a68cef89c01d5 (diff)
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: Alexey Dobriyan <adobriyan@sw.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/mips/kernel/irixelf.c7
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c7
-rw-r--r--fs/exec.c34
-rw-r--r--include/linux/binfmts.h2
4 files changed, 17 insertions, 33 deletions
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 8ef5cf4cc423..5a3fe43e3019 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -47,8 +47,11 @@ static int irix_core_dump(long signr, struct pt_regs * regs,
47 struct file *file); 47 struct file *file);
48 48
49static struct linux_binfmt irix_format = { 49static struct linux_binfmt irix_format = {
50 NULL, THIS_MODULE, load_irix_binary, load_irix_library, 50 .module = THIS_MODULE,
51 irix_core_dump, PAGE_SIZE 51 .load_binary = load_irix_binary,
52 .load_shlib = load_irix_library,
53 .core_dump = irix_core_dump,
54 .min_coredump = PAGE_SIZE,
52}; 55};
53 56
54/* Debugging routines. */ 57/* Debugging routines. */
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index d208cc7804f2..c8acbeab49b4 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -38,8 +38,11 @@ static int load_aout32_library(struct file*);
38static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); 38static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
39 39
40static struct linux_binfmt aout32_format = { 40static struct linux_binfmt aout32_format = {
41 NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump, 41 .module = THIS_MODULE,
42 PAGE_SIZE 42 .load_binary = load_aout32_binary,
43 .load_shlib = load_aout32_library,
44 .core_dump = aout32_core_dump,
45 .min_coredump = PAGE_SIZE,
43}; 46};
44 47
45static void set_brk(unsigned long start, unsigned long end) 48static void set_brk(unsigned long start, unsigned long end)
diff --git a/fs/exec.c b/fs/exec.c
index 073b0b8c6d05..65825bdc4475 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -66,27 +66,15 @@ int suid_dumpable = 0;
66EXPORT_SYMBOL(suid_dumpable); 66EXPORT_SYMBOL(suid_dumpable);
67/* The maximal length of core_pattern is also specified in sysctl.c */ 67/* The maximal length of core_pattern is also specified in sysctl.c */
68 68
69static struct linux_binfmt *formats; 69static LIST_HEAD(formats);
70static DEFINE_RWLOCK(binfmt_lock); 70static DEFINE_RWLOCK(binfmt_lock);
71 71
72int register_binfmt(struct linux_binfmt * fmt) 72int register_binfmt(struct linux_binfmt * fmt)
73{ 73{
74 struct linux_binfmt ** tmp = &formats;
75
76 if (!fmt) 74 if (!fmt)
77 return -EINVAL; 75 return -EINVAL;
78 if (fmt->next)
79 return -EBUSY;
80 write_lock(&binfmt_lock); 76 write_lock(&binfmt_lock);
81 while (*tmp) { 77 list_add(&fmt->lh, &formats);
82 if (fmt == *tmp) {
83 write_unlock(&binfmt_lock);
84 return -EBUSY;
85 }
86 tmp = &(*tmp)->next;
87 }
88 fmt->next = formats;
89 formats = fmt;
90 write_unlock(&binfmt_lock); 78 write_unlock(&binfmt_lock);
91 return 0; 79 return 0;
92} 80}
@@ -95,20 +83,10 @@ EXPORT_SYMBOL(register_binfmt);
95 83
96int unregister_binfmt(struct linux_binfmt * fmt) 84int unregister_binfmt(struct linux_binfmt * fmt)
97{ 85{
98 struct linux_binfmt ** tmp = &formats;
99
100 write_lock(&binfmt_lock); 86 write_lock(&binfmt_lock);
101 while (*tmp) { 87 list_del(&fmt->lh);
102 if (fmt == *tmp) {
103 *tmp = fmt->next;
104 fmt->next = NULL;
105 write_unlock(&binfmt_lock);
106 return 0;
107 }
108 tmp = &(*tmp)->next;
109 }
110 write_unlock(&binfmt_lock); 88 write_unlock(&binfmt_lock);
111 return -EINVAL; 89 return 0;
112} 90}
113 91
114EXPORT_SYMBOL(unregister_binfmt); 92EXPORT_SYMBOL(unregister_binfmt);
@@ -155,7 +133,7 @@ asmlinkage long sys_uselib(const char __user * library)
155 struct linux_binfmt * fmt; 133 struct linux_binfmt * fmt;
156 134
157 read_lock(&binfmt_lock); 135 read_lock(&binfmt_lock);
158 for (fmt = formats ; fmt ; fmt = fmt->next) { 136 list_for_each_entry(fmt, &formats, lh) {
159 if (!fmt->load_shlib) 137 if (!fmt->load_shlib)
160 continue; 138 continue;
161 if (!try_module_get(fmt->module)) 139 if (!try_module_get(fmt->module))
@@ -1284,7 +1262,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1284 retval = -ENOENT; 1262 retval = -ENOENT;
1285 for (try=0; try<2; try++) { 1263 for (try=0; try<2; try++) {
1286 read_lock(&binfmt_lock); 1264 read_lock(&binfmt_lock);
1287 for (fmt = formats ; fmt ; fmt = fmt->next) { 1265 list_for_each_entry(fmt, &formats, lh) {
1288 int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary; 1266 int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
1289 if (!fn) 1267 if (!fn)
1290 continue; 1268 continue;
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 91c8c07fe8b7..6b834dcd20b0 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -63,7 +63,7 @@ struct linux_binprm{
63 * linux accepts. 63 * linux accepts.
64 */ 64 */
65struct linux_binfmt { 65struct linux_binfmt {
66 struct linux_binfmt * next; 66 struct list_head lh;
67 struct module *module; 67 struct module *module;
68 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); 68 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
69 int (*load_shlib)(struct file *); 69 int (*load_shlib)(struct file *);