diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2013-12-17 08:41:49 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-12-17 08:41:49 -0500 |
commit | c03aae7f627d83b2fa80550671947002515f10fc (patch) | |
tree | 4e3f0a8aa66b68ac0a279271cdc716765ca1cbda /block | |
parent | 67a8032136484766fb109303006b4a2a20ce8abf (diff) | |
parent | 184c20bbc978eb7a2e1d3637b7864208822c7ebc (diff) |
Merge tag 'v3.10.23' into v3.10-rt
This is the 3.10.23 stable release
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 10 | ||||
-rw-r--r-- | block/elevator.c | 22 |
2 files changed, 29 insertions, 3 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 630d55f9069c..a1eeb262b566 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -741,9 +741,17 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, q->sg_reserved_size = INT_MAX; + /* Protect q->elevator from elevator_change */ + mutex_lock(&q->sysfs_lock); + /* init elevator */ - if (elevator_init(q, NULL)) + if (elevator_init(q, NULL)) { + mutex_unlock(&q->sysfs_lock); return NULL; + } + + mutex_unlock(&q->sysfs_lock); + return q; } EXPORT_SYMBOL(blk_init_allocated_queue); diff --git a/block/elevator.c b/block/elevator.c index 668394d18588..6d765f7e2b2b 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -186,6 +186,12 @@ int elevator_init(struct request_queue *q, char *name) struct elevator_type *e = NULL; int err; + /* + * q->sysfs_lock must be held to provide mutual exclusion between + * elevator_switch() and here. + */ + lockdep_assert_held(&q->sysfs_lock); + if (unlikely(q->elevator)) return 0; @@ -959,7 +965,7 @@ fail_init: /* * Switch this queue to the given IO scheduler. */ -int elevator_change(struct request_queue *q, const char *name) +static int __elevator_change(struct request_queue *q, const char *name) { char elevator_name[ELV_NAME_MAX]; struct elevator_type *e; @@ -981,6 +987,18 @@ int elevator_change(struct request_queue *q, const char *name) return elevator_switch(q, e); } + +int elevator_change(struct request_queue *q, const char *name) +{ + int ret; + + /* Protect q->elevator from elevator_init() */ + mutex_lock(&q->sysfs_lock); + ret = __elevator_change(q, name); + mutex_unlock(&q->sysfs_lock); + + return ret; +} EXPORT_SYMBOL(elevator_change); ssize_t elv_iosched_store(struct request_queue *q, const char *name, @@ -991,7 +1009,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, if (!q->elevator) return count; - ret = elevator_change(q, name); + ret = __elevator_change(q, name); if (!ret) return count; |