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 /fs | |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exec.c | 34 |
1 files changed, 6 insertions, 28 deletions
@@ -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; |