diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
commit | fa251f89903d73989e2f63e13d0eaed1e07ce0da (patch) | |
tree | 3f7fe779941e3b6d67754dd7c44a32f48ea47c74 /block/elevator.c | |
parent | dd3932eddf428571762596e17b65f5dc92ca361b (diff) | |
parent | cd07202cc8262e1669edff0d97715f3dd9260917 (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.c | 52 |
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 | ||
891 | void elv_unregister_queue(struct request_queue *q) | 893 | 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) | |||
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 | ||
1000 | fail_register: | 1006 | fail_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 | ||
1016 | ssize_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 | */ | ||
1025 | int 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); | 1047 | EXPORT_SYMBOL(elevator_change); |
1040 | return count; | 1048 | |
1049 | ssize_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 | ||
1043 | ssize_t elv_iosched_show(struct request_queue *q, char *name) | 1065 | ssize_t elv_iosched_show(struct request_queue *q, char *name) |