X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=block%2Felevator.c;h=bafbae0344d319e909e3e7add07467b1c0463a73;hb=4eb166d9874b4917d79ccd14577a60d795a0cb4a;hp=952aee04a68ad7cc240b8ecb7a8a0e1590b9a33f;hpb=fe2520094d88018423dfc42b3cd0015f74e8adea;p=linux-2.6-omap-h63xx.git diff --git a/block/elevator.c b/block/elevator.c index 952aee04a68..bafbae0344d 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -45,7 +45,8 @@ static LIST_HEAD(elv_list); */ static const int elv_hash_shift = 6; #define ELV_HASH_BLOCK(sec) ((sec) >> 3) -#define ELV_HASH_FN(sec) (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift)) +#define ELV_HASH_FN(sec) \ + (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift)) #define ELV_HASH_ENTRIES (1 << elv_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) #define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) @@ -185,9 +186,7 @@ static elevator_t *elevator_alloc(struct request_queue *q, eq->ops = &e->ops; eq->elevator_type = e; - kobject_init(&eq->kobj); - kobject_set_name(&eq->kobj, "%s", "iosched"); - eq->kobj.ktype = &elv_ktype; + kobject_init(&eq->kobj, &elv_ktype); mutex_init(&eq->sysfs_lock); eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, @@ -226,15 +225,27 @@ int elevator_init(struct request_queue *q, char *name) q->end_sector = 0; q->boundary_rq = NULL; - if (name && !(e = elevator_get(name))) - return -EINVAL; + if (name) { + e = elevator_get(name); + if (!e) + return -EINVAL; + } - if (!e && *chosen_elevator && !(e = elevator_get(chosen_elevator))) - printk("I/O scheduler %s not found\n", chosen_elevator); + if (!e && *chosen_elevator) { + e = elevator_get(chosen_elevator); + if (!e) + printk(KERN_ERR "I/O scheduler %s not found\n", + chosen_elevator); + } - if (!e && !(e = elevator_get(CONFIG_DEFAULT_IOSCHED))) { - printk("Default I/O scheduler not found, using no-op\n"); - e = elevator_get("noop"); + if (!e) { + e = elevator_get(CONFIG_DEFAULT_IOSCHED); + if (!e) { + printk(KERN_ERR + "Default I/O scheduler not found. " \ + "Using noop.\n"); + e = elevator_get("noop"); + } } eq = elevator_alloc(q, e); @@ -250,7 +261,6 @@ int elevator_init(struct request_queue *q, char *name) elevator_attach(q, eq, data); return ret; } - EXPORT_SYMBOL(elevator_init); void elevator_exit(elevator_t *e) @@ -263,7 +273,6 @@ void elevator_exit(elevator_t *e) kobject_put(&e->kobj); } - EXPORT_SYMBOL(elevator_exit); static void elv_activate_rq(struct request_queue *q, struct request *rq) @@ -355,7 +364,6 @@ struct request *elv_rb_add(struct rb_root *root, struct request *rq) rb_insert_color(&rq->rb_node, root); return NULL; } - EXPORT_SYMBOL(elv_rb_add); void elv_rb_del(struct rb_root *root, struct request *rq) @@ -364,7 +372,6 @@ void elv_rb_del(struct rb_root *root, struct request *rq) rb_erase(&rq->rb_node, root); RB_CLEAR_NODE(&rq->rb_node); } - EXPORT_SYMBOL(elv_rb_del); struct request *elv_rb_find(struct rb_root *root, sector_t sector) @@ -385,18 +392,18 @@ struct request *elv_rb_find(struct rb_root *root, sector_t sector) return NULL; } - EXPORT_SYMBOL(elv_rb_find); /* * Insert rq into dispatch queue of q. Queue lock must be held on - * entry. rq is sort insted into the dispatch queue. To be used by + * entry. rq is sort instead into the dispatch queue. To be used by * specific elevators. */ void elv_dispatch_sort(struct request_queue *q, struct request *rq) { sector_t boundary; struct list_head *entry; + int stop_flags; if (q->last_merge == rq) q->last_merge = NULL; @@ -406,13 +413,13 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) q->nr_sorted--; boundary = q->end_sector; - + stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED; list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); if (rq_data_dir(rq) != rq_data_dir(pos)) break; - if (pos->cmd_flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) + if (pos->cmd_flags & stop_flags) break; if (rq->sector >= boundary) { if (pos->sector < boundary) @@ -427,7 +434,6 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) list_add(&rq->queuelist, entry); } - EXPORT_SYMBOL(elv_dispatch_sort); /* @@ -448,7 +454,6 @@ void elv_dispatch_add_tail(struct request_queue *q, struct request *rq) q->boundary_rq = rq; list_add_tail(&rq->queuelist, &q->queue_head); } - EXPORT_SYMBOL(elv_dispatch_add_tail); int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) @@ -667,7 +672,8 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where, q->end_sector = rq_end_sector(rq); q->boundary_rq = rq; } - } else if (!(rq->cmd_flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + } else if (!(rq->cmd_flags & REQ_ELVPRIV) && + where == ELEVATOR_INSERT_SORT) where = ELEVATOR_INSERT_BACK; if (plug) @@ -675,7 +681,6 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where, elv_insert(q, rq, where); } - EXPORT_SYMBOL(__elv_add_request); void elv_add_request(struct request_queue *q, struct request *rq, int where, @@ -687,7 +692,6 @@ void elv_add_request(struct request_queue *q, struct request *rq, int where, __elv_add_request(q, rq, where, plug); spin_unlock_irqrestore(q->queue_lock, flags); } - EXPORT_SYMBOL(elv_add_request); static inline struct request *__elv_next_request(struct request_queue *q) @@ -743,7 +747,21 @@ struct request *elv_next_request(struct request_queue *q) q->boundary_rq = NULL; } - if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) + if (rq->cmd_flags & REQ_DONTPREP) + break; + + if (q->dma_drain_size && rq->data_len) { + /* + * make sure space for the drain appears we + * know we can do this because max_hw_segments + * has been adjusted to be one fewer than the + * device can handle + */ + rq->nr_phys_segments++; + rq->nr_hw_segments++; + } + + if (!q->prep_rq_fn) break; ret = q->prep_rq_fn(q, rq); @@ -756,6 +774,16 @@ struct request *elv_next_request(struct request_queue *q) * avoid resource deadlock. REQ_STARTED will * prevent other fs requests from passing this one. */ + if (q->dma_drain_size && rq->data_len && + !(rq->cmd_flags & REQ_DONTPREP)) { + /* + * remove the space for the drain we added + * so that we don't add it again + */ + --rq->nr_phys_segments; + --rq->nr_hw_segments; + } + rq = NULL; break; } else if (ret == BLKPREP_KILL) { @@ -770,7 +798,6 @@ struct request *elv_next_request(struct request_queue *q) return rq; } - EXPORT_SYMBOL(elv_next_request); void elv_dequeue_request(struct request_queue *q, struct request *rq) @@ -788,7 +815,6 @@ void elv_dequeue_request(struct request_queue *q, struct request *rq) if (blk_account_rq(rq)) q->in_flight++; } - EXPORT_SYMBOL(elv_dequeue_request); int elv_queue_empty(struct request_queue *q) @@ -803,7 +829,6 @@ int elv_queue_empty(struct request_queue *q) return 1; } - EXPORT_SYMBOL(elv_queue_empty); struct request *elv_latter_request(struct request_queue *q, struct request *rq) @@ -931,9 +956,7 @@ int elv_register_queue(struct request_queue *q) elevator_t *e = q->elevator; int error; - e->kobj.parent = &q->kobj; - - error = kobject_add(&e->kobj); + error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched"); if (!error) { struct elv_fs_entry *attr = e->elevator_type->elevator_attrs; if (attr) { @@ -960,7 +983,7 @@ void elv_unregister_queue(struct request_queue *q) __elv_unregister_queue(q->elevator); } -int elv_register(struct elevator_type *e) +void elv_register(struct elevator_type *e) { char *def = ""; @@ -974,8 +997,8 @@ int elv_register(struct elevator_type *e) !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED))) def = " (default)"; - printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def); - return 0; + printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, + def); } EXPORT_SYMBOL_GPL(elv_register); @@ -1107,7 +1130,8 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, } if (!elevator_switch(q, e)) - printk(KERN_ERR "elevator: switch to %s failed\n",elevator_name); + printk(KERN_ERR "elevator: switch to %s failed\n", + elevator_name); return count; } @@ -1141,7 +1165,6 @@ struct request *elv_rb_former_request(struct request_queue *q, return NULL; } - EXPORT_SYMBOL(elv_rb_former_request); struct request *elv_rb_latter_request(struct request_queue *q, @@ -1154,5 +1177,4 @@ struct request *elv_rb_latter_request(struct request_queue *q, return NULL; } - EXPORT_SYMBOL(elv_rb_latter_request);