Merge branch 'v2.6.36-rc8' into for-2.6.37/barrier
Conflicts: block/blk-core.c drivers/block/loop.c mm/swapfile.c Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
+1
-1
@@ -966,7 +966,7 @@ blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
|
||||
|
||||
/* Currently we do not support hierarchy deeper than two level (0,1) */
|
||||
if (parent != cgroup->top_cgroup)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
|
||||
if (!blkcg)
|
||||
|
||||
+3
-3
@@ -1182,9 +1182,9 @@ static int __make_request(struct request_queue *q, struct bio *bio)
|
||||
int el_ret;
|
||||
unsigned int bytes = bio->bi_size;
|
||||
const unsigned short prio = bio_prio(bio);
|
||||
const bool sync = (bio->bi_rw & REQ_SYNC);
|
||||
const bool unplug = (bio->bi_rw & REQ_UNPLUG);
|
||||
const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
|
||||
const bool sync = !!(bio->bi_rw & REQ_SYNC);
|
||||
const bool unplug = !!(bio->bi_rw & REQ_UNPLUG);
|
||||
const unsigned long ff = bio->bi_rw & REQ_FAILFAST_MASK;
|
||||
int where = ELEVATOR_INSERT_SORT;
|
||||
int rw_flags;
|
||||
|
||||
|
||||
+1
-1
@@ -307,7 +307,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
|
||||
return PTR_ERR(bio);
|
||||
|
||||
if (rq_data_dir(rq) == WRITE)
|
||||
bio->bi_rw |= (1 << REQ_WRITE);
|
||||
bio->bi_rw |= REQ_WRITE;
|
||||
|
||||
if (do_copy)
|
||||
rq->cmd_flags |= REQ_COPY_USER;
|
||||
|
||||
@@ -361,6 +361,18 @@ static int attempt_merge(struct request_queue *q, struct request *req,
|
||||
if (!rq_mergeable(req) || !rq_mergeable(next))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Don't merge file system requests and discard requests
|
||||
*/
|
||||
if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Don't merge discard requests and secure discard requests
|
||||
*/
|
||||
if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* not contiguous
|
||||
*/
|
||||
|
||||
@@ -511,6 +511,7 @@ int blk_register_queue(struct gendisk *disk)
|
||||
kobject_uevent(&q->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&q->kobj);
|
||||
blk_trace_remove_sysfs(disk_to_dev(disk));
|
||||
kobject_put(&dev->kobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -148,14 +148,18 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
|
||||
|
||||
static inline int blk_cpu_to_group(int cpu)
|
||||
{
|
||||
int group = NR_CPUS;
|
||||
#ifdef CONFIG_SCHED_MC
|
||||
const struct cpumask *mask = cpu_coregroup_mask(cpu);
|
||||
return cpumask_first(mask);
|
||||
group = cpumask_first(mask);
|
||||
#elif defined(CONFIG_SCHED_SMT)
|
||||
return cpumask_first(topology_thread_cpumask(cpu));
|
||||
group = cpumask_first(topology_thread_cpumask(cpu));
|
||||
#else
|
||||
return cpu;
|
||||
#endif
|
||||
if (likely(group < NR_CPUS))
|
||||
return group;
|
||||
return cpu;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+101
-18
@@ -30,6 +30,7 @@ static const int cfq_slice_sync = HZ / 10;
|
||||
static int cfq_slice_async = HZ / 25;
|
||||
static const int cfq_slice_async_rq = 2;
|
||||
static int cfq_slice_idle = HZ / 125;
|
||||
static int cfq_group_idle = HZ / 125;
|
||||
static const int cfq_target_latency = HZ * 3/10; /* 300 ms */
|
||||
static const int cfq_hist_divisor = 4;
|
||||
|
||||
@@ -147,6 +148,8 @@ struct cfq_queue {
|
||||
struct cfq_queue *new_cfqq;
|
||||
struct cfq_group *cfqg;
|
||||
struct cfq_group *orig_cfqg;
|
||||
/* Number of sectors dispatched from queue in single dispatch round */
|
||||
unsigned long nr_sectors;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -198,6 +201,8 @@ struct cfq_group {
|
||||
struct hlist_node cfqd_node;
|
||||
atomic_t ref;
|
||||
#endif
|
||||
/* number of requests that are on the dispatch list or inside driver */
|
||||
int dispatched;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -271,6 +276,7 @@ struct cfq_data {
|
||||
unsigned int cfq_slice[2];
|
||||
unsigned int cfq_slice_async_rq;
|
||||
unsigned int cfq_slice_idle;
|
||||
unsigned int cfq_group_idle;
|
||||
unsigned int cfq_latency;
|
||||
unsigned int cfq_group_isolation;
|
||||
|
||||
@@ -378,6 +384,21 @@ CFQ_CFQQ_FNS(wait_busy);
|
||||
&cfqg->service_trees[i][j]: NULL) \
|
||||
|
||||
|
||||
static inline bool iops_mode(struct cfq_data *cfqd)
|
||||
{
|
||||
/*
|
||||
* If we are not idling on queues and it is a NCQ drive, parallel
|
||||
* execution of requests is on and measuring time is not possible
|
||||
* in most of the cases until and unless we drive shallower queue
|
||||
* depths and that becomes a performance bottleneck. In such cases
|
||||
* switch to start providing fairness in terms of number of IOs.
|
||||
*/
|
||||
if (!cfqd->cfq_slice_idle && cfqd->hw_tag)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline enum wl_prio_t cfqq_prio(struct cfq_queue *cfqq)
|
||||
{
|
||||
if (cfq_class_idle(cfqq))
|
||||
@@ -906,7 +927,6 @@ static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq)
|
||||
slice_used = cfqq->allocated_slice;
|
||||
}
|
||||
|
||||
cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u", slice_used);
|
||||
return slice_used;
|
||||
}
|
||||
|
||||
@@ -914,19 +934,21 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
|
||||
struct cfq_queue *cfqq)
|
||||
{
|
||||
struct cfq_rb_root *st = &cfqd->grp_service_tree;
|
||||
unsigned int used_sl, charge_sl;
|
||||
unsigned int used_sl, charge;
|
||||
int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg)
|
||||
- cfqg->service_tree_idle.count;
|
||||
|
||||
BUG_ON(nr_sync < 0);
|
||||
used_sl = charge_sl = cfq_cfqq_slice_usage(cfqq);
|
||||
used_sl = charge = cfq_cfqq_slice_usage(cfqq);
|
||||
|
||||
if (!cfq_cfqq_sync(cfqq) && !nr_sync)
|
||||
charge_sl = cfqq->allocated_slice;
|
||||
if (iops_mode(cfqd))
|
||||
charge = cfqq->slice_dispatch;
|
||||
else if (!cfq_cfqq_sync(cfqq) && !nr_sync)
|
||||
charge = cfqq->allocated_slice;
|
||||
|
||||
/* Can't update vdisktime while group is on service tree */
|
||||
cfq_rb_erase(&cfqg->rb_node, st);
|
||||
cfqg->vdisktime += cfq_scale_slice(charge_sl, cfqg);
|
||||
cfqg->vdisktime += cfq_scale_slice(charge, cfqg);
|
||||
__cfq_group_service_tree_add(st, cfqg);
|
||||
|
||||
/* This group is being expired. Save the context */
|
||||
@@ -940,6 +962,9 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg,
|
||||
|
||||
cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime,
|
||||
st->min_vdisktime);
|
||||
cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u"
|
||||
" sect=%u", used_sl, cfqq->slice_dispatch, charge,
|
||||
iops_mode(cfqd), cfqq->nr_sectors);
|
||||
cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl);
|
||||
cfq_blkiocg_set_start_empty_time(&cfqg->blkg);
|
||||
}
|
||||
@@ -994,10 +1019,20 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
|
||||
*/
|
||||
atomic_set(&cfqg->ref, 1);
|
||||
|
||||
/* Add group onto cgroup list */
|
||||
sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
|
||||
cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
|
||||
/*
|
||||
* Add group onto cgroup list. It might happen that bdi->dev is
|
||||
* not initiliazed yet. Initialize this new group without major
|
||||
* and minor info and this info will be filled in once a new thread
|
||||
* comes for IO. See code above.
|
||||
*/
|
||||
if (bdi->dev) {
|
||||
sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
|
||||
cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
|
||||
MKDEV(major, minor));
|
||||
} else
|
||||
cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
|
||||
0);
|
||||
|
||||
cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev);
|
||||
|
||||
/* Add group on cfqd list */
|
||||
@@ -1587,6 +1622,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
|
||||
cfqq->allocated_slice = 0;
|
||||
cfqq->slice_end = 0;
|
||||
cfqq->slice_dispatch = 0;
|
||||
cfqq->nr_sectors = 0;
|
||||
|
||||
cfq_clear_cfqq_wait_request(cfqq);
|
||||
cfq_clear_cfqq_must_dispatch(cfqq);
|
||||
@@ -1839,6 +1875,9 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
|
||||
BUG_ON(!service_tree);
|
||||
BUG_ON(!service_tree->count);
|
||||
|
||||
if (!cfqd->cfq_slice_idle)
|
||||
return false;
|
||||
|
||||
/* We never do for idle class queues. */
|
||||
if (prio == IDLE_WORKLOAD)
|
||||
return false;
|
||||
@@ -1863,7 +1902,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
{
|
||||
struct cfq_queue *cfqq = cfqd->active_queue;
|
||||
struct cfq_io_context *cic;
|
||||
unsigned long sl;
|
||||
unsigned long sl, group_idle = 0;
|
||||
|
||||
/*
|
||||
* SSD device without seek penalty, disable idling. But only do so
|
||||
@@ -1879,8 +1918,13 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
/*
|
||||
* idle is disabled, either manually or by past process history
|
||||
*/
|
||||
if (!cfqd->cfq_slice_idle || !cfq_should_idle(cfqd, cfqq))
|
||||
return;
|
||||
if (!cfq_should_idle(cfqd, cfqq)) {
|
||||
/* no queue idling. Check for group idling */
|
||||
if (cfqd->cfq_group_idle)
|
||||
group_idle = cfqd->cfq_group_idle;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* still active requests from this queue, don't idle
|
||||
@@ -1907,13 +1951,21 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
|
||||
return;
|
||||
}
|
||||
|
||||
/* There are other queues in the group, don't do group idle */
|
||||
if (group_idle && cfqq->cfqg->nr_cfqq > 1)
|
||||
return;
|
||||
|
||||
cfq_mark_cfqq_wait_request(cfqq);
|
||||
|
||||
sl = cfqd->cfq_slice_idle;
|
||||
if (group_idle)
|
||||
sl = cfqd->cfq_group_idle;
|
||||
else
|
||||
sl = cfqd->cfq_slice_idle;
|
||||
|
||||
mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
|
||||
cfq_blkiocg_update_set_idle_time_stats(&cfqq->cfqg->blkg);
|
||||
cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl);
|
||||
cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu group_idle: %d", sl,
|
||||
group_idle ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1929,9 +1981,11 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
|
||||
cfqq->next_rq = cfq_find_next_rq(cfqd, cfqq, rq);
|
||||
cfq_remove_request(rq);
|
||||
cfqq->dispatched++;
|
||||
(RQ_CFQG(rq))->dispatched++;
|
||||
elv_dispatch_sort(q, rq);
|
||||
|
||||
cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++;
|
||||
cfqq->nr_sectors += blk_rq_sectors(rq);
|
||||
cfq_blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq),
|
||||
rq_data_dir(rq), rq_is_sync(rq));
|
||||
}
|
||||
@@ -2198,7 +2252,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
|
||||
cfqq = NULL;
|
||||
goto keep_queue;
|
||||
} else
|
||||
goto expire;
|
||||
goto check_group_idle;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2226,8 +2280,23 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
|
||||
* flight or is idling for a new request, allow either of these
|
||||
* conditions to happen (or time out) before selecting a new queue.
|
||||
*/
|
||||
if (timer_pending(&cfqd->idle_slice_timer) ||
|
||||
(cfqq->dispatched && cfq_should_idle(cfqd, cfqq))) {
|
||||
if (timer_pending(&cfqd->idle_slice_timer)) {
|
||||
cfqq = NULL;
|
||||
goto keep_queue;
|
||||
}
|
||||
|
||||
if (cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) {
|
||||
cfqq = NULL;
|
||||
goto keep_queue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If group idle is enabled and there are requests dispatched from
|
||||
* this group, wait for requests to complete.
|
||||
*/
|
||||
check_group_idle:
|
||||
if (cfqd->cfq_group_idle && cfqq->cfqg->nr_cfqq == 1
|
||||
&& cfqq->cfqg->dispatched) {
|
||||
cfqq = NULL;
|
||||
goto keep_queue;
|
||||
}
|
||||
@@ -3375,6 +3444,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
|
||||
WARN_ON(!cfqq->dispatched);
|
||||
cfqd->rq_in_driver--;
|
||||
cfqq->dispatched--;
|
||||
(RQ_CFQG(rq))->dispatched--;
|
||||
cfq_blkiocg_update_completion_stats(&cfqq->cfqg->blkg,
|
||||
rq_start_time_ns(rq), rq_io_start_time_ns(rq),
|
||||
rq_data_dir(rq), rq_is_sync(rq));
|
||||
@@ -3404,7 +3474,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
|
||||
* the queue.
|
||||
*/
|
||||
if (cfq_should_wait_busy(cfqd, cfqq)) {
|
||||
cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
|
||||
unsigned long extend_sl = cfqd->cfq_slice_idle;
|
||||
if (!cfqd->cfq_slice_idle)
|
||||
extend_sl = cfqd->cfq_group_idle;
|
||||
cfqq->slice_end = jiffies + extend_sl;
|
||||
cfq_mark_cfqq_wait_busy(cfqq);
|
||||
cfq_log_cfqq(cfqd, cfqq, "will busy wait");
|
||||
}
|
||||
@@ -3850,6 +3923,7 @@ static void *cfq_init_queue(struct request_queue *q)
|
||||
cfqd->cfq_slice[1] = cfq_slice_sync;
|
||||
cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
|
||||
cfqd->cfq_slice_idle = cfq_slice_idle;
|
||||
cfqd->cfq_group_idle = cfq_group_idle;
|
||||
cfqd->cfq_latency = 1;
|
||||
cfqd->cfq_group_isolation = 0;
|
||||
cfqd->hw_tag = -1;
|
||||
@@ -3922,6 +3996,7 @@ SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1);
|
||||
SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0);
|
||||
SHOW_FUNCTION(cfq_back_seek_penalty_show, cfqd->cfq_back_penalty, 0);
|
||||
SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
|
||||
SHOW_FUNCTION(cfq_group_idle_show, cfqd->cfq_group_idle, 1);
|
||||
SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
|
||||
SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
|
||||
SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
|
||||
@@ -3954,6 +4029,7 @@ STORE_FUNCTION(cfq_back_seek_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0);
|
||||
STORE_FUNCTION(cfq_back_seek_penalty_store, &cfqd->cfq_back_penalty, 1,
|
||||
UINT_MAX, 0);
|
||||
STORE_FUNCTION(cfq_slice_idle_store, &cfqd->cfq_slice_idle, 0, UINT_MAX, 1);
|
||||
STORE_FUNCTION(cfq_group_idle_store, &cfqd->cfq_group_idle, 0, UINT_MAX, 1);
|
||||
STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
|
||||
STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
|
||||
STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
|
||||
@@ -3975,6 +4051,7 @@ static struct elv_fs_entry cfq_attrs[] = {
|
||||
CFQ_ATTR(slice_async),
|
||||
CFQ_ATTR(slice_async_rq),
|
||||
CFQ_ATTR(slice_idle),
|
||||
CFQ_ATTR(group_idle),
|
||||
CFQ_ATTR(low_latency),
|
||||
CFQ_ATTR(group_isolation),
|
||||
__ATTR_NULL
|
||||
@@ -4028,6 +4105,12 @@ static int __init cfq_init(void)
|
||||
if (!cfq_slice_idle)
|
||||
cfq_slice_idle = 1;
|
||||
|
||||
#ifdef CONFIG_CFQ_GROUP_IOSCHED
|
||||
if (!cfq_group_idle)
|
||||
cfq_group_idle = 1;
|
||||
#else
|
||||
cfq_group_idle = 0;
|
||||
#endif
|
||||
if (cfq_slab_setup())
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
+37
-15
@@ -877,6 +877,7 @@ int elv_register_queue(struct request_queue *q)
|
||||
}
|
||||
}
|
||||
kobject_uevent(&e->kobj, KOBJ_ADD);
|
||||
e->registered = 1;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@@ -886,6 +887,7 @@ static void __elv_unregister_queue(struct elevator_queue *e)
|
||||
{
|
||||
kobject_uevent(&e->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&e->kobj);
|
||||
e->registered = 0;
|
||||
}
|
||||
|
||||
void elv_unregister_queue(struct request_queue *q)
|
||||
@@ -948,18 +950,19 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
||||
{
|
||||
struct elevator_queue *old_elevator, *e;
|
||||
void *data;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Allocate new elevator
|
||||
*/
|
||||
e = elevator_alloc(q, new_e);
|
||||
if (!e)
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
|
||||
data = elevator_init_queue(q, e);
|
||||
if (!data) {
|
||||
kobject_put(&e->kobj);
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -980,10 +983,13 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
||||
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
__elv_unregister_queue(old_elevator);
|
||||
if (old_elevator->registered) {
|
||||
__elv_unregister_queue(old_elevator);
|
||||
|
||||
if (elv_register_queue(q))
|
||||
goto fail_register;
|
||||
err = elv_register_queue(q);
|
||||
if (err)
|
||||
goto fail_register;
|
||||
}
|
||||
|
||||
/*
|
||||
* finally exit old elevator and turn off BYPASS.
|
||||
@@ -995,7 +1001,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
||||
|
||||
blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
fail_register:
|
||||
/*
|
||||
@@ -1010,17 +1016,19 @@ fail_register:
|
||||
queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
ssize_t elv_iosched_store(struct request_queue *q, const char *name,
|
||||
size_t count)
|
||||
/*
|
||||
* Switch this queue to the given IO scheduler.
|
||||
*/
|
||||
int elevator_change(struct request_queue *q, const char *name)
|
||||
{
|
||||
char elevator_name[ELV_NAME_MAX];
|
||||
struct elevator_type *e;
|
||||
|
||||
if (!q->elevator)
|
||||
return count;
|
||||
return -ENXIO;
|
||||
|
||||
strlcpy(elevator_name, name, sizeof(elevator_name));
|
||||
e = elevator_get(strstrip(elevator_name));
|
||||
@@ -1031,13 +1039,27 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
|
||||
|
||||
if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
|
||||
elevator_put(e);
|
||||
return count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!elevator_switch(q, e))
|
||||
printk(KERN_ERR "elevator: switch to %s failed\n",
|
||||
elevator_name);
|
||||
return count;
|
||||
return elevator_switch(q, e);
|
||||
}
|
||||
EXPORT_SYMBOL(elevator_change);
|
||||
|
||||
ssize_t elv_iosched_store(struct request_queue *q, const char *name,
|
||||
size_t count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!q->elevator)
|
||||
return count;
|
||||
|
||||
ret = elevator_change(q, name);
|
||||
if (!ret)
|
||||
return count;
|
||||
|
||||
printk(KERN_ERR "elevator: switch to %s failed\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t elv_iosched_show(struct request_queue *q, char *name)
|
||||
|
||||
Reference in New Issue
Block a user