diff options
-rw-r--r-- | block/elevator.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/block/elevator.c b/block/elevator.c index c2d61d56e0b7..603b2c178740 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -100,14 +100,14 @@ static void elevator_put(struct elevator_type *e) | |||
100 | module_put(e->elevator_owner); | 100 | module_put(e->elevator_owner); |
101 | } | 101 | } |
102 | 102 | ||
103 | static struct elevator_type *elevator_get(const char *name) | 103 | static struct elevator_type *elevator_get(const char *name, bool try_loading) |
104 | { | 104 | { |
105 | struct elevator_type *e; | 105 | struct elevator_type *e; |
106 | 106 | ||
107 | spin_lock(&elv_list_lock); | 107 | spin_lock(&elv_list_lock); |
108 | 108 | ||
109 | e = elevator_find(name); | 109 | e = elevator_find(name); |
110 | if (!e) { | 110 | if (!e && try_loading) { |
111 | spin_unlock(&elv_list_lock); | 111 | spin_unlock(&elv_list_lock); |
112 | request_module("%s-iosched", name); | 112 | request_module("%s-iosched", name); |
113 | spin_lock(&elv_list_lock); | 113 | spin_lock(&elv_list_lock); |
@@ -207,25 +207,30 @@ int elevator_init(struct request_queue *q, char *name) | |||
207 | q->boundary_rq = NULL; | 207 | q->boundary_rq = NULL; |
208 | 208 | ||
209 | if (name) { | 209 | if (name) { |
210 | e = elevator_get(name); | 210 | e = elevator_get(name, true); |
211 | if (!e) | 211 | if (!e) |
212 | return -EINVAL; | 212 | return -EINVAL; |
213 | } | 213 | } |
214 | 214 | ||
215 | /* | ||
216 | * Use the default elevator specified by config boot param or | ||
217 | * config option. Don't try to load modules as we could be running | ||
218 | * off async and request_module() isn't allowed from async. | ||
219 | */ | ||
215 | if (!e && *chosen_elevator) { | 220 | if (!e && *chosen_elevator) { |
216 | e = elevator_get(chosen_elevator); | 221 | e = elevator_get(chosen_elevator, false); |
217 | if (!e) | 222 | if (!e) |
218 | printk(KERN_ERR "I/O scheduler %s not found\n", | 223 | printk(KERN_ERR "I/O scheduler %s not found\n", |
219 | chosen_elevator); | 224 | chosen_elevator); |
220 | } | 225 | } |
221 | 226 | ||
222 | if (!e) { | 227 | if (!e) { |
223 | e = elevator_get(CONFIG_DEFAULT_IOSCHED); | 228 | e = elevator_get(CONFIG_DEFAULT_IOSCHED, false); |
224 | if (!e) { | 229 | if (!e) { |
225 | printk(KERN_ERR | 230 | printk(KERN_ERR |
226 | "Default I/O scheduler not found. " \ | 231 | "Default I/O scheduler not found. " \ |
227 | "Using noop.\n"); | 232 | "Using noop.\n"); |
228 | e = elevator_get("noop"); | 233 | e = elevator_get("noop", false); |
229 | } | 234 | } |
230 | } | 235 | } |
231 | 236 | ||
@@ -967,7 +972,7 @@ int elevator_change(struct request_queue *q, const char *name) | |||
967 | return -ENXIO; | 972 | return -ENXIO; |
968 | 973 | ||
969 | strlcpy(elevator_name, name, sizeof(elevator_name)); | 974 | strlcpy(elevator_name, name, sizeof(elevator_name)); |
970 | e = elevator_get(strstrip(elevator_name)); | 975 | e = elevator_get(strstrip(elevator_name), true); |
971 | if (!e) { | 976 | if (!e) { |
972 | printk(KERN_ERR "elevator: type %s not found\n", elevator_name); | 977 | printk(KERN_ERR "elevator: type %s not found\n", elevator_name); |
973 | return -EINVAL; | 978 | return -EINVAL; |