X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=block%2Felevator.c;h=8cd5775acd7a2d4c1111acb0f823a57a46819dc0;hb=dff244af014144e4ac87dfc5b6e450dc8832710e;hp=c6d153de9fd68ba33fcfb9cc65c00deb35623e8b;hpb=b2e961eb2e7a54ffaae82f8e0198b26b54ade98e;p=linux-2.6-omap-h63xx.git diff --git a/block/elevator.c b/block/elevator.c index c6d153de9fd..8cd5775acd7 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -185,9 +185,7 @@ static elevator_t *elevator_alloc(struct request_queue *q, eq->ops = &e->ops; eq->elevator_type = e; - kobject_init(&eq->kobj); - snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%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, @@ -390,7 +388,7 @@ 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) @@ -712,6 +710,14 @@ struct request *elv_next_request(struct request_queue *q) int ret; while ((rq = __elv_next_request(q)) != NULL) { + /* + * Kill the empty barrier place holder, the driver must + * not ever see it. + */ + if (blk_empty_barrier(rq)) { + end_queued_request(rq, 1); + continue; + } if (!(rq->cmd_flags & REQ_STARTED)) { /* * This is the first time the device driver @@ -735,7 +741,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); @@ -748,18 +768,21 @@ 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) { - int nr_bytes = rq->hard_nr_sectors << 9; - - if (!nr_bytes) - nr_bytes = rq->data_len; - - blkdev_dequeue_request(rq); rq->cmd_flags |= REQ_QUIET; - end_that_request_chunk(rq, 0, nr_bytes); - end_that_request_last(rq, 0); + end_queued_request(rq, 0); } else { printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__, ret); @@ -930,9 +953,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) { @@ -959,7 +980,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,7 +995,6 @@ int elv_register(struct elevator_type *e) def = " (default)"; printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def); - return 0; } EXPORT_SYMBOL_GPL(elv_register);