diff options
author | Alexey Dobriyan <adobriyan@sw.ru> | 2007-10-17 02:26:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 11:42:46 -0400 |
commit | e4dc1b14d8dc57c3975bf69740e4f5cda6bfba09 (patch) | |
tree | 084771b19ecb4335c31cdd91093f7a02b7861e69 | |
parent | deba0f49b9345f885a53a077623a68cef89c01d5 (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.c | 7 | ||||
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 7 | ||||
-rw-r--r-- | fs/exec.c | 34 | ||||
-rw-r--r-- | include/linux/binfmts.h | 2 |
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 | ||
49 | static struct linux_binfmt irix_format = { | 49 | static 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*); | |||
38 | static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); | 38 | static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); |
39 | 39 | ||
40 | static struct linux_binfmt aout32_format = { | 40 | static 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 | ||
45 | static void set_brk(unsigned long start, unsigned long end) | 48 | static void set_brk(unsigned long start, unsigned long end) |
@@ -66,27 +66,15 @@ int suid_dumpable = 0; | |||
66 | EXPORT_SYMBOL(suid_dumpable); | 66 | EXPORT_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 | ||
69 | static struct linux_binfmt *formats; | 69 | static LIST_HEAD(formats); |
70 | static DEFINE_RWLOCK(binfmt_lock); | 70 | static DEFINE_RWLOCK(binfmt_lock); |
71 | 71 | ||
72 | int register_binfmt(struct linux_binfmt * fmt) | 72 | int 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 | ||
96 | int unregister_binfmt(struct linux_binfmt * fmt) | 84 | int 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 | ||
114 | EXPORT_SYMBOL(unregister_binfmt); | 92 | EXPORT_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 | */ |
65 | struct linux_binfmt { | 65 | struct 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 *); |