diff options
author | Tomoki Sekiyama <tomoki.sekiyama@hds.com> | 2013-10-15 18:42:19 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-11-08 11:00:13 -0500 |
commit | 7c8a3679e3d8e9d92d58f282161760a0e247df97 (patch) | |
tree | 220802e0b80df5b3191359cf09effcfae84718a5 | |
parent | eb1c160b22655fd4ec44be732d6594fd1b1e44f4 (diff) |
elevator: acquire q->sysfs_lock in elevator_change()
Add locking of q->sysfs_lock into elevator_change() (an exported function)
to ensure it is held to protect q->elevator from elevator_init(), even if
elevator_change() is called from non-sysfs paths.
sysfs path (elv_iosched_store) uses __elevator_change(), non-locking
version, as the lock is already taken by elv_iosched_store().
Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | block/elevator.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/block/elevator.c b/block/elevator.c index 249cc5e10906..b7ff2861b6bd 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -965,7 +965,7 @@ fail_init: | |||
965 | /* | 965 | /* |
966 | * Switch this queue to the given IO scheduler. | 966 | * Switch this queue to the given IO scheduler. |
967 | */ | 967 | */ |
968 | int elevator_change(struct request_queue *q, const char *name) | 968 | static int __elevator_change(struct request_queue *q, const char *name) |
969 | { | 969 | { |
970 | char elevator_name[ELV_NAME_MAX]; | 970 | char elevator_name[ELV_NAME_MAX]; |
971 | struct elevator_type *e; | 971 | struct elevator_type *e; |
@@ -987,6 +987,18 @@ int elevator_change(struct request_queue *q, const char *name) | |||
987 | 987 | ||
988 | return elevator_switch(q, e); | 988 | return elevator_switch(q, e); |
989 | } | 989 | } |
990 | |||
991 | int elevator_change(struct request_queue *q, const char *name) | ||
992 | { | ||
993 | int ret; | ||
994 | |||
995 | /* Protect q->elevator from elevator_init() */ | ||
996 | mutex_lock(&q->sysfs_lock); | ||
997 | ret = __elevator_change(q, name); | ||
998 | mutex_unlock(&q->sysfs_lock); | ||
999 | |||
1000 | return ret; | ||
1001 | } | ||
990 | EXPORT_SYMBOL(elevator_change); | 1002 | EXPORT_SYMBOL(elevator_change); |
991 | 1003 | ||
992 | ssize_t elv_iosched_store(struct request_queue *q, const char *name, | 1004 | ssize_t elv_iosched_store(struct request_queue *q, const char *name, |
@@ -997,7 +1009,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, | |||
997 | if (!q->elevator) | 1009 | if (!q->elevator) |
998 | return count; | 1010 | return count; |
999 | 1011 | ||
1000 | ret = elevator_change(q, name); | 1012 | ret = __elevator_change(q, name); |
1001 | if (!ret) | 1013 | if (!ret) |
1002 | return count; | 1014 | return count; |
1003 | 1015 | ||