diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-core.c | 31 | ||||
-rw-r--r-- | block/blk-settings.c | 26 | ||||
-rw-r--r-- | block/blk-sysfs.c | 11 | ||||
-rw-r--r-- | block/cfq-iosched.c | 6 | ||||
-rw-r--r-- | block/elevator.c | 11 |
5 files changed, 43 insertions, 42 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index d1a9a0a64f9..36c0deebc2d 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1490,9 +1490,9 @@ end_io: | |||
1490 | /* | 1490 | /* |
1491 | * We only want one ->make_request_fn to be active at a time, | 1491 | * We only want one ->make_request_fn to be active at a time, |
1492 | * else stack usage with stacked devices could be a problem. | 1492 | * else stack usage with stacked devices could be a problem. |
1493 | * So use current->bio_{list,tail} to keep a list of requests | 1493 | * So use current->bio_list to keep a list of requests |
1494 | * submited by a make_request_fn function. | 1494 | * submited by a make_request_fn function. |
1495 | * current->bio_tail is also used as a flag to say if | 1495 | * current->bio_list is also used as a flag to say if |
1496 | * generic_make_request is currently active in this task or not. | 1496 | * generic_make_request is currently active in this task or not. |
1497 | * If it is NULL, then no make_request is active. If it is non-NULL, | 1497 | * If it is NULL, then no make_request is active. If it is non-NULL, |
1498 | * then a make_request is active, and new requests should be added | 1498 | * then a make_request is active, and new requests should be added |
@@ -1500,11 +1500,11 @@ end_io: | |||
1500 | */ | 1500 | */ |
1501 | void generic_make_request(struct bio *bio) | 1501 | void generic_make_request(struct bio *bio) |
1502 | { | 1502 | { |
1503 | if (current->bio_tail) { | 1503 | struct bio_list bio_list_on_stack; |
1504 | |||
1505 | if (current->bio_list) { | ||
1504 | /* make_request is active */ | 1506 | /* make_request is active */ |
1505 | *(current->bio_tail) = bio; | 1507 | bio_list_add(current->bio_list, bio); |
1506 | bio->bi_next = NULL; | ||
1507 | current->bio_tail = &bio->bi_next; | ||
1508 | return; | 1508 | return; |
1509 | } | 1509 | } |
1510 | /* following loop may be a bit non-obvious, and so deserves some | 1510 | /* following loop may be a bit non-obvious, and so deserves some |
@@ -1512,30 +1512,27 @@ void generic_make_request(struct bio *bio) | |||
1512 | * Before entering the loop, bio->bi_next is NULL (as all callers | 1512 | * Before entering the loop, bio->bi_next is NULL (as all callers |
1513 | * ensure that) so we have a list with a single bio. | 1513 | * ensure that) so we have a list with a single bio. |
1514 | * We pretend that we have just taken it off a longer list, so | 1514 | * We pretend that we have just taken it off a longer list, so |
1515 | * we assign bio_list to the next (which is NULL) and bio_tail | 1515 | * we assign bio_list to a pointer to the bio_list_on_stack, |
1516 | * to &bio_list, thus initialising the bio_list of new bios to be | 1516 | * thus initialising the bio_list of new bios to be |
1517 | * added. __generic_make_request may indeed add some more bios | 1517 | * added. __generic_make_request may indeed add some more bios |
1518 | * through a recursive call to generic_make_request. If it | 1518 | * through a recursive call to generic_make_request. If it |
1519 | * did, we find a non-NULL value in bio_list and re-enter the loop | 1519 | * did, we find a non-NULL value in bio_list and re-enter the loop |
1520 | * from the top. In this case we really did just take the bio | 1520 | * from the top. In this case we really did just take the bio |
1521 | * of the top of the list (no pretending) and so fixup bio_list and | 1521 | * of the top of the list (no pretending) and so remove it from |
1522 | * bio_tail or bi_next, and call into __generic_make_request again. | 1522 | * bio_list, and call into __generic_make_request again. |
1523 | * | 1523 | * |
1524 | * The loop was structured like this to make only one call to | 1524 | * The loop was structured like this to make only one call to |
1525 | * __generic_make_request (which is important as it is large and | 1525 | * __generic_make_request (which is important as it is large and |
1526 | * inlined) and to keep the structure simple. | 1526 | * inlined) and to keep the structure simple. |
1527 | */ | 1527 | */ |
1528 | BUG_ON(bio->bi_next); | 1528 | BUG_ON(bio->bi_next); |
1529 | bio_list_init(&bio_list_on_stack); | ||
1530 | current->bio_list = &bio_list_on_stack; | ||
1529 | do { | 1531 | do { |
1530 | current->bio_list = bio->bi_next; | ||
1531 | if (bio->bi_next == NULL) | ||
1532 | current->bio_tail = ¤t->bio_list; | ||
1533 | else | ||
1534 | bio->bi_next = NULL; | ||
1535 | __generic_make_request(bio); | 1532 | __generic_make_request(bio); |
1536 | bio = current->bio_list; | 1533 | bio = bio_list_pop(current->bio_list); |
1537 | } while (bio); | 1534 | } while (bio); |
1538 | current->bio_tail = NULL; /* deactivate */ | 1535 | current->bio_list = NULL; /* deactivate */ |
1539 | } | 1536 | } |
1540 | EXPORT_SYMBOL(generic_make_request); | 1537 | EXPORT_SYMBOL(generic_make_request); |
1541 | 1538 | ||
diff --git a/block/blk-settings.c b/block/blk-settings.c index 5eeb9e0d256..78549c72378 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -507,7 +507,7 @@ static unsigned int lcm(unsigned int a, unsigned int b) | |||
507 | * blk_stack_limits - adjust queue_limits for stacked devices | 507 | * blk_stack_limits - adjust queue_limits for stacked devices |
508 | * @t: the stacking driver limits (top device) | 508 | * @t: the stacking driver limits (top device) |
509 | * @b: the underlying queue limits (bottom, component device) | 509 | * @b: the underlying queue limits (bottom, component device) |
510 | * @offset: offset to beginning of data within component device | 510 | * @start: first data sector within component device |
511 | * | 511 | * |
512 | * Description: | 512 | * Description: |
513 | * This function is used by stacking drivers like MD and DM to ensure | 513 | * This function is used by stacking drivers like MD and DM to ensure |
@@ -525,10 +525,9 @@ static unsigned int lcm(unsigned int a, unsigned int b) | |||
525 | * the alignment_offset is undefined. | 525 | * the alignment_offset is undefined. |
526 | */ | 526 | */ |
527 | int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 527 | int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
528 | sector_t offset) | 528 | sector_t start) |
529 | { | 529 | { |
530 | sector_t alignment; | 530 | unsigned int top, bottom, alignment, ret = 0; |
531 | unsigned int top, bottom, ret = 0; | ||
532 | 531 | ||
533 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); | 532 | t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); |
534 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); | 533 | t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); |
@@ -548,7 +547,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
548 | 547 | ||
549 | t->misaligned |= b->misaligned; | 548 | t->misaligned |= b->misaligned; |
550 | 549 | ||
551 | alignment = queue_limit_alignment_offset(b, offset); | 550 | alignment = queue_limit_alignment_offset(b, start); |
552 | 551 | ||
553 | /* Bottom device has different alignment. Check that it is | 552 | /* Bottom device has different alignment. Check that it is |
554 | * compatible with the current top alignment. | 553 | * compatible with the current top alignment. |
@@ -611,11 +610,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
611 | 610 | ||
612 | /* Discard alignment and granularity */ | 611 | /* Discard alignment and granularity */ |
613 | if (b->discard_granularity) { | 612 | if (b->discard_granularity) { |
614 | unsigned int granularity = b->discard_granularity; | 613 | alignment = queue_limit_discard_alignment(b, start); |
615 | offset &= granularity - 1; | ||
616 | |||
617 | alignment = (granularity + b->discard_alignment - offset) | ||
618 | & (granularity - 1); | ||
619 | 614 | ||
620 | if (t->discard_granularity != 0 && | 615 | if (t->discard_granularity != 0 && |
621 | t->discard_alignment != alignment) { | 616 | t->discard_alignment != alignment) { |
@@ -657,7 +652,7 @@ int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, | |||
657 | 652 | ||
658 | start += get_start_sect(bdev); | 653 | start += get_start_sect(bdev); |
659 | 654 | ||
660 | return blk_stack_limits(t, &bq->limits, start << 9); | 655 | return blk_stack_limits(t, &bq->limits, start); |
661 | } | 656 | } |
662 | EXPORT_SYMBOL(bdev_stack_limits); | 657 | EXPORT_SYMBOL(bdev_stack_limits); |
663 | 658 | ||
@@ -668,9 +663,8 @@ EXPORT_SYMBOL(bdev_stack_limits); | |||
668 | * @offset: offset to beginning of data within component device | 663 | * @offset: offset to beginning of data within component device |
669 | * | 664 | * |
670 | * Description: | 665 | * Description: |
671 | * Merges the limits for two queues. Returns 0 if alignment | 666 | * Merges the limits for a top level gendisk and a bottom level |
672 | * didn't change. Returns -1 if adding the bottom device caused | 667 | * block_device. |
673 | * misalignment. | ||
674 | */ | 668 | */ |
675 | void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | 669 | void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, |
676 | sector_t offset) | 670 | sector_t offset) |
@@ -678,9 +672,7 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
678 | struct request_queue *t = disk->queue; | 672 | struct request_queue *t = disk->queue; |
679 | struct request_queue *b = bdev_get_queue(bdev); | 673 | struct request_queue *b = bdev_get_queue(bdev); |
680 | 674 | ||
681 | offset += get_start_sect(bdev) << 9; | 675 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { |
682 | |||
683 | if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) { | ||
684 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; | 676 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; |
685 | 677 | ||
686 | disk_name(disk, 0, top); | 678 | disk_name(disk, 0, top); |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 8606c9543fd..e85442415db 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -189,7 +189,8 @@ static ssize_t queue_nonrot_store(struct request_queue *q, const char *page, | |||
189 | 189 | ||
190 | static ssize_t queue_nomerges_show(struct request_queue *q, char *page) | 190 | static ssize_t queue_nomerges_show(struct request_queue *q, char *page) |
191 | { | 191 | { |
192 | return queue_var_show(blk_queue_nomerges(q), page); | 192 | return queue_var_show((blk_queue_nomerges(q) << 1) | |
193 | blk_queue_noxmerges(q), page); | ||
193 | } | 194 | } |
194 | 195 | ||
195 | static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, | 196 | static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, |
@@ -199,10 +200,12 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, | |||
199 | ssize_t ret = queue_var_store(&nm, page, count); | 200 | ssize_t ret = queue_var_store(&nm, page, count); |
200 | 201 | ||
201 | spin_lock_irq(q->queue_lock); | 202 | spin_lock_irq(q->queue_lock); |
202 | if (nm) | 203 | queue_flag_clear(QUEUE_FLAG_NOMERGES, q); |
204 | queue_flag_clear(QUEUE_FLAG_NOXMERGES, q); | ||
205 | if (nm == 2) | ||
203 | queue_flag_set(QUEUE_FLAG_NOMERGES, q); | 206 | queue_flag_set(QUEUE_FLAG_NOMERGES, q); |
204 | else | 207 | else if (nm) |
205 | queue_flag_clear(QUEUE_FLAG_NOMERGES, q); | 208 | queue_flag_set(QUEUE_FLAG_NOXMERGES, q); |
206 | spin_unlock_irq(q->queue_lock); | 209 | spin_unlock_irq(q->queue_lock); |
207 | 210 | ||
208 | return ret; | 211 | return ret; |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 023f4e69a33..e3dedfd3bcb 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -115,11 +115,11 @@ struct cfq_queue { | |||
115 | /* time when queue got scheduled in to dispatch first request. */ | 115 | /* time when queue got scheduled in to dispatch first request. */ |
116 | unsigned long dispatch_start; | 116 | unsigned long dispatch_start; |
117 | unsigned int allocated_slice; | 117 | unsigned int allocated_slice; |
118 | unsigned int slice_dispatch; | ||
118 | /* time when first request from queue completed and slice started. */ | 119 | /* time when first request from queue completed and slice started. */ |
119 | unsigned long slice_start; | 120 | unsigned long slice_start; |
120 | unsigned long slice_end; | 121 | unsigned long slice_end; |
121 | long slice_resid; | 122 | long slice_resid; |
122 | unsigned int slice_dispatch; | ||
123 | 123 | ||
124 | /* pending metadata requests */ | 124 | /* pending metadata requests */ |
125 | int meta_pending; | 125 | int meta_pending; |
@@ -130,13 +130,13 @@ struct cfq_queue { | |||
130 | unsigned short ioprio, org_ioprio; | 130 | unsigned short ioprio, org_ioprio; |
131 | unsigned short ioprio_class, org_ioprio_class; | 131 | unsigned short ioprio_class, org_ioprio_class; |
132 | 132 | ||
133 | pid_t pid; | ||
134 | |||
133 | unsigned int seek_samples; | 135 | unsigned int seek_samples; |
134 | u64 seek_total; | 136 | u64 seek_total; |
135 | sector_t seek_mean; | 137 | sector_t seek_mean; |
136 | sector_t last_request_pos; | 138 | sector_t last_request_pos; |
137 | 139 | ||
138 | pid_t pid; | ||
139 | |||
140 | struct cfq_rb_root *service_tree; | 140 | struct cfq_rb_root *service_tree; |
141 | struct cfq_queue *new_cfqq; | 141 | struct cfq_queue *new_cfqq; |
142 | struct cfq_group *cfqg; | 142 | struct cfq_group *cfqg; |
diff --git a/block/elevator.c b/block/elevator.c index 9ad5ccc4c5e..ee3a883840f 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -474,6 +474,15 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) | |||
474 | int ret; | 474 | int ret; |
475 | 475 | ||
476 | /* | 476 | /* |
477 | * Levels of merges: | ||
478 | * nomerges: No merges at all attempted | ||
479 | * noxmerges: Only simple one-hit cache try | ||
480 | * merges: All merge tries attempted | ||
481 | */ | ||
482 | if (blk_queue_nomerges(q)) | ||
483 | return ELEVATOR_NO_MERGE; | ||
484 | |||
485 | /* | ||
477 | * First try one-hit cache. | 486 | * First try one-hit cache. |
478 | */ | 487 | */ |
479 | if (q->last_merge) { | 488 | if (q->last_merge) { |
@@ -484,7 +493,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio) | |||
484 | } | 493 | } |
485 | } | 494 | } |
486 | 495 | ||
487 | if (blk_queue_nomerges(q)) | 496 | if (blk_queue_noxmerges(q)) |
488 | return ELEVATOR_NO_MERGE; | 497 | return ELEVATOR_NO_MERGE; |
489 | 498 | ||
490 | /* | 499 | /* |