aboutsummaryrefslogtreecommitdiffstats
path: root/block/elevator.c
diff options
context:
space:
mode:
authorJens Axboe <jaxboe@fusionio.com>2010-10-19 03:13:04 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-10-19 03:13:04 -0400
commitfa251f89903d73989e2f63e13d0eaed1e07ce0da (patch)
tree3f7fe779941e3b6d67754dd7c44a32f48ea47c74 /block/elevator.c
parentdd3932eddf428571762596e17b65f5dc92ca361b (diff)
parentcd07202cc8262e1669edff0d97715f3dd9260917 (diff)
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>
Diffstat (limited to 'block/elevator.c')
-rw-r--r--block/elevator.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/block/elevator.c b/block/elevator.c
index 241c69c45c5f..282e8308f7e2 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -877,6 +877,7 @@ int elv_register_queue(struct request_queue *q)
877 } 877 }
878 } 878 }
879 kobject_uevent(&e->kobj, KOBJ_ADD); 879 kobject_uevent(&e->kobj, KOBJ_ADD);
880 e->registered = 1;
880 } 881 }
881 return error; 882 return error;
882} 883}
@@ -886,6 +887,7 @@ static void __elv_unregister_queue(struct elevator_queue *e)
886{ 887{
887 kobject_uevent(&e->kobj, KOBJ_REMOVE); 888 kobject_uevent(&e->kobj, KOBJ_REMOVE);
888 kobject_del(&e->kobj); 889 kobject_del(&e->kobj);
890 e->registered = 0;
889} 891}
890 892
891void elv_unregister_queue(struct request_queue *q) 893void elv_unregister_queue(struct request_queue *q)
@@ -948,18 +950,19 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
948{ 950{
949 struct elevator_queue *old_elevator, *e; 951 struct elevator_queue *old_elevator, *e;
950 void *data; 952 void *data;
953 int err;
951 954
952 /* 955 /*
953 * Allocate new elevator 956 * Allocate new elevator
954 */ 957 */
955 e = elevator_alloc(q, new_e); 958 e = elevator_alloc(q, new_e);
956 if (!e) 959 if (!e)
957 return 0; 960 return -ENOMEM;
958 961
959 data = elevator_init_queue(q, e); 962 data = elevator_init_queue(q, e);
960 if (!data) { 963 if (!data) {
961 kobject_put(&e->kobj); 964 kobject_put(&e->kobj);
962 return 0; 965 return -ENOMEM;
963 } 966 }
964 967
965 /* 968 /*
@@ -980,10 +983,13 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
980 983
981 spin_unlock_irq(q->queue_lock); 984 spin_unlock_irq(q->queue_lock);
982 985
983 __elv_unregister_queue(old_elevator); 986 if (old_elevator->registered) {
987 __elv_unregister_queue(old_elevator);
984 988
985 if (elv_register_queue(q)) 989 err = elv_register_queue(q);
986 goto fail_register; 990 if (err)
991 goto fail_register;
992 }
987 993
988 /* 994 /*
989 * finally exit old elevator and turn off BYPASS. 995 * 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)
995 1001
996 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); 1002 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
997 1003
998 return 1; 1004 return 0;
999 1005
1000fail_register: 1006fail_register:
1001 /* 1007 /*
@@ -1010,17 +1016,19 @@ fail_register:
1010 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); 1016 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
1011 spin_unlock_irq(q->queue_lock); 1017 spin_unlock_irq(q->queue_lock);
1012 1018
1013 return 0; 1019 return err;
1014} 1020}
1015 1021
1016ssize_t elv_iosched_store(struct request_queue *q, const char *name, 1022/*
1017 size_t count) 1023 * Switch this queue to the given IO scheduler.
1024 */
1025int elevator_change(struct request_queue *q, const char *name)
1018{ 1026{
1019 char elevator_name[ELV_NAME_MAX]; 1027 char elevator_name[ELV_NAME_MAX];
1020 struct elevator_type *e; 1028 struct elevator_type *e;
1021 1029
1022 if (!q->elevator) 1030 if (!q->elevator)
1023 return count; 1031 return -ENXIO;
1024 1032
1025 strlcpy(elevator_name, name, sizeof(elevator_name)); 1033 strlcpy(elevator_name, name, sizeof(elevator_name));
1026 e = elevator_get(strstrip(elevator_name)); 1034 e = elevator_get(strstrip(elevator_name));
@@ -1031,13 +1039,27 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
1031 1039
1032 if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) { 1040 if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
1033 elevator_put(e); 1041 elevator_put(e);
1034 return count; 1042 return 0;
1035 } 1043 }
1036 1044
1037 if (!elevator_switch(q, e)) 1045 return elevator_switch(q, e);
1038 printk(KERN_ERR "elevator: switch to %s failed\n", 1046}
1039 elevator_name); 1047EXPORT_SYMBOL(elevator_change);
1040 return count; 1048
1049ssize_t elv_iosched_store(struct request_queue *q, const char *name,
1050 size_t count)
1051{
1052 int ret;
1053
1054 if (!q->elevator)
1055 return count;
1056
1057 ret = elevator_change(q, name);
1058 if (!ret)
1059 return count;
1060
1061 printk(KERN_ERR "elevator: switch to %s failed\n", name);
1062 return ret;
1041} 1063}
1042 1064
1043ssize_t elv_iosched_show(struct request_queue *q, char *name) 1065ssize_t elv_iosched_show(struct request_queue *q, char *name)