X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=block%2Fll_rw_blk.c;h=3d0422f48453c0019ad8d1de25eaa4643bb379fe;hb=444ad82bc3eaa554be40d22dc248e58aeefd54d9;hp=56f2646612e604c2599b3ba8589f99adbf752fcb;hpb=434a25d422db13729da14637325875dc64c05faf;p=linux-2.6 diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 56f2646612..3d0422f484 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -759,6 +759,30 @@ void blk_queue_dma_alignment(struct request_queue *q, int mask) EXPORT_SYMBOL(blk_queue_dma_alignment); +/** + * blk_queue_update_dma_alignment - update dma length and memory alignment + * @q: the request queue for the device + * @mask: alignment mask + * + * description: + * update required memory and length aligment for direct dma transactions. + * If the requested alignment is larger than the current alignment, then + * the current queue alignment is updated to the new value, otherwise it + * is left alone. The design of this is to allow multiple objects + * (driver, device, transport etc) to set their respective + * alignments without having them interfere. + * + **/ +void blk_queue_update_dma_alignment(struct request_queue *q, int mask) +{ + BUG_ON(mask > PAGE_SIZE); + + if (mask > q->dma_alignment) + q->dma_alignment = mask; +} + +EXPORT_SYMBOL(blk_queue_update_dma_alignment); + /** * blk_queue_find_tag - find a request by its tag and queue * @q: The request queue for the device @@ -1143,22 +1167,9 @@ EXPORT_SYMBOL(blk_queue_start_tag); void blk_queue_invalidate_tags(struct request_queue *q) { struct list_head *tmp, *n; - struct request *rq; - list_for_each_safe(tmp, n, &q->tag_busy_list) { - rq = list_entry_rq(tmp); - - if (rq->tag == -1) { - printk(KERN_ERR - "%s: bad tag found on list\n", __FUNCTION__); - list_del_init(&rq->queuelist); - rq->cmd_flags &= ~REQ_QUEUED; - } else - blk_queue_end_tag(q, rq); - - rq->cmd_flags &= ~REQ_STARTED; - __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0); - } + list_for_each_safe(tmp, n, &q->tag_busy_list) + blk_requeue_request(q, list_entry_rq(tmp)); } EXPORT_SYMBOL(blk_queue_invalidate_tags); @@ -1369,7 +1380,7 @@ new_segment: } /* segments in rq */ if (sg) - __sg_mark_end(sg); + sg_mark_end(sg); return nsegs; } @@ -1634,15 +1645,7 @@ static void blk_backing_dev_unplug(struct backing_dev_info *bdi, { struct request_queue *q = bdi->unplug_io_data; - /* - * devices don't necessarily have an ->unplug_fn defined - */ - if (q->unplug_fn) { - blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL, - q->rq.count[READ] + q->rq.count[WRITE]); - - q->unplug_fn(q); - } + blk_unplug(q); } static void blk_unplug_work(struct work_struct *work) @@ -1666,6 +1669,20 @@ static void blk_unplug_timeout(unsigned long data) kblockd_schedule_work(&q->unplug_work); } +void blk_unplug(struct request_queue *q) +{ + /* + * devices don't necessarily have an ->unplug_fn defined + */ + if (q->unplug_fn) { + blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL, + q->rq.count[READ] + q->rq.count[WRITE]); + + q->unplug_fn(q); + } +} +EXPORT_SYMBOL(blk_unplug); + /** * blk_start_queue - restart a previously stopped queue * @q: The &struct request_queue in question @@ -1869,9 +1886,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) init_timer(&q->unplug_timer); - kobject_set_name(&q->kobj, "%s", "queue"); - q->kobj.ktype = &queue_ktype; - kobject_init(&q->kobj); + kobject_init(&q->kobj, &queue_ktype); mutex_init(&q->sysfs_lock); @@ -3221,6 +3236,7 @@ static inline void __generic_make_request(struct bio *bio) sector_t old_sector; int ret, nr_sectors = bio_sectors(bio); dev_t old_dev; + int err = -EIO; might_sleep(); @@ -3248,7 +3264,7 @@ static inline void __generic_make_request(struct bio *bio) bdevname(bio->bi_bdev, b), (long long) bio->bi_sector); end_io: - bio_endio(bio, -EIO); + bio_endio(bio, err); break; } @@ -3283,6 +3299,10 @@ end_io: if (bio_check_eod(bio, nr_sectors)) goto end_io; + if (bio_empty_barrier(bio) && !q->prepare_flush_fn) { + err = -EOPNOTSUPP; + goto end_io; + } ret = q->make_request_fn(q, bio); } while (ret); @@ -4082,23 +4102,7 @@ static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page) return queue_var_show(max_hw_sectors_kb, (page)); } -static ssize_t queue_max_segments_show(struct request_queue *q, char *page) -{ - return queue_var_show(q->max_phys_segments, page); -} - -static ssize_t queue_max_segments_store(struct request_queue *q, - const char *page, size_t count) -{ - unsigned long segments; - ssize_t ret = queue_var_store(&segments, page, count); - - spin_lock_irq(q->queue_lock); - q->max_phys_segments = segments; - spin_unlock_irq(q->queue_lock); - return ret; -} static struct queue_sysfs_entry queue_requests_entry = { .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, .show = queue_requests_show, @@ -4122,12 +4126,6 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = { .show = queue_max_hw_sectors_show, }; -static struct queue_sysfs_entry queue_max_segments_entry = { - .attr = {.name = "max_segments", .mode = S_IRUGO | S_IWUSR }, - .show = queue_max_segments_show, - .store = queue_max_segments_store, -}; - static struct queue_sysfs_entry queue_iosched_entry = { .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, .show = elv_iosched_show, @@ -4139,7 +4137,6 @@ static struct attribute *default_attrs[] = { &queue_ra_entry.attr, &queue_max_hw_sectors_entry.attr, &queue_max_sectors_entry.attr, - &queue_max_segments_entry.attr, &queue_iosched_entry.attr, NULL, }; @@ -4207,9 +4204,8 @@ int blk_register_queue(struct gendisk *disk) if (!q || !q->request_fn) return -ENXIO; - q->kobj.parent = kobject_get(&disk->kobj); - - ret = kobject_add(&q->kobj); + ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj), + "%s", "queue"); if (ret < 0) return ret; @@ -4234,6 +4230,6 @@ void blk_unregister_queue(struct gendisk *disk) kobject_uevent(&q->kobj, KOBJ_REMOVE); kobject_del(&q->kobj); - kobject_put(&disk->kobj); + kobject_put(&disk->dev.kobj); } }