diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:55:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:55:15 -0400 |
commit | 355bbd8cb82e60a592f6cd86ce6dbe5677615cf4 (patch) | |
tree | 23678e50ad4687f1656edc972388ee8014e7b89d | |
parent | 39695224bd84dc4be29abad93a0ec232a16fc519 (diff) | |
parent | 746cd1e7e4a555ddaee53b19a46e05c9c61eaf09 (diff) |
Merge branch 'for-2.6.32' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.32' of git://git.kernel.dk/linux-2.6-block: (29 commits)
block: use blkdev_issue_discard in blk_ioctl_discard
Make DISCARD_BARRIER and DISCARD_NOBARRIER writes instead of reads
block: don't assume device has a request list backing in nr_requests store
block: Optimal I/O limit wrapper
cfq: choose a new next_req when a request is dispatched
Seperate read and write statistics of in_flight requests
aoe: end barrier bios with EOPNOTSUPP
block: trace bio queueing trial only when it occurs
block: enable rq CPU completion affinity by default
cfq: fix the log message after dispatched a request
block: use printk_once
cciss: memory leak in cciss_init_one()
splice: update mtime and atime on files
block: make blk_iopoll_prep_sched() follow normal 0/1 return convention
cfq-iosched: get rid of must_alloc flag
block: use interrupts disabled version of raise_softirq_irqoff()
block: fix comment in blk-iopoll.c
block: adjust default budget for blk-iopoll
block: fix long lines in block/blk-iopoll.c
block: add blk-iopoll, a NAPI like approach for block devices
...
42 files changed, 729 insertions, 284 deletions
diff --git a/block/Makefile b/block/Makefile index 6c54ed0ff755..ba74ca6bfa14 100644 --- a/block/Makefile +++ b/block/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ | 5 | obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ |
6 | blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ | 6 | blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ |
7 | blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \ | 7 | blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \ |
8 | ioctl.o genhd.o scsi_ioctl.o | 8 | blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o |
9 | 9 | ||
10 | obj-$(CONFIG_BLK_DEV_BSG) += bsg.o | 10 | obj-$(CONFIG_BLK_DEV_BSG) += bsg.o |
11 | obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o | 11 | obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o |
diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 30022b4e2f63..6593ab39cfe9 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c | |||
@@ -348,6 +348,9 @@ static void blkdev_discard_end_io(struct bio *bio, int err) | |||
348 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | 348 | clear_bit(BIO_UPTODATE, &bio->bi_flags); |
349 | } | 349 | } |
350 | 350 | ||
351 | if (bio->bi_private) | ||
352 | complete(bio->bi_private); | ||
353 | |||
351 | bio_put(bio); | 354 | bio_put(bio); |
352 | } | 355 | } |
353 | 356 | ||
@@ -357,21 +360,20 @@ static void blkdev_discard_end_io(struct bio *bio, int err) | |||
357 | * @sector: start sector | 360 | * @sector: start sector |
358 | * @nr_sects: number of sectors to discard | 361 | * @nr_sects: number of sectors to discard |
359 | * @gfp_mask: memory allocation flags (for bio_alloc) | 362 | * @gfp_mask: memory allocation flags (for bio_alloc) |
363 | * @flags: DISCARD_FL_* flags to control behaviour | ||
360 | * | 364 | * |
361 | * Description: | 365 | * Description: |
362 | * Issue a discard request for the sectors in question. Does not wait. | 366 | * Issue a discard request for the sectors in question. |
363 | */ | 367 | */ |
364 | int blkdev_issue_discard(struct block_device *bdev, | 368 | int blkdev_issue_discard(struct block_device *bdev, sector_t sector, |
365 | sector_t sector, sector_t nr_sects, gfp_t gfp_mask) | 369 | sector_t nr_sects, gfp_t gfp_mask, int flags) |
366 | { | 370 | { |
367 | struct request_queue *q; | 371 | DECLARE_COMPLETION_ONSTACK(wait); |
368 | struct bio *bio; | 372 | struct request_queue *q = bdev_get_queue(bdev); |
373 | int type = flags & DISCARD_FL_BARRIER ? | ||
374 | DISCARD_BARRIER : DISCARD_NOBARRIER; | ||
369 | int ret = 0; | 375 | int ret = 0; |
370 | 376 | ||
371 | if (bdev->bd_disk == NULL) | ||
372 | return -ENXIO; | ||
373 | |||
374 | q = bdev_get_queue(bdev); | ||
375 | if (!q) | 377 | if (!q) |
376 | return -ENXIO; | 378 | return -ENXIO; |
377 | 379 | ||
@@ -379,12 +381,14 @@ int blkdev_issue_discard(struct block_device *bdev, | |||
379 | return -EOPNOTSUPP; | 381 | return -EOPNOTSUPP; |
380 | 382 | ||
381 | while (nr_sects && !ret) { | 383 | while (nr_sects && !ret) { |
382 | bio = bio_alloc(gfp_mask, 0); | 384 | struct bio *bio = bio_alloc(gfp_mask, 0); |
383 | if (!bio) | 385 | if (!bio) |
384 | return -ENOMEM; | 386 | return -ENOMEM; |
385 | 387 | ||
386 | bio->bi_end_io = blkdev_discard_end_io; | 388 | bio->bi_end_io = blkdev_discard_end_io; |
387 | bio->bi_bdev = bdev; | 389 | bio->bi_bdev = bdev; |
390 | if (flags & DISCARD_FL_WAIT) | ||
391 | bio->bi_private = &wait; | ||
388 | 392 | ||
389 | bio->bi_sector = sector; | 393 | bio->bi_sector = sector; |
390 | 394 | ||
@@ -396,10 +400,13 @@ int blkdev_issue_discard(struct block_device *bdev, | |||
396 | bio->bi_size = nr_sects << 9; | 400 | bio->bi_size = nr_sects << 9; |
397 | nr_sects = 0; | 401 | nr_sects = 0; |
398 | } | 402 | } |
403 | |||
399 | bio_get(bio); | 404 | bio_get(bio); |
400 | submit_bio(DISCARD_BARRIER, bio); | 405 | submit_bio(type, bio); |
406 | |||
407 | if (flags & DISCARD_FL_WAIT) | ||
408 | wait_for_completion(&wait); | ||
401 | 409 | ||
402 | /* Check if it failed immediately */ | ||
403 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | 410 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) |
404 | ret = -EOPNOTSUPP; | 411 | ret = -EOPNOTSUPP; |
405 | else if (!bio_flagged(bio, BIO_UPTODATE)) | 412 | else if (!bio_flagged(bio, BIO_UPTODATE)) |
diff --git a/block/blk-core.c b/block/blk-core.c index e695634882a6..8135228e4b29 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -69,7 +69,7 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
69 | part_stat_inc(cpu, part, merges[rw]); | 69 | part_stat_inc(cpu, part, merges[rw]); |
70 | else { | 70 | else { |
71 | part_round_stats(cpu, part); | 71 | part_round_stats(cpu, part); |
72 | part_inc_in_flight(part); | 72 | part_inc_in_flight(part, rw); |
73 | } | 73 | } |
74 | 74 | ||
75 | part_stat_unlock(); | 75 | part_stat_unlock(); |
@@ -1031,7 +1031,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part, | |||
1031 | 1031 | ||
1032 | if (part->in_flight) { | 1032 | if (part->in_flight) { |
1033 | __part_stat_add(cpu, part, time_in_queue, | 1033 | __part_stat_add(cpu, part, time_in_queue, |
1034 | part->in_flight * (now - part->stamp)); | 1034 | part_in_flight(part) * (now - part->stamp)); |
1035 | __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); | 1035 | __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); |
1036 | } | 1036 | } |
1037 | part->stamp = now; | 1037 | part->stamp = now; |
@@ -1112,31 +1112,27 @@ void init_request_from_bio(struct request *req, struct bio *bio) | |||
1112 | req->cmd_type = REQ_TYPE_FS; | 1112 | req->cmd_type = REQ_TYPE_FS; |
1113 | 1113 | ||
1114 | /* | 1114 | /* |
1115 | * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) | 1115 | * Inherit FAILFAST from bio (for read-ahead, and explicit |
1116 | * FAILFAST). FAILFAST flags are identical for req and bio. | ||
1116 | */ | 1117 | */ |
1117 | if (bio_rw_ahead(bio)) | 1118 | if (bio_rw_flagged(bio, BIO_RW_AHEAD)) |
1118 | req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 1119 | req->cmd_flags |= REQ_FAILFAST_MASK; |
1119 | REQ_FAILFAST_DRIVER); | 1120 | else |
1120 | if (bio_failfast_dev(bio)) | 1121 | req->cmd_flags |= bio->bi_rw & REQ_FAILFAST_MASK; |
1121 | req->cmd_flags |= REQ_FAILFAST_DEV; | 1122 | |
1122 | if (bio_failfast_transport(bio)) | 1123 | if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) { |
1123 | req->cmd_flags |= REQ_FAILFAST_TRANSPORT; | ||
1124 | if (bio_failfast_driver(bio)) | ||
1125 | req->cmd_flags |= REQ_FAILFAST_DRIVER; | ||
1126 | |||
1127 | if (unlikely(bio_discard(bio))) { | ||
1128 | req->cmd_flags |= REQ_DISCARD; | 1124 | req->cmd_flags |= REQ_DISCARD; |
1129 | if (bio_barrier(bio)) | 1125 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) |
1130 | req->cmd_flags |= REQ_SOFTBARRIER; | 1126 | req->cmd_flags |= REQ_SOFTBARRIER; |
1131 | req->q->prepare_discard_fn(req->q, req); | 1127 | req->q->prepare_discard_fn(req->q, req); |
1132 | } else if (unlikely(bio_barrier(bio))) | 1128 | } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) |
1133 | req->cmd_flags |= REQ_HARDBARRIER; | 1129 | req->cmd_flags |= REQ_HARDBARRIER; |
1134 | 1130 | ||
1135 | if (bio_sync(bio)) | 1131 | if (bio_rw_flagged(bio, BIO_RW_SYNCIO)) |
1136 | req->cmd_flags |= REQ_RW_SYNC; | 1132 | req->cmd_flags |= REQ_RW_SYNC; |
1137 | if (bio_rw_meta(bio)) | 1133 | if (bio_rw_flagged(bio, BIO_RW_META)) |
1138 | req->cmd_flags |= REQ_RW_META; | 1134 | req->cmd_flags |= REQ_RW_META; |
1139 | if (bio_noidle(bio)) | 1135 | if (bio_rw_flagged(bio, BIO_RW_NOIDLE)) |
1140 | req->cmd_flags |= REQ_NOIDLE; | 1136 | req->cmd_flags |= REQ_NOIDLE; |
1141 | 1137 | ||
1142 | req->errors = 0; | 1138 | req->errors = 0; |
@@ -1151,7 +1147,7 @@ void init_request_from_bio(struct request *req, struct bio *bio) | |||
1151 | */ | 1147 | */ |
1152 | static inline bool queue_should_plug(struct request_queue *q) | 1148 | static inline bool queue_should_plug(struct request_queue *q) |
1153 | { | 1149 | { |
1154 | return !(blk_queue_nonrot(q) && blk_queue_tagged(q)); | 1150 | return !(blk_queue_nonrot(q) && blk_queue_queuing(q)); |
1155 | } | 1151 | } |
1156 | 1152 | ||
1157 | static int __make_request(struct request_queue *q, struct bio *bio) | 1153 | static int __make_request(struct request_queue *q, struct bio *bio) |
@@ -1160,11 +1156,12 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1160 | int el_ret; | 1156 | int el_ret; |
1161 | unsigned int bytes = bio->bi_size; | 1157 | unsigned int bytes = bio->bi_size; |
1162 | const unsigned short prio = bio_prio(bio); | 1158 | const unsigned short prio = bio_prio(bio); |
1163 | const int sync = bio_sync(bio); | 1159 | const bool sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); |
1164 | const int unplug = bio_unplug(bio); | 1160 | const bool unplug = bio_rw_flagged(bio, BIO_RW_UNPLUG); |
1161 | const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK; | ||
1165 | int rw_flags; | 1162 | int rw_flags; |
1166 | 1163 | ||
1167 | if (bio_barrier(bio) && bio_has_data(bio) && | 1164 | if (bio_rw_flagged(bio, BIO_RW_BARRIER) && bio_has_data(bio) && |
1168 | (q->next_ordered == QUEUE_ORDERED_NONE)) { | 1165 | (q->next_ordered == QUEUE_ORDERED_NONE)) { |
1169 | bio_endio(bio, -EOPNOTSUPP); | 1166 | bio_endio(bio, -EOPNOTSUPP); |
1170 | return 0; | 1167 | return 0; |
@@ -1178,7 +1175,7 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1178 | 1175 | ||
1179 | spin_lock_irq(q->queue_lock); | 1176 | spin_lock_irq(q->queue_lock); |
1180 | 1177 | ||
1181 | if (unlikely(bio_barrier(bio)) || elv_queue_empty(q)) | 1178 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)) || elv_queue_empty(q)) |
1182 | goto get_rq; | 1179 | goto get_rq; |
1183 | 1180 | ||
1184 | el_ret = elv_merge(q, &req, bio); | 1181 | el_ret = elv_merge(q, &req, bio); |
@@ -1191,6 +1188,9 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1191 | 1188 | ||
1192 | trace_block_bio_backmerge(q, bio); | 1189 | trace_block_bio_backmerge(q, bio); |
1193 | 1190 | ||
1191 | if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff) | ||
1192 | blk_rq_set_mixed_merge(req); | ||
1193 | |||
1194 | req->biotail->bi_next = bio; | 1194 | req->biotail->bi_next = bio; |
1195 | req->biotail = bio; | 1195 | req->biotail = bio; |
1196 | req->__data_len += bytes; | 1196 | req->__data_len += bytes; |
@@ -1210,6 +1210,12 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1210 | 1210 | ||
1211 | trace_block_bio_frontmerge(q, bio); | 1211 | trace_block_bio_frontmerge(q, bio); |
1212 | 1212 | ||
1213 | if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff) { | ||
1214 | blk_rq_set_mixed_merge(req); | ||
1215 | req->cmd_flags &= ~REQ_FAILFAST_MASK; | ||
1216 | req->cmd_flags |= ff; | ||
1217 | } | ||
1218 | |||
1213 | bio->bi_next = req->bio; | 1219 | bio->bi_next = req->bio; |
1214 | req->bio = bio; | 1220 | req->bio = bio; |
1215 | 1221 | ||
@@ -1457,19 +1463,20 @@ static inline void __generic_make_request(struct bio *bio) | |||
1457 | if (old_sector != -1) | 1463 | if (old_sector != -1) |
1458 | trace_block_remap(q, bio, old_dev, old_sector); | 1464 | trace_block_remap(q, bio, old_dev, old_sector); |
1459 | 1465 | ||
1460 | trace_block_bio_queue(q, bio); | ||
1461 | |||
1462 | old_sector = bio->bi_sector; | 1466 | old_sector = bio->bi_sector; |
1463 | old_dev = bio->bi_bdev->bd_dev; | 1467 | old_dev = bio->bi_bdev->bd_dev; |
1464 | 1468 | ||
1465 | if (bio_check_eod(bio, nr_sectors)) | 1469 | if (bio_check_eod(bio, nr_sectors)) |
1466 | goto end_io; | 1470 | goto end_io; |
1467 | 1471 | ||
1468 | if (bio_discard(bio) && !q->prepare_discard_fn) { | 1472 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) && |
1473 | !q->prepare_discard_fn) { | ||
1469 | err = -EOPNOTSUPP; | 1474 | err = -EOPNOTSUPP; |
1470 | goto end_io; | 1475 | goto end_io; |
1471 | } | 1476 | } |
1472 | 1477 | ||
1478 | trace_block_bio_queue(q, bio); | ||
1479 | |||
1473 | ret = q->make_request_fn(q, bio); | 1480 | ret = q->make_request_fn(q, bio); |
1474 | } while (ret); | 1481 | } while (ret); |
1475 | 1482 | ||
@@ -1654,6 +1661,50 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq) | |||
1654 | } | 1661 | } |
1655 | EXPORT_SYMBOL_GPL(blk_insert_cloned_request); | 1662 | EXPORT_SYMBOL_GPL(blk_insert_cloned_request); |
1656 | 1663 | ||
1664 | /** | ||
1665 | * blk_rq_err_bytes - determine number of bytes till the next failure boundary | ||
1666 | * @rq: request to examine | ||
1667 | * | ||
1668 | * Description: | ||
1669 | * A request could be merge of IOs which require different failure | ||
1670 | * handling. This function determines the number of bytes which | ||
1671 | * can be failed from the beginning of the request without | ||
1672 | * crossing into area which need to be retried further. | ||
1673 | * | ||
1674 | * Return: | ||
1675 | * The number of bytes to fail. | ||
1676 | * | ||
1677 | * Context: | ||
1678 | * queue_lock must be held. | ||
1679 | */ | ||
1680 | unsigned int blk_rq_err_bytes(const struct request *rq) | ||
1681 | { | ||
1682 | unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK; | ||
1683 | unsigned int bytes = 0; | ||
1684 | struct bio *bio; | ||
1685 | |||
1686 | if (!(rq->cmd_flags & REQ_MIXED_MERGE)) | ||
1687 | return blk_rq_bytes(rq); | ||
1688 | |||
1689 | /* | ||
1690 | * Currently the only 'mixing' which can happen is between | ||
1691 | * different fastfail types. We can safely fail portions | ||
1692 | * which have all the failfast bits that the first one has - | ||
1693 | * the ones which are at least as eager to fail as the first | ||
1694 | * one. | ||
1695 | */ | ||
1696 | for (bio = rq->bio; bio; bio = bio->bi_next) { | ||
1697 | if ((bio->bi_rw & ff) != ff) | ||
1698 | break; | ||
1699 | bytes += bio->bi_size; | ||
1700 | } | ||
1701 | |||
1702 | /* this could lead to infinite loop */ | ||
1703 | BUG_ON(blk_rq_bytes(rq) && !bytes); | ||
1704 | return bytes; | ||
1705 | } | ||
1706 | EXPORT_SYMBOL_GPL(blk_rq_err_bytes); | ||
1707 | |||
1657 | static void blk_account_io_completion(struct request *req, unsigned int bytes) | 1708 | static void blk_account_io_completion(struct request *req, unsigned int bytes) |
1658 | { | 1709 | { |
1659 | if (blk_do_io_stat(req)) { | 1710 | if (blk_do_io_stat(req)) { |
@@ -1687,7 +1738,7 @@ static void blk_account_io_done(struct request *req) | |||
1687 | part_stat_inc(cpu, part, ios[rw]); | 1738 | part_stat_inc(cpu, part, ios[rw]); |
1688 | part_stat_add(cpu, part, ticks[rw], duration); | 1739 | part_stat_add(cpu, part, ticks[rw], duration); |
1689 | part_round_stats(cpu, part); | 1740 | part_round_stats(cpu, part); |
1690 | part_dec_in_flight(part); | 1741 | part_dec_in_flight(part, rw); |
1691 | 1742 | ||
1692 | part_stat_unlock(); | 1743 | part_stat_unlock(); |
1693 | } | 1744 | } |
@@ -1807,8 +1858,15 @@ void blk_dequeue_request(struct request *rq) | |||
1807 | * and to it is freed is accounted as io that is in progress at | 1858 | * and to it is freed is accounted as io that is in progress at |
1808 | * the driver side. | 1859 | * the driver side. |
1809 | */ | 1860 | */ |
1810 | if (blk_account_rq(rq)) | 1861 | if (blk_account_rq(rq)) { |
1811 | q->in_flight[rq_is_sync(rq)]++; | 1862 | q->in_flight[rq_is_sync(rq)]++; |
1863 | /* | ||
1864 | * Mark this device as supporting hardware queuing, if | ||
1865 | * we have more IOs in flight than 4. | ||
1866 | */ | ||
1867 | if (!blk_queue_queuing(q) && queue_in_flight(q) > 4) | ||
1868 | set_bit(QUEUE_FLAG_CQ, &q->queue_flags); | ||
1869 | } | ||
1812 | } | 1870 | } |
1813 | 1871 | ||
1814 | /** | 1872 | /** |
@@ -2000,6 +2058,12 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) | |||
2000 | if (blk_fs_request(req) || blk_discard_rq(req)) | 2058 | if (blk_fs_request(req) || blk_discard_rq(req)) |
2001 | req->__sector += total_bytes >> 9; | 2059 | req->__sector += total_bytes >> 9; |
2002 | 2060 | ||
2061 | /* mixed attributes always follow the first bio */ | ||
2062 | if (req->cmd_flags & REQ_MIXED_MERGE) { | ||
2063 | req->cmd_flags &= ~REQ_FAILFAST_MASK; | ||
2064 | req->cmd_flags |= req->bio->bi_rw & REQ_FAILFAST_MASK; | ||
2065 | } | ||
2066 | |||
2003 | /* | 2067 | /* |
2004 | * If total number of sectors is less than the first segment | 2068 | * If total number of sectors is less than the first segment |
2005 | * size, something has gone terribly wrong. | 2069 | * size, something has gone terribly wrong. |
@@ -2179,6 +2243,25 @@ bool blk_end_request_cur(struct request *rq, int error) | |||
2179 | EXPORT_SYMBOL(blk_end_request_cur); | 2243 | EXPORT_SYMBOL(blk_end_request_cur); |
2180 | 2244 | ||
2181 | /** | 2245 | /** |
2246 | * blk_end_request_err - Finish a request till the next failure boundary. | ||
2247 | * @rq: the request to finish till the next failure boundary for | ||
2248 | * @error: must be negative errno | ||
2249 | * | ||
2250 | * Description: | ||
2251 | * Complete @rq till the next failure boundary. | ||
2252 | * | ||
2253 | * Return: | ||
2254 | * %false - we are done with this request | ||
2255 | * %true - still buffers pending for this request | ||
2256 | */ | ||
2257 | bool blk_end_request_err(struct request *rq, int error) | ||
2258 | { | ||
2259 | WARN_ON(error >= 0); | ||
2260 | return blk_end_request(rq, error, blk_rq_err_bytes(rq)); | ||
2261 | } | ||
2262 | EXPORT_SYMBOL_GPL(blk_end_request_err); | ||
2263 | |||
2264 | /** | ||
2182 | * __blk_end_request - Helper function for drivers to complete the request. | 2265 | * __blk_end_request - Helper function for drivers to complete the request. |
2183 | * @rq: the request being processed | 2266 | * @rq: the request being processed |
2184 | * @error: %0 for success, < %0 for error | 2267 | * @error: %0 for success, < %0 for error |
@@ -2237,12 +2320,31 @@ bool __blk_end_request_cur(struct request *rq, int error) | |||
2237 | } | 2320 | } |
2238 | EXPORT_SYMBOL(__blk_end_request_cur); | 2321 | EXPORT_SYMBOL(__blk_end_request_cur); |
2239 | 2322 | ||
2323 | /** | ||
2324 | * __blk_end_request_err - Finish a request till the next failure boundary. | ||
2325 | * @rq: the request to finish till the next failure boundary for | ||
2326 | * @error: must be negative errno | ||
2327 | * | ||
2328 | * Description: | ||
2329 | * Complete @rq till the next failure boundary. Must be called | ||
2330 | * with queue lock held. | ||
2331 | * | ||
2332 | * Return: | ||
2333 | * %false - we are done with this request | ||
2334 | * %true - still buffers pending for this request | ||
2335 | */ | ||
2336 | bool __blk_end_request_err(struct request *rq, int error) | ||
2337 | { | ||
2338 | WARN_ON(error >= 0); | ||
2339 | return __blk_end_request(rq, error, blk_rq_err_bytes(rq)); | ||
2340 | } | ||
2341 | EXPORT_SYMBOL_GPL(__blk_end_request_err); | ||
2342 | |||
2240 | void blk_rq_bio_prep(struct request_queue *q, struct request *rq, | 2343 | void blk_rq_bio_prep(struct request_queue *q, struct request *rq, |
2241 | struct bio *bio) | 2344 | struct bio *bio) |
2242 | { | 2345 | { |
2243 | /* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw, and | 2346 | /* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */ |
2244 | we want BIO_RW_AHEAD (bit 1) to imply REQ_FAILFAST (bit 1). */ | 2347 | rq->cmd_flags |= bio->bi_rw & REQ_RW; |
2245 | rq->cmd_flags |= (bio->bi_rw & 3); | ||
2246 | 2348 | ||
2247 | if (bio_has_data(bio)) { | 2349 | if (bio_has_data(bio)) { |
2248 | rq->nr_phys_segments = bio_phys_segments(q, bio); | 2350 | rq->nr_phys_segments = bio_phys_segments(q, bio); |
diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c new file mode 100644 index 000000000000..ca564202ed7a --- /dev/null +++ b/block/blk-iopoll.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Functions related to interrupt-poll handling in the block layer. This | ||
3 | * is similar to NAPI for network devices. | ||
4 | */ | ||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/bio.h> | ||
9 | #include <linux/blkdev.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/cpu.h> | ||
12 | #include <linux/blk-iopoll.h> | ||
13 | #include <linux/delay.h> | ||
14 | |||
15 | #include "blk.h" | ||
16 | |||
17 | int blk_iopoll_enabled = 1; | ||
18 | EXPORT_SYMBOL(blk_iopoll_enabled); | ||
19 | |||
20 | static unsigned int blk_iopoll_budget __read_mostly = 256; | ||
21 | |||
22 | static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll); | ||
23 | |||
24 | /** | ||
25 | * blk_iopoll_sched - Schedule a run of the iopoll handler | ||
26 | * @iop: The parent iopoll structure | ||
27 | * | ||
28 | * Description: | ||
29 | * Add this blk_iopoll structure to the pending poll list and trigger the | ||
30 | * raise of the blk iopoll softirq. The driver must already have gotten a | ||
31 | * succesful return from blk_iopoll_sched_prep() before calling this. | ||
32 | **/ | ||
33 | void blk_iopoll_sched(struct blk_iopoll *iop) | ||
34 | { | ||
35 | unsigned long flags; | ||
36 | |||
37 | local_irq_save(flags); | ||
38 | list_add_tail(&iop->list, &__get_cpu_var(blk_cpu_iopoll)); | ||
39 | __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); | ||
40 | local_irq_restore(flags); | ||
41 | } | ||
42 | EXPORT_SYMBOL(blk_iopoll_sched); | ||
43 | |||
44 | /** | ||
45 | * __blk_iopoll_complete - Mark this @iop as un-polled again | ||
46 | * @iop: The parent iopoll structure | ||
47 | * | ||
48 | * Description: | ||
49 | * See blk_iopoll_complete(). This function must be called with interrupts | ||
50 | * disabled. | ||
51 | **/ | ||
52 | void __blk_iopoll_complete(struct blk_iopoll *iop) | ||
53 | { | ||
54 | list_del(&iop->list); | ||
55 | smp_mb__before_clear_bit(); | ||
56 | clear_bit_unlock(IOPOLL_F_SCHED, &iop->state); | ||
57 | } | ||
58 | EXPORT_SYMBOL(__blk_iopoll_complete); | ||
59 | |||
60 | /** | ||
61 | * blk_iopoll_complete - Mark this @iop as un-polled again | ||
62 | * @iop: The parent iopoll structure | ||
63 | * | ||
64 | * Description: | ||
65 | * If a driver consumes less than the assigned budget in its run of the | ||
66 | * iopoll handler, it'll end the polled mode by calling this function. The | ||
67 | * iopoll handler will not be invoked again before blk_iopoll_sched_prep() | ||
68 | * is called. | ||
69 | **/ | ||
70 | void blk_iopoll_complete(struct blk_iopoll *iopoll) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | |||
74 | local_irq_save(flags); | ||
75 | __blk_iopoll_complete(iopoll); | ||
76 | local_irq_restore(flags); | ||
77 | } | ||
78 | EXPORT_SYMBOL(blk_iopoll_complete); | ||
79 | |||
80 | static void blk_iopoll_softirq(struct softirq_action *h) | ||
81 | { | ||
82 | struct list_head *list = &__get_cpu_var(blk_cpu_iopoll); | ||
83 | int rearm = 0, budget = blk_iopoll_budget; | ||
84 | unsigned long start_time = jiffies; | ||
85 | |||
86 | local_irq_disable(); | ||
87 | |||
88 | while (!list_empty(list)) { | ||
89 | struct blk_iopoll *iop; | ||
90 | int work, weight; | ||
91 | |||
92 | /* | ||
93 | * If softirq window is exhausted then punt. | ||
94 | */ | ||
95 | if (budget <= 0 || time_after(jiffies, start_time)) { | ||
96 | rearm = 1; | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | local_irq_enable(); | ||
101 | |||
102 | /* Even though interrupts have been re-enabled, this | ||
103 | * access is safe because interrupts can only add new | ||
104 | * entries to the tail of this list, and only ->poll() | ||
105 | * calls can remove this head entry from the list. | ||
106 | */ | ||
107 | iop = list_entry(list->next, struct blk_iopoll, list); | ||
108 | |||
109 | weight = iop->weight; | ||
110 | work = 0; | ||
111 | if (test_bit(IOPOLL_F_SCHED, &iop->state)) | ||
112 | work = iop->poll(iop, weight); | ||
113 | |||
114 | budget -= work; | ||
115 | |||
116 | local_irq_disable(); | ||
117 | |||
118 | /* | ||
119 | * Drivers must not modify the iopoll state, if they | ||
120 | * consume their assigned weight (or more, some drivers can't | ||
121 | * easily just stop processing, they have to complete an | ||
122 | * entire mask of commands).In such cases this code | ||
123 | * still "owns" the iopoll instance and therefore can | ||
124 | * move the instance around on the list at-will. | ||
125 | */ | ||
126 | if (work >= weight) { | ||
127 | if (blk_iopoll_disable_pending(iop)) | ||
128 | __blk_iopoll_complete(iop); | ||
129 | else | ||
130 | list_move_tail(&iop->list, list); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | if (rearm) | ||
135 | __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); | ||
136 | |||
137 | local_irq_enable(); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * blk_iopoll_disable - Disable iopoll on this @iop | ||
142 | * @iop: The parent iopoll structure | ||
143 | * | ||
144 | * Description: | ||
145 | * Disable io polling and wait for any pending callbacks to have completed. | ||
146 | **/ | ||
147 | void blk_iopoll_disable(struct blk_iopoll *iop) | ||
148 | { | ||
149 | set_bit(IOPOLL_F_DISABLE, &iop->state); | ||
150 | while (test_and_set_bit(IOPOLL_F_SCHED, &iop->state)) | ||
151 | msleep(1); | ||
152 | clear_bit(IOPOLL_F_DISABLE, &iop->state); | ||
153 | } | ||
154 | EXPORT_SYMBOL(blk_iopoll_disable); | ||
155 | |||
156 | /** | ||
157 | * blk_iopoll_enable - Enable iopoll on this @iop | ||
158 | * @iop: The parent iopoll structure | ||
159 | * | ||
160 | * Description: | ||
161 | * Enable iopoll on this @iop. Note that the handler run will not be | ||
162 | * scheduled, it will only mark it as active. | ||
163 | **/ | ||
164 | void blk_iopoll_enable(struct blk_iopoll *iop) | ||
165 | { | ||
166 | BUG_ON(!test_bit(IOPOLL_F_SCHED, &iop->state)); | ||
167 | smp_mb__before_clear_bit(); | ||
168 | clear_bit_unlock(IOPOLL_F_SCHED, &iop->state); | ||
169 | } | ||
170 | EXPORT_SYMBOL(blk_iopoll_enable); | ||
171 | |||
172 | /** | ||
173 | * blk_iopoll_init - Initialize this @iop | ||
174 | * @iop: The parent iopoll structure | ||
175 | * @weight: The default weight (or command completion budget) | ||
176 | * @poll_fn: The handler to invoke | ||
177 | * | ||
178 | * Description: | ||
179 | * Initialize this blk_iopoll structure. Before being actively used, the | ||
180 | * driver must call blk_iopoll_enable(). | ||
181 | **/ | ||
182 | void blk_iopoll_init(struct blk_iopoll *iop, int weight, blk_iopoll_fn *poll_fn) | ||
183 | { | ||
184 | memset(iop, 0, sizeof(*iop)); | ||
185 | INIT_LIST_HEAD(&iop->list); | ||
186 | iop->weight = weight; | ||
187 | iop->poll = poll_fn; | ||
188 | set_bit(IOPOLL_F_SCHED, &iop->state); | ||
189 | } | ||
190 | EXPORT_SYMBOL(blk_iopoll_init); | ||
191 | |||
192 | static int __cpuinit blk_iopoll_cpu_notify(struct notifier_block *self, | ||
193 | unsigned long action, void *hcpu) | ||
194 | { | ||
195 | /* | ||
196 | * If a CPU goes away, splice its entries to the current CPU | ||
197 | * and trigger a run of the softirq | ||
198 | */ | ||
199 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { | ||
200 | int cpu = (unsigned long) hcpu; | ||
201 | |||
202 | local_irq_disable(); | ||
203 | list_splice_init(&per_cpu(blk_cpu_iopoll, cpu), | ||
204 | &__get_cpu_var(blk_cpu_iopoll)); | ||
205 | __raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ); | ||
206 | local_irq_enable(); | ||
207 | } | ||
208 | |||
209 | return NOTIFY_OK; | ||
210 | } | ||
211 | |||
212 | static struct notifier_block __cpuinitdata blk_iopoll_cpu_notifier = { | ||
213 | .notifier_call = blk_iopoll_cpu_notify, | ||
214 | }; | ||
215 | |||
216 | static __init int blk_iopoll_setup(void) | ||
217 | { | ||
218 | int i; | ||
219 | |||
220 | for_each_possible_cpu(i) | ||
221 | INIT_LIST_HEAD(&per_cpu(blk_cpu_iopoll, i)); | ||
222 | |||
223 | open_softirq(BLOCK_IOPOLL_SOFTIRQ, blk_iopoll_softirq); | ||
224 | register_hotcpu_notifier(&blk_iopoll_cpu_notifier); | ||
225 | return 0; | ||
226 | } | ||
227 | subsys_initcall(blk_iopoll_setup); | ||
diff --git a/block/blk-merge.c b/block/blk-merge.c index e1999679a4d5..99cb5cf1f447 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -311,6 +311,36 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, | |||
311 | return 1; | 311 | return 1; |
312 | } | 312 | } |
313 | 313 | ||
314 | /** | ||
315 | * blk_rq_set_mixed_merge - mark a request as mixed merge | ||
316 | * @rq: request to mark as mixed merge | ||
317 | * | ||
318 | * Description: | ||
319 | * @rq is about to be mixed merged. Make sure the attributes | ||
320 | * which can be mixed are set in each bio and mark @rq as mixed | ||
321 | * merged. | ||
322 | */ | ||
323 | void blk_rq_set_mixed_merge(struct request *rq) | ||
324 | { | ||
325 | unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK; | ||
326 | struct bio *bio; | ||
327 | |||
328 | if (rq->cmd_flags & REQ_MIXED_MERGE) | ||
329 | return; | ||
330 | |||
331 | /* | ||
332 | * @rq will no longer represent mixable attributes for all the | ||
333 | * contained bios. It will just track those of the first one. | ||
334 | * Distributes the attributs to each bio. | ||
335 | */ | ||
336 | for (bio = rq->bio; bio; bio = bio->bi_next) { | ||
337 | WARN_ON_ONCE((bio->bi_rw & REQ_FAILFAST_MASK) && | ||
338 | (bio->bi_rw & REQ_FAILFAST_MASK) != ff); | ||
339 | bio->bi_rw |= ff; | ||
340 | } | ||
341 | rq->cmd_flags |= REQ_MIXED_MERGE; | ||
342 | } | ||
343 | |||
314 | static void blk_account_io_merge(struct request *req) | 344 | static void blk_account_io_merge(struct request *req) |
315 | { | 345 | { |
316 | if (blk_do_io_stat(req)) { | 346 | if (blk_do_io_stat(req)) { |
@@ -321,7 +351,7 @@ static void blk_account_io_merge(struct request *req) | |||
321 | part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); | 351 | part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req)); |
322 | 352 | ||
323 | part_round_stats(cpu, part); | 353 | part_round_stats(cpu, part); |
324 | part_dec_in_flight(part); | 354 | part_dec_in_flight(part, rq_data_dir(req)); |
325 | 355 | ||
326 | part_stat_unlock(); | 356 | part_stat_unlock(); |
327 | } | 357 | } |
@@ -350,12 +380,6 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
350 | if (blk_integrity_rq(req) != blk_integrity_rq(next)) | 380 | if (blk_integrity_rq(req) != blk_integrity_rq(next)) |
351 | return 0; | 381 | return 0; |
352 | 382 | ||
353 | /* don't merge requests of different failfast settings */ | ||
354 | if (blk_failfast_dev(req) != blk_failfast_dev(next) || | ||
355 | blk_failfast_transport(req) != blk_failfast_transport(next) || | ||
356 | blk_failfast_driver(req) != blk_failfast_driver(next)) | ||
357 | return 0; | ||
358 | |||
359 | /* | 383 | /* |
360 | * If we are allowed to merge, then append bio list | 384 | * If we are allowed to merge, then append bio list |
361 | * from next to rq and release next. merge_requests_fn | 385 | * from next to rq and release next. merge_requests_fn |
@@ -366,6 +390,19 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
366 | return 0; | 390 | return 0; |
367 | 391 | ||
368 | /* | 392 | /* |
393 | * If failfast settings disagree or any of the two is already | ||
394 | * a mixed merge, mark both as mixed before proceeding. This | ||
395 | * makes sure that all involved bios have mixable attributes | ||
396 | * set properly. | ||
397 | */ | ||
398 | if ((req->cmd_flags | next->cmd_flags) & REQ_MIXED_MERGE || | ||
399 | (req->cmd_flags & REQ_FAILFAST_MASK) != | ||
400 | (next->cmd_flags & REQ_FAILFAST_MASK)) { | ||
401 | blk_rq_set_mixed_merge(req); | ||
402 | blk_rq_set_mixed_merge(next); | ||
403 | } | ||
404 | |||
405 | /* | ||
369 | * At this point we have either done a back merge | 406 | * At this point we have either done a back merge |
370 | * or front merge. We need the smaller start_time of | 407 | * or front merge. We need the smaller start_time of |
371 | * the merged requests to be the current request | 408 | * the merged requests to be the current request |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 476d87065073..83413ff83739 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -428,6 +428,25 @@ void blk_queue_io_min(struct request_queue *q, unsigned int min) | |||
428 | EXPORT_SYMBOL(blk_queue_io_min); | 428 | EXPORT_SYMBOL(blk_queue_io_min); |
429 | 429 | ||
430 | /** | 430 | /** |
431 | * blk_limits_io_opt - set optimal request size for a device | ||
432 | * @limits: the queue limits | ||
433 | * @opt: smallest I/O size in bytes | ||
434 | * | ||
435 | * Description: | ||
436 | * Storage devices may report an optimal I/O size, which is the | ||
437 | * device's preferred unit for sustained I/O. This is rarely reported | ||
438 | * for disk drives. For RAID arrays it is usually the stripe width or | ||
439 | * the internal track size. A properly aligned multiple of | ||
440 | * optimal_io_size is the preferred request size for workloads where | ||
441 | * sustained throughput is desired. | ||
442 | */ | ||
443 | void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt) | ||
444 | { | ||
445 | limits->io_opt = opt; | ||
446 | } | ||
447 | EXPORT_SYMBOL(blk_limits_io_opt); | ||
448 | |||
449 | /** | ||
431 | * blk_queue_io_opt - set optimal request size for the queue | 450 | * blk_queue_io_opt - set optimal request size for the queue |
432 | * @q: the request queue for the device | 451 | * @q: the request queue for the device |
433 | * @opt: optimal request size in bytes | 452 | * @opt: optimal request size in bytes |
@@ -442,7 +461,7 @@ EXPORT_SYMBOL(blk_queue_io_min); | |||
442 | */ | 461 | */ |
443 | void blk_queue_io_opt(struct request_queue *q, unsigned int opt) | 462 | void blk_queue_io_opt(struct request_queue *q, unsigned int opt) |
444 | { | 463 | { |
445 | q->limits.io_opt = opt; | 464 | blk_limits_io_opt(&q->limits, opt); |
446 | } | 465 | } |
447 | EXPORT_SYMBOL(blk_queue_io_opt); | 466 | EXPORT_SYMBOL(blk_queue_io_opt); |
448 | 467 | ||
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index d3aa2aadb3e0..b78c9c3e2670 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -40,7 +40,12 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count) | |||
40 | { | 40 | { |
41 | struct request_list *rl = &q->rq; | 41 | struct request_list *rl = &q->rq; |
42 | unsigned long nr; | 42 | unsigned long nr; |
43 | int ret = queue_var_store(&nr, page, count); | 43 | int ret; |
44 | |||
45 | if (!q->request_fn) | ||
46 | return -EINVAL; | ||
47 | |||
48 | ret = queue_var_store(&nr, page, count); | ||
44 | if (nr < BLKDEV_MIN_RQ) | 49 | if (nr < BLKDEV_MIN_RQ) |
45 | nr = BLKDEV_MIN_RQ; | 50 | nr = BLKDEV_MIN_RQ; |
46 | 51 | ||
diff --git a/block/blk.h b/block/blk.h index 3fae6add5430..5ee3d7e72feb 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -104,6 +104,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, | |||
104 | int attempt_back_merge(struct request_queue *q, struct request *rq); | 104 | int attempt_back_merge(struct request_queue *q, struct request *rq); |
105 | int attempt_front_merge(struct request_queue *q, struct request *rq); | 105 | int attempt_front_merge(struct request_queue *q, struct request *rq); |
106 | void blk_recalc_rq_segments(struct request *rq); | 106 | void blk_recalc_rq_segments(struct request *rq); |
107 | void blk_rq_set_mixed_merge(struct request *rq); | ||
107 | 108 | ||
108 | void blk_queue_congestion_threshold(struct request_queue *q); | 109 | void blk_queue_congestion_threshold(struct request_queue *q); |
109 | 110 | ||
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index fd7080ed7935..0e3814b662af 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -134,13 +134,8 @@ struct cfq_data { | |||
134 | struct rb_root prio_trees[CFQ_PRIO_LISTS]; | 134 | struct rb_root prio_trees[CFQ_PRIO_LISTS]; |
135 | 135 | ||
136 | unsigned int busy_queues; | 136 | unsigned int busy_queues; |
137 | /* | ||
138 | * Used to track any pending rt requests so we can pre-empt current | ||
139 | * non-RT cfqq in service when this value is non-zero. | ||
140 | */ | ||
141 | unsigned int busy_rt_queues; | ||
142 | 137 | ||
143 | int rq_in_driver; | 138 | int rq_in_driver[2]; |
144 | int sync_flight; | 139 | int sync_flight; |
145 | 140 | ||
146 | /* | 141 | /* |
@@ -191,7 +186,6 @@ enum cfqq_state_flags { | |||
191 | CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */ | 186 | CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */ |
192 | CFQ_CFQQ_FLAG_wait_request, /* waiting for a request */ | 187 | CFQ_CFQQ_FLAG_wait_request, /* waiting for a request */ |
193 | CFQ_CFQQ_FLAG_must_dispatch, /* must be allowed a dispatch */ | 188 | CFQ_CFQQ_FLAG_must_dispatch, /* must be allowed a dispatch */ |
194 | CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ | ||
195 | CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */ | 189 | CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */ |
196 | CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ | 190 | CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ |
197 | CFQ_CFQQ_FLAG_idle_window, /* slice idling enabled */ | 191 | CFQ_CFQQ_FLAG_idle_window, /* slice idling enabled */ |
@@ -218,7 +212,6 @@ static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq) \ | |||
218 | CFQ_CFQQ_FNS(on_rr); | 212 | CFQ_CFQQ_FNS(on_rr); |
219 | CFQ_CFQQ_FNS(wait_request); | 213 | CFQ_CFQQ_FNS(wait_request); |
220 | CFQ_CFQQ_FNS(must_dispatch); | 214 | CFQ_CFQQ_FNS(must_dispatch); |
221 | CFQ_CFQQ_FNS(must_alloc); | ||
222 | CFQ_CFQQ_FNS(must_alloc_slice); | 215 | CFQ_CFQQ_FNS(must_alloc_slice); |
223 | CFQ_CFQQ_FNS(fifo_expire); | 216 | CFQ_CFQQ_FNS(fifo_expire); |
224 | CFQ_CFQQ_FNS(idle_window); | 217 | CFQ_CFQQ_FNS(idle_window); |
@@ -239,6 +232,11 @@ static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, | |||
239 | static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *, | 232 | static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *, |
240 | struct io_context *); | 233 | struct io_context *); |
241 | 234 | ||
235 | static inline int rq_in_driver(struct cfq_data *cfqd) | ||
236 | { | ||
237 | return cfqd->rq_in_driver[0] + cfqd->rq_in_driver[1]; | ||
238 | } | ||
239 | |||
242 | static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic, | 240 | static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic, |
243 | int is_sync) | 241 | int is_sync) |
244 | { | 242 | { |
@@ -257,7 +255,7 @@ static inline void cic_set_cfqq(struct cfq_io_context *cic, | |||
257 | */ | 255 | */ |
258 | static inline int cfq_bio_sync(struct bio *bio) | 256 | static inline int cfq_bio_sync(struct bio *bio) |
259 | { | 257 | { |
260 | if (bio_data_dir(bio) == READ || bio_sync(bio)) | 258 | if (bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO)) |
261 | return 1; | 259 | return 1; |
262 | 260 | ||
263 | return 0; | 261 | return 0; |
@@ -648,8 +646,6 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
648 | BUG_ON(cfq_cfqq_on_rr(cfqq)); | 646 | BUG_ON(cfq_cfqq_on_rr(cfqq)); |
649 | cfq_mark_cfqq_on_rr(cfqq); | 647 | cfq_mark_cfqq_on_rr(cfqq); |
650 | cfqd->busy_queues++; | 648 | cfqd->busy_queues++; |
651 | if (cfq_class_rt(cfqq)) | ||
652 | cfqd->busy_rt_queues++; | ||
653 | 649 | ||
654 | cfq_resort_rr_list(cfqd, cfqq); | 650 | cfq_resort_rr_list(cfqd, cfqq); |
655 | } | 651 | } |
@@ -673,8 +669,6 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
673 | 669 | ||
674 | BUG_ON(!cfqd->busy_queues); | 670 | BUG_ON(!cfqd->busy_queues); |
675 | cfqd->busy_queues--; | 671 | cfqd->busy_queues--; |
676 | if (cfq_class_rt(cfqq)) | ||
677 | cfqd->busy_rt_queues--; | ||
678 | } | 672 | } |
679 | 673 | ||
680 | /* | 674 | /* |
@@ -760,9 +754,9 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) | |||
760 | { | 754 | { |
761 | struct cfq_data *cfqd = q->elevator->elevator_data; | 755 | struct cfq_data *cfqd = q->elevator->elevator_data; |
762 | 756 | ||
763 | cfqd->rq_in_driver++; | 757 | cfqd->rq_in_driver[rq_is_sync(rq)]++; |
764 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", | 758 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", |
765 | cfqd->rq_in_driver); | 759 | rq_in_driver(cfqd)); |
766 | 760 | ||
767 | cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); | 761 | cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); |
768 | } | 762 | } |
@@ -770,11 +764,12 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) | |||
770 | static void cfq_deactivate_request(struct request_queue *q, struct request *rq) | 764 | static void cfq_deactivate_request(struct request_queue *q, struct request *rq) |
771 | { | 765 | { |
772 | struct cfq_data *cfqd = q->elevator->elevator_data; | 766 | struct cfq_data *cfqd = q->elevator->elevator_data; |
767 | const int sync = rq_is_sync(rq); | ||
773 | 768 | ||
774 | WARN_ON(!cfqd->rq_in_driver); | 769 | WARN_ON(!cfqd->rq_in_driver[sync]); |
775 | cfqd->rq_in_driver--; | 770 | cfqd->rq_in_driver[sync]--; |
776 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", | 771 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", |
777 | cfqd->rq_in_driver); | 772 | rq_in_driver(cfqd)); |
778 | } | 773 | } |
779 | 774 | ||
780 | static void cfq_remove_request(struct request *rq) | 775 | static void cfq_remove_request(struct request *rq) |
@@ -1080,7 +1075,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1080 | /* | 1075 | /* |
1081 | * still requests with the driver, don't idle | 1076 | * still requests with the driver, don't idle |
1082 | */ | 1077 | */ |
1083 | if (cfqd->rq_in_driver) | 1078 | if (rq_in_driver(cfqd)) |
1084 | return; | 1079 | return; |
1085 | 1080 | ||
1086 | /* | 1081 | /* |
@@ -1115,6 +1110,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq) | |||
1115 | 1110 | ||
1116 | cfq_log_cfqq(cfqd, cfqq, "dispatch_insert"); | 1111 | cfq_log_cfqq(cfqd, cfqq, "dispatch_insert"); |
1117 | 1112 | ||
1113 | cfqq->next_rq = cfq_find_next_rq(cfqd, cfqq, rq); | ||
1118 | cfq_remove_request(rq); | 1114 | cfq_remove_request(rq); |
1119 | cfqq->dispatched++; | 1115 | cfqq->dispatched++; |
1120 | elv_dispatch_sort(q, rq); | 1116 | elv_dispatch_sort(q, rq); |
@@ -1179,20 +1175,6 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) | |||
1179 | goto expire; | 1175 | goto expire; |
1180 | 1176 | ||
1181 | /* | 1177 | /* |
1182 | * If we have a RT cfqq waiting, then we pre-empt the current non-rt | ||
1183 | * cfqq. | ||
1184 | */ | ||
1185 | if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues) { | ||
1186 | /* | ||
1187 | * We simulate this as cfqq timed out so that it gets to bank | ||
1188 | * the remaining of its time slice. | ||
1189 | */ | ||
1190 | cfq_log_cfqq(cfqd, cfqq, "preempt"); | ||
1191 | cfq_slice_expired(cfqd, 1); | ||
1192 | goto new_queue; | ||
1193 | } | ||
1194 | |||
1195 | /* | ||
1196 | * The active queue has requests and isn't expired, allow it to | 1178 | * The active queue has requests and isn't expired, allow it to |
1197 | * dispatch. | 1179 | * dispatch. |
1198 | */ | 1180 | */ |
@@ -1312,6 +1294,12 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1312 | return 0; | 1294 | return 0; |
1313 | 1295 | ||
1314 | /* | 1296 | /* |
1297 | * Drain async requests before we start sync IO | ||
1298 | */ | ||
1299 | if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) | ||
1300 | return 0; | ||
1301 | |||
1302 | /* | ||
1315 | * If this is an async queue and we have sync IO in flight, let it wait | 1303 | * If this is an async queue and we have sync IO in flight, let it wait |
1316 | */ | 1304 | */ |
1317 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) | 1305 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) |
@@ -1362,7 +1350,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1362 | cfq_slice_expired(cfqd, 0); | 1350 | cfq_slice_expired(cfqd, 0); |
1363 | } | 1351 | } |
1364 | 1352 | ||
1365 | cfq_log(cfqd, "dispatched a request"); | 1353 | cfq_log_cfqq(cfqd, cfqq, "dispatched a request"); |
1366 | return 1; | 1354 | return 1; |
1367 | } | 1355 | } |
1368 | 1356 | ||
@@ -2130,11 +2118,11 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq) | |||
2130 | */ | 2118 | */ |
2131 | static void cfq_update_hw_tag(struct cfq_data *cfqd) | 2119 | static void cfq_update_hw_tag(struct cfq_data *cfqd) |
2132 | { | 2120 | { |
2133 | if (cfqd->rq_in_driver > cfqd->rq_in_driver_peak) | 2121 | if (rq_in_driver(cfqd) > cfqd->rq_in_driver_peak) |
2134 | cfqd->rq_in_driver_peak = cfqd->rq_in_driver; | 2122 | cfqd->rq_in_driver_peak = rq_in_driver(cfqd); |
2135 | 2123 | ||
2136 | if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN && | 2124 | if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN && |
2137 | cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN) | 2125 | rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN) |
2138 | return; | 2126 | return; |
2139 | 2127 | ||
2140 | if (cfqd->hw_tag_samples++ < 50) | 2128 | if (cfqd->hw_tag_samples++ < 50) |
@@ -2161,9 +2149,9 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
2161 | 2149 | ||
2162 | cfq_update_hw_tag(cfqd); | 2150 | cfq_update_hw_tag(cfqd); |
2163 | 2151 | ||
2164 | WARN_ON(!cfqd->rq_in_driver); | 2152 | WARN_ON(!cfqd->rq_in_driver[sync]); |
2165 | WARN_ON(!cfqq->dispatched); | 2153 | WARN_ON(!cfqq->dispatched); |
2166 | cfqd->rq_in_driver--; | 2154 | cfqd->rq_in_driver[sync]--; |
2167 | cfqq->dispatched--; | 2155 | cfqq->dispatched--; |
2168 | 2156 | ||
2169 | if (cfq_cfqq_sync(cfqq)) | 2157 | if (cfq_cfqq_sync(cfqq)) |
@@ -2197,7 +2185,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
2197 | cfq_arm_slice_timer(cfqd); | 2185 | cfq_arm_slice_timer(cfqd); |
2198 | } | 2186 | } |
2199 | 2187 | ||
2200 | if (!cfqd->rq_in_driver) | 2188 | if (!rq_in_driver(cfqd)) |
2201 | cfq_schedule_dispatch(cfqd); | 2189 | cfq_schedule_dispatch(cfqd); |
2202 | } | 2190 | } |
2203 | 2191 | ||
@@ -2229,8 +2217,7 @@ static void cfq_prio_boost(struct cfq_queue *cfqq) | |||
2229 | 2217 | ||
2230 | static inline int __cfq_may_queue(struct cfq_queue *cfqq) | 2218 | static inline int __cfq_may_queue(struct cfq_queue *cfqq) |
2231 | { | 2219 | { |
2232 | if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) && | 2220 | if (cfq_cfqq_wait_request(cfqq) && !cfq_cfqq_must_alloc_slice(cfqq)) { |
2233 | !cfq_cfqq_must_alloc_slice(cfqq)) { | ||
2234 | cfq_mark_cfqq_must_alloc_slice(cfqq); | 2221 | cfq_mark_cfqq_must_alloc_slice(cfqq); |
2235 | return ELV_MQUEUE_MUST; | 2222 | return ELV_MQUEUE_MUST; |
2236 | } | 2223 | } |
@@ -2317,7 +2304,6 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) | |||
2317 | } | 2304 | } |
2318 | 2305 | ||
2319 | cfqq->allocated[rw]++; | 2306 | cfqq->allocated[rw]++; |
2320 | cfq_clear_cfqq_must_alloc(cfqq); | ||
2321 | atomic_inc(&cfqq->ref); | 2307 | atomic_inc(&cfqq->ref); |
2322 | 2308 | ||
2323 | spin_unlock_irqrestore(q->queue_lock, flags); | 2309 | spin_unlock_irqrestore(q->queue_lock, flags); |
diff --git a/block/elevator.c b/block/elevator.c index 2d511f9105e1..1975b619c86d 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -79,7 +79,8 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) | |||
79 | /* | 79 | /* |
80 | * Don't merge file system requests and discard requests | 80 | * Don't merge file system requests and discard requests |
81 | */ | 81 | */ |
82 | if (bio_discard(bio) != bio_discard(rq->bio)) | 82 | if (bio_rw_flagged(bio, BIO_RW_DISCARD) != |
83 | bio_rw_flagged(rq->bio, BIO_RW_DISCARD)) | ||
83 | return 0; | 84 | return 0; |
84 | 85 | ||
85 | /* | 86 | /* |
@@ -100,19 +101,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) | |||
100 | if (bio_integrity(bio) != blk_integrity_rq(rq)) | 101 | if (bio_integrity(bio) != blk_integrity_rq(rq)) |
101 | return 0; | 102 | return 0; |
102 | 103 | ||
103 | /* | ||
104 | * Don't merge if failfast settings don't match. | ||
105 | * | ||
106 | * FIXME: The negation in front of each condition is necessary | ||
107 | * because bio and request flags use different bit positions | ||
108 | * and the accessors return those bits directly. This | ||
109 | * ugliness will soon go away. | ||
110 | */ | ||
111 | if (!bio_failfast_dev(bio) != !blk_failfast_dev(rq) || | ||
112 | !bio_failfast_transport(bio) != !blk_failfast_transport(rq) || | ||
113 | !bio_failfast_driver(bio) != !blk_failfast_driver(rq)) | ||
114 | return 0; | ||
115 | |||
116 | if (!elv_iosched_allow_merge(rq, bio)) | 104 | if (!elv_iosched_allow_merge(rq, bio)) |
117 | return 0; | 105 | return 0; |
118 | 106 | ||
diff --git a/block/genhd.c b/block/genhd.c index f4c64c2b303a..5b76bf55d05c 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -869,6 +869,7 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | |||
869 | static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); | 869 | static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL); |
870 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); | 870 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); |
871 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 871 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
872 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | ||
872 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 873 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
873 | static struct device_attribute dev_attr_fail = | 874 | static struct device_attribute dev_attr_fail = |
874 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 875 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
@@ -888,6 +889,7 @@ static struct attribute *disk_attrs[] = { | |||
888 | &dev_attr_alignment_offset.attr, | 889 | &dev_attr_alignment_offset.attr, |
889 | &dev_attr_capability.attr, | 890 | &dev_attr_capability.attr, |
890 | &dev_attr_stat.attr, | 891 | &dev_attr_stat.attr, |
892 | &dev_attr_inflight.attr, | ||
891 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 893 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
892 | &dev_attr_fail.attr, | 894 | &dev_attr_fail.attr, |
893 | #endif | 895 | #endif |
@@ -1053,7 +1055,7 @@ static int diskstats_show(struct seq_file *seqf, void *v) | |||
1053 | part_stat_read(hd, merges[1]), | 1055 | part_stat_read(hd, merges[1]), |
1054 | (unsigned long long)part_stat_read(hd, sectors[1]), | 1056 | (unsigned long long)part_stat_read(hd, sectors[1]), |
1055 | jiffies_to_msecs(part_stat_read(hd, ticks[1])), | 1057 | jiffies_to_msecs(part_stat_read(hd, ticks[1])), |
1056 | hd->in_flight, | 1058 | part_in_flight(hd), |
1057 | jiffies_to_msecs(part_stat_read(hd, io_ticks)), | 1059 | jiffies_to_msecs(part_stat_read(hd, io_ticks)), |
1058 | jiffies_to_msecs(part_stat_read(hd, time_in_queue)) | 1060 | jiffies_to_msecs(part_stat_read(hd, time_in_queue)) |
1059 | ); | 1061 | ); |
@@ -1215,6 +1217,16 @@ void put_disk(struct gendisk *disk) | |||
1215 | 1217 | ||
1216 | EXPORT_SYMBOL(put_disk); | 1218 | EXPORT_SYMBOL(put_disk); |
1217 | 1219 | ||
1220 | static void set_disk_ro_uevent(struct gendisk *gd, int ro) | ||
1221 | { | ||
1222 | char event[] = "DISK_RO=1"; | ||
1223 | char *envp[] = { event, NULL }; | ||
1224 | |||
1225 | if (!ro) | ||
1226 | event[8] = '0'; | ||
1227 | kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp); | ||
1228 | } | ||
1229 | |||
1218 | void set_device_ro(struct block_device *bdev, int flag) | 1230 | void set_device_ro(struct block_device *bdev, int flag) |
1219 | { | 1231 | { |
1220 | bdev->bd_part->policy = flag; | 1232 | bdev->bd_part->policy = flag; |
@@ -1227,8 +1239,12 @@ void set_disk_ro(struct gendisk *disk, int flag) | |||
1227 | struct disk_part_iter piter; | 1239 | struct disk_part_iter piter; |
1228 | struct hd_struct *part; | 1240 | struct hd_struct *part; |
1229 | 1241 | ||
1230 | disk_part_iter_init(&piter, disk, | 1242 | if (disk->part0.policy != flag) { |
1231 | DISK_PITER_INCL_EMPTY | DISK_PITER_INCL_PART0); | 1243 | set_disk_ro_uevent(disk, flag); |
1244 | disk->part0.policy = flag; | ||
1245 | } | ||
1246 | |||
1247 | disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY); | ||
1232 | while ((part = disk_part_iter_next(&piter))) | 1248 | while ((part = disk_part_iter_next(&piter))) |
1233 | part->policy = flag; | 1249 | part->policy = flag; |
1234 | disk_part_iter_exit(&piter); | 1250 | disk_part_iter_exit(&piter); |
diff --git a/block/ioctl.c b/block/ioctl.c index 500e4c73cc52..d3e6b5827a34 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -112,22 +112,9 @@ static int blkdev_reread_part(struct block_device *bdev) | |||
112 | return res; | 112 | return res; |
113 | } | 113 | } |
114 | 114 | ||
115 | static void blk_ioc_discard_endio(struct bio *bio, int err) | ||
116 | { | ||
117 | if (err) { | ||
118 | if (err == -EOPNOTSUPP) | ||
119 | set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); | ||
120 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
121 | } | ||
122 | complete(bio->bi_private); | ||
123 | } | ||
124 | |||
125 | static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, | 115 | static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, |
126 | uint64_t len) | 116 | uint64_t len) |
127 | { | 117 | { |
128 | struct request_queue *q = bdev_get_queue(bdev); | ||
129 | int ret = 0; | ||
130 | |||
131 | if (start & 511) | 118 | if (start & 511) |
132 | return -EINVAL; | 119 | return -EINVAL; |
133 | if (len & 511) | 120 | if (len & 511) |
@@ -137,40 +124,8 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, | |||
137 | 124 | ||
138 | if (start + len > (bdev->bd_inode->i_size >> 9)) | 125 | if (start + len > (bdev->bd_inode->i_size >> 9)) |
139 | return -EINVAL; | 126 | return -EINVAL; |
140 | 127 | return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, | |
141 | if (!q->prepare_discard_fn) | 128 | DISCARD_FL_WAIT); |
142 | return -EOPNOTSUPP; | ||
143 | |||
144 | while (len && !ret) { | ||
145 | DECLARE_COMPLETION_ONSTACK(wait); | ||
146 | struct bio *bio; | ||
147 | |||
148 | bio = bio_alloc(GFP_KERNEL, 0); | ||
149 | |||
150 | bio->bi_end_io = blk_ioc_discard_endio; | ||
151 | bio->bi_bdev = bdev; | ||
152 | bio->bi_private = &wait; | ||
153 | bio->bi_sector = start; | ||
154 | |||
155 | if (len > queue_max_hw_sectors(q)) { | ||
156 | bio->bi_size = queue_max_hw_sectors(q) << 9; | ||
157 | len -= queue_max_hw_sectors(q); | ||
158 | start += queue_max_hw_sectors(q); | ||
159 | } else { | ||
160 | bio->bi_size = len << 9; | ||
161 | len = 0; | ||
162 | } | ||
163 | submit_bio(DISCARD_NOBARRIER, bio); | ||
164 | |||
165 | wait_for_completion(&wait); | ||
166 | |||
167 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) | ||
168 | ret = -EOPNOTSUPP; | ||
169 | else if (!bio_flagged(bio, BIO_UPTODATE)) | ||
170 | ret = -EIO; | ||
171 | bio_put(bio); | ||
172 | } | ||
173 | return ret; | ||
174 | } | 129 | } |
175 | 130 | ||
176 | static int put_ushort(unsigned long arg, unsigned short val) | 131 | static int put_ushort(unsigned long arg, unsigned short val) |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 95d344971eda..b6cd571adbf2 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -172,6 +172,9 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) | |||
172 | BUG(); | 172 | BUG(); |
173 | bio_endio(bio, -ENXIO); | 173 | bio_endio(bio, -ENXIO); |
174 | return 0; | 174 | return 0; |
175 | } else if (bio_rw_flagged(bio, BIO_RW_BARRIER)) { | ||
176 | bio_endio(bio, -EOPNOTSUPP); | ||
177 | return 0; | ||
175 | } else if (bio->bi_io_vec == NULL) { | 178 | } else if (bio->bi_io_vec == NULL) { |
176 | printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); | 179 | printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); |
177 | BUG(); | 180 | BUG(); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a52cc7fe45ea..0589dfbbd7db 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -3889,7 +3889,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3889 | int j = 0; | 3889 | int j = 0; |
3890 | int rc; | 3890 | int rc; |
3891 | int dac, return_code; | 3891 | int dac, return_code; |
3892 | InquiryData_struct *inq_buff = NULL; | 3892 | InquiryData_struct *inq_buff; |
3893 | 3893 | ||
3894 | if (reset_devices) { | 3894 | if (reset_devices) { |
3895 | /* Reset the controller with a PCI power-cycle */ | 3895 | /* Reset the controller with a PCI power-cycle */ |
@@ -4029,6 +4029,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4029 | printk(KERN_WARNING "cciss: unable to determine firmware" | 4029 | printk(KERN_WARNING "cciss: unable to determine firmware" |
4030 | " version of controller\n"); | 4030 | " version of controller\n"); |
4031 | } | 4031 | } |
4032 | kfree(inq_buff); | ||
4032 | 4033 | ||
4033 | cciss_procinit(i); | 4034 | cciss_procinit(i); |
4034 | 4035 | ||
@@ -4045,7 +4046,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4045 | return 1; | 4046 | return 1; |
4046 | 4047 | ||
4047 | clean4: | 4048 | clean4: |
4048 | kfree(inq_buff); | ||
4049 | kfree(hba[i]->cmd_pool_bits); | 4049 | kfree(hba[i]->cmd_pool_bits); |
4050 | if (hba[i]->cmd_pool) | 4050 | if (hba[i]->cmd_pool) |
4051 | pci_free_consistent(hba[i]->pdev, | 4051 | pci_free_consistent(hba[i]->pdev, |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 5757188cd1fb..bbb79441d895 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -475,7 +475,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
475 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; | 475 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; |
476 | 476 | ||
477 | if (bio_rw(bio) == WRITE) { | 477 | if (bio_rw(bio) == WRITE) { |
478 | int barrier = bio_barrier(bio); | 478 | bool barrier = bio_rw_flagged(bio, BIO_RW_BARRIER); |
479 | struct file *file = lo->lo_backing_file; | 479 | struct file *file = lo->lo_backing_file; |
480 | 480 | ||
481 | if (barrier) { | 481 | if (barrier) { |
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 911dfd98d813..9f3518c515a1 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -219,8 +219,6 @@ static int pcd_sector; /* address of next requested sector */ | |||
219 | static int pcd_count; /* number of blocks still to do */ | 219 | static int pcd_count; /* number of blocks still to do */ |
220 | static char *pcd_buf; /* buffer for request in progress */ | 220 | static char *pcd_buf; /* buffer for request in progress */ |
221 | 221 | ||
222 | static int pcd_warned; /* Have we logged a phase warning ? */ | ||
223 | |||
224 | /* kernel glue structures */ | 222 | /* kernel glue structures */ |
225 | 223 | ||
226 | static int pcd_block_open(struct block_device *bdev, fmode_t mode) | 224 | static int pcd_block_open(struct block_device *bdev, fmode_t mode) |
@@ -417,12 +415,10 @@ static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun) | |||
417 | printk | 415 | printk |
418 | ("%s: %s: Unexpected phase %d, d=%d, k=%d\n", | 416 | ("%s: %s: Unexpected phase %d, d=%d, k=%d\n", |
419 | cd->name, fun, p, d, k); | 417 | cd->name, fun, p, d, k); |
420 | if ((verbose < 2) && !pcd_warned) { | 418 | if (verbose < 2) |
421 | pcd_warned = 1; | 419 | printk_once( |
422 | printk | 420 | "%s: WARNING: ATAPI phase errors\n", |
423 | ("%s: WARNING: ATAPI phase errors\n", | 421 | cd->name); |
424 | cd->name); | ||
425 | } | ||
426 | mdelay(1); | 422 | mdelay(1); |
427 | } | 423 | } |
428 | if (k++ > PCD_TMO) { | 424 | if (k++ > PCD_TMO) { |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index da403b6a7f43..f5cd2e83ebcc 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -1564,15 +1564,13 @@ static int carm_init_shm(struct carm_host *host) | |||
1564 | 1564 | ||
1565 | static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 1565 | static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
1566 | { | 1566 | { |
1567 | static unsigned int printed_version; | ||
1568 | struct carm_host *host; | 1567 | struct carm_host *host; |
1569 | unsigned int pci_dac; | 1568 | unsigned int pci_dac; |
1570 | int rc; | 1569 | int rc; |
1571 | struct request_queue *q; | 1570 | struct request_queue *q; |
1572 | unsigned int i; | 1571 | unsigned int i; |
1573 | 1572 | ||
1574 | if (!printed_version++) | 1573 | printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); |
1575 | printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); | ||
1576 | 1574 | ||
1577 | rc = pci_enable_device(pdev); | 1575 | rc = pci_enable_device(pdev); |
1578 | if (rc) | 1576 | if (rc) |
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 390d69bb7c48..b441ce3832e9 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -416,15 +416,9 @@ retry: | |||
416 | goto retry; | 416 | goto retry; |
417 | } | 417 | } |
418 | if (we.max_disk > (MAX_DISKNO - 1)) { | 418 | if (we.max_disk > (MAX_DISKNO - 1)) { |
419 | static int warned; | 419 | printk_once(VIOD_KERN_INFO |
420 | 420 | "Only examining the first %d of %d disks connected\n", | |
421 | if (warned == 0) { | 421 | MAX_DISKNO, we.max_disk + 1); |
422 | warned++; | ||
423 | printk(VIOD_KERN_INFO | ||
424 | "Only examining the first %d " | ||
425 | "of %d disks connected\n", | ||
426 | MAX_DISKNO, we.max_disk + 1); | ||
427 | } | ||
428 | } | 422 | } |
429 | 423 | ||
430 | /* Send the close event to OS/400. We DON'T expect a response */ | 424 | /* Send the close event to OS/400. We DON'T expect a response */ |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 33f179e66bf5..cc9dc79b0784 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1129,7 +1129,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1129 | if (error == -EOPNOTSUPP) | 1129 | if (error == -EOPNOTSUPP) |
1130 | goto out; | 1130 | goto out; |
1131 | 1131 | ||
1132 | if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) | 1132 | if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD)) |
1133 | goto out; | 1133 | goto out; |
1134 | 1134 | ||
1135 | if (unlikely(error)) { | 1135 | if (unlikely(error)) { |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 3e563d251733..e0efc1adcaff 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -285,7 +285,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio, | |||
285 | if (!error) | 285 | if (!error) |
286 | return 0; /* I/O complete */ | 286 | return 0; /* I/O complete */ |
287 | 287 | ||
288 | if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) | 288 | if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD)) |
289 | return error; | 289 | return error; |
290 | 290 | ||
291 | if (error == -EOPNOTSUPP) | 291 | if (error == -EOPNOTSUPP) |
@@ -336,7 +336,7 @@ static void stripe_io_hints(struct dm_target *ti, | |||
336 | unsigned chunk_size = (sc->chunk_mask + 1) << 9; | 336 | unsigned chunk_size = (sc->chunk_mask + 1) << 9; |
337 | 337 | ||
338 | blk_limits_io_min(limits, chunk_size); | 338 | blk_limits_io_min(limits, chunk_size); |
339 | limits->io_opt = chunk_size * sc->stripes; | 339 | blk_limits_io_opt(limits, chunk_size * sc->stripes); |
340 | } | 340 | } |
341 | 341 | ||
342 | static struct target_type stripe_target = { | 342 | static struct target_type stripe_target = { |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index b4845b14740d..eee28fac210c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -130,7 +130,7 @@ struct mapped_device { | |||
130 | /* | 130 | /* |
131 | * A list of ios that arrived while we were suspended. | 131 | * A list of ios that arrived while we were suspended. |
132 | */ | 132 | */ |
133 | atomic_t pending; | 133 | atomic_t pending[2]; |
134 | wait_queue_head_t wait; | 134 | wait_queue_head_t wait; |
135 | struct work_struct work; | 135 | struct work_struct work; |
136 | struct bio_list deferred; | 136 | struct bio_list deferred; |
@@ -453,13 +453,14 @@ static void start_io_acct(struct dm_io *io) | |||
453 | { | 453 | { |
454 | struct mapped_device *md = io->md; | 454 | struct mapped_device *md = io->md; |
455 | int cpu; | 455 | int cpu; |
456 | int rw = bio_data_dir(io->bio); | ||
456 | 457 | ||
457 | io->start_time = jiffies; | 458 | io->start_time = jiffies; |
458 | 459 | ||
459 | cpu = part_stat_lock(); | 460 | cpu = part_stat_lock(); |
460 | part_round_stats(cpu, &dm_disk(md)->part0); | 461 | part_round_stats(cpu, &dm_disk(md)->part0); |
461 | part_stat_unlock(); | 462 | part_stat_unlock(); |
462 | dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending); | 463 | dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]); |
463 | } | 464 | } |
464 | 465 | ||
465 | static void end_io_acct(struct dm_io *io) | 466 | static void end_io_acct(struct dm_io *io) |
@@ -479,8 +480,9 @@ static void end_io_acct(struct dm_io *io) | |||
479 | * After this is decremented the bio must not be touched if it is | 480 | * After this is decremented the bio must not be touched if it is |
480 | * a barrier. | 481 | * a barrier. |
481 | */ | 482 | */ |
482 | dm_disk(md)->part0.in_flight = pending = | 483 | dm_disk(md)->part0.in_flight[rw] = pending = |
483 | atomic_dec_return(&md->pending); | 484 | atomic_dec_return(&md->pending[rw]); |
485 | pending += atomic_read(&md->pending[rw^0x1]); | ||
484 | 486 | ||
485 | /* nudge anyone waiting on suspend queue */ | 487 | /* nudge anyone waiting on suspend queue */ |
486 | if (!pending) | 488 | if (!pending) |
@@ -586,7 +588,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
586 | */ | 588 | */ |
587 | spin_lock_irqsave(&md->deferred_lock, flags); | 589 | spin_lock_irqsave(&md->deferred_lock, flags); |
588 | if (__noflush_suspending(md)) { | 590 | if (__noflush_suspending(md)) { |
589 | if (!bio_barrier(io->bio)) | 591 | if (!bio_rw_flagged(io->bio, BIO_RW_BARRIER)) |
590 | bio_list_add_head(&md->deferred, | 592 | bio_list_add_head(&md->deferred, |
591 | io->bio); | 593 | io->bio); |
592 | } else | 594 | } else |
@@ -598,7 +600,7 @@ static void dec_pending(struct dm_io *io, int error) | |||
598 | io_error = io->error; | 600 | io_error = io->error; |
599 | bio = io->bio; | 601 | bio = io->bio; |
600 | 602 | ||
601 | if (bio_barrier(bio)) { | 603 | if (bio_rw_flagged(bio, BIO_RW_BARRIER)) { |
602 | /* | 604 | /* |
603 | * There can be just one barrier request so we use | 605 | * There can be just one barrier request so we use |
604 | * a per-device variable for error reporting. | 606 | * a per-device variable for error reporting. |
@@ -1209,7 +1211,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) | |||
1209 | 1211 | ||
1210 | ci.map = dm_get_table(md); | 1212 | ci.map = dm_get_table(md); |
1211 | if (unlikely(!ci.map)) { | 1213 | if (unlikely(!ci.map)) { |
1212 | if (!bio_barrier(bio)) | 1214 | if (!bio_rw_flagged(bio, BIO_RW_BARRIER)) |
1213 | bio_io_error(bio); | 1215 | bio_io_error(bio); |
1214 | else | 1216 | else |
1215 | if (!md->barrier_error) | 1217 | if (!md->barrier_error) |
@@ -1321,7 +1323,7 @@ static int _dm_request(struct request_queue *q, struct bio *bio) | |||
1321 | * we have to queue this io for later. | 1323 | * we have to queue this io for later. |
1322 | */ | 1324 | */ |
1323 | if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) || | 1325 | if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) || |
1324 | unlikely(bio_barrier(bio))) { | 1326 | unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
1325 | up_read(&md->io_lock); | 1327 | up_read(&md->io_lock); |
1326 | 1328 | ||
1327 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) && | 1329 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) && |
@@ -1344,7 +1346,7 @@ static int dm_make_request(struct request_queue *q, struct bio *bio) | |||
1344 | { | 1346 | { |
1345 | struct mapped_device *md = q->queuedata; | 1347 | struct mapped_device *md = q->queuedata; |
1346 | 1348 | ||
1347 | if (unlikely(bio_barrier(bio))) { | 1349 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
1348 | bio_endio(bio, -EOPNOTSUPP); | 1350 | bio_endio(bio, -EOPNOTSUPP); |
1349 | return 0; | 1351 | return 0; |
1350 | } | 1352 | } |
@@ -1785,7 +1787,8 @@ static struct mapped_device *alloc_dev(int minor) | |||
1785 | if (!md->disk) | 1787 | if (!md->disk) |
1786 | goto bad_disk; | 1788 | goto bad_disk; |
1787 | 1789 | ||
1788 | atomic_set(&md->pending, 0); | 1790 | atomic_set(&md->pending[0], 0); |
1791 | atomic_set(&md->pending[1], 0); | ||
1789 | init_waitqueue_head(&md->wait); | 1792 | init_waitqueue_head(&md->wait); |
1790 | INIT_WORK(&md->work, dm_wq_work); | 1793 | INIT_WORK(&md->work, dm_wq_work); |
1791 | init_waitqueue_head(&md->eventq); | 1794 | init_waitqueue_head(&md->eventq); |
@@ -2088,7 +2091,8 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) | |||
2088 | break; | 2091 | break; |
2089 | } | 2092 | } |
2090 | spin_unlock_irqrestore(q->queue_lock, flags); | 2093 | spin_unlock_irqrestore(q->queue_lock, flags); |
2091 | } else if (!atomic_read(&md->pending)) | 2094 | } else if (!atomic_read(&md->pending[0]) && |
2095 | !atomic_read(&md->pending[1])) | ||
2092 | break; | 2096 | break; |
2093 | 2097 | ||
2094 | if (interruptible == TASK_INTERRUPTIBLE && | 2098 | if (interruptible == TASK_INTERRUPTIBLE && |
@@ -2164,7 +2168,7 @@ static void dm_wq_work(struct work_struct *work) | |||
2164 | if (dm_request_based(md)) | 2168 | if (dm_request_based(md)) |
2165 | generic_make_request(c); | 2169 | generic_make_request(c); |
2166 | else { | 2170 | else { |
2167 | if (bio_barrier(c)) | 2171 | if (bio_rw_flagged(c, BIO_RW_BARRIER)) |
2168 | process_barrier(md, c); | 2172 | process_barrier(md, c); |
2169 | else | 2173 | else |
2170 | __split_and_process_bio(md, c); | 2174 | __split_and_process_bio(md, c); |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 5fe39c2a3d2b..ea4842905444 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -288,7 +288,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
288 | sector_t start_sector; | 288 | sector_t start_sector; |
289 | int cpu; | 289 | int cpu; |
290 | 290 | ||
291 | if (unlikely(bio_barrier(bio))) { | 291 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
292 | bio_endio(bio, -EOPNOTSUPP); | 292 | bio_endio(bio, -EOPNOTSUPP); |
293 | return 0; | 293 | return 0; |
294 | } | 294 | } |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 7140909f6662..89e76819f61f 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -90,7 +90,7 @@ static void multipath_end_request(struct bio *bio, int error) | |||
90 | 90 | ||
91 | if (uptodate) | 91 | if (uptodate) |
92 | multipath_end_bh_io(mp_bh, 0); | 92 | multipath_end_bh_io(mp_bh, 0); |
93 | else if (!bio_rw_ahead(bio)) { | 93 | else if (!bio_rw_flagged(bio, BIO_RW_AHEAD)) { |
94 | /* | 94 | /* |
95 | * oops, IO error: | 95 | * oops, IO error: |
96 | */ | 96 | */ |
@@ -144,7 +144,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) | |||
144 | const int rw = bio_data_dir(bio); | 144 | const int rw = bio_data_dir(bio); |
145 | int cpu; | 145 | int cpu; |
146 | 146 | ||
147 | if (unlikely(bio_barrier(bio))) { | 147 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
148 | bio_endio(bio, -EOPNOTSUPP); | 148 | bio_endio(bio, -EOPNOTSUPP); |
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 898e2bdfee47..f845ed98fec9 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -448,7 +448,7 @@ static int raid0_make_request(struct request_queue *q, struct bio *bio) | |||
448 | const int rw = bio_data_dir(bio); | 448 | const int rw = bio_data_dir(bio); |
449 | int cpu; | 449 | int cpu; |
450 | 450 | ||
451 | if (unlikely(bio_barrier(bio))) { | 451 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
452 | bio_endio(bio, -EOPNOTSUPP); | 452 | bio_endio(bio, -EOPNOTSUPP); |
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 8726fd7ebce5..ff7ed3335995 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -782,8 +782,9 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
782 | struct bio_list bl; | 782 | struct bio_list bl; |
783 | struct page **behind_pages = NULL; | 783 | struct page **behind_pages = NULL; |
784 | const int rw = bio_data_dir(bio); | 784 | const int rw = bio_data_dir(bio); |
785 | const int do_sync = bio_sync(bio); | 785 | const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); |
786 | int cpu, do_barriers; | 786 | int cpu; |
787 | bool do_barriers; | ||
787 | mdk_rdev_t *blocked_rdev; | 788 | mdk_rdev_t *blocked_rdev; |
788 | 789 | ||
789 | /* | 790 | /* |
@@ -797,7 +798,8 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
797 | 798 | ||
798 | md_write_start(mddev, bio); /* wait on superblock update early */ | 799 | md_write_start(mddev, bio); /* wait on superblock update early */ |
799 | 800 | ||
800 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | 801 | if (unlikely(!mddev->barriers_work && |
802 | bio_rw_flagged(bio, BIO_RW_BARRIER))) { | ||
801 | if (rw == WRITE) | 803 | if (rw == WRITE) |
802 | md_write_end(mddev); | 804 | md_write_end(mddev); |
803 | bio_endio(bio, -EOPNOTSUPP); | 805 | bio_endio(bio, -EOPNOTSUPP); |
@@ -925,7 +927,7 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
925 | atomic_set(&r1_bio->remaining, 0); | 927 | atomic_set(&r1_bio->remaining, 0); |
926 | atomic_set(&r1_bio->behind_remaining, 0); | 928 | atomic_set(&r1_bio->behind_remaining, 0); |
927 | 929 | ||
928 | do_barriers = bio_barrier(bio); | 930 | do_barriers = bio_rw_flagged(bio, BIO_RW_BARRIER); |
929 | if (do_barriers) | 931 | if (do_barriers) |
930 | set_bit(R1BIO_Barrier, &r1_bio->state); | 932 | set_bit(R1BIO_Barrier, &r1_bio->state); |
931 | 933 | ||
@@ -1600,7 +1602,7 @@ static void raid1d(mddev_t *mddev) | |||
1600 | * We already have a nr_pending reference on these rdevs. | 1602 | * We already have a nr_pending reference on these rdevs. |
1601 | */ | 1603 | */ |
1602 | int i; | 1604 | int i; |
1603 | const int do_sync = bio_sync(r1_bio->master_bio); | 1605 | const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO); |
1604 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1606 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
1605 | clear_bit(R1BIO_Barrier, &r1_bio->state); | 1607 | clear_bit(R1BIO_Barrier, &r1_bio->state); |
1606 | for (i=0; i < conf->raid_disks; i++) | 1608 | for (i=0; i < conf->raid_disks; i++) |
@@ -1654,7 +1656,7 @@ static void raid1d(mddev_t *mddev) | |||
1654 | (unsigned long long)r1_bio->sector); | 1656 | (unsigned long long)r1_bio->sector); |
1655 | raid_end_bio_io(r1_bio); | 1657 | raid_end_bio_io(r1_bio); |
1656 | } else { | 1658 | } else { |
1657 | const int do_sync = bio_sync(r1_bio->master_bio); | 1659 | const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO); |
1658 | r1_bio->bios[r1_bio->read_disk] = | 1660 | r1_bio->bios[r1_bio->read_disk] = |
1659 | mddev->ro ? IO_BLOCKED : NULL; | 1661 | mddev->ro ? IO_BLOCKED : NULL; |
1660 | r1_bio->read_disk = disk; | 1662 | r1_bio->read_disk = disk; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3d9020cf6f6e..d0a2152e064f 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -796,12 +796,12 @@ static int make_request(struct request_queue *q, struct bio * bio) | |||
796 | int i; | 796 | int i; |
797 | int chunk_sects = conf->chunk_mask + 1; | 797 | int chunk_sects = conf->chunk_mask + 1; |
798 | const int rw = bio_data_dir(bio); | 798 | const int rw = bio_data_dir(bio); |
799 | const int do_sync = bio_sync(bio); | 799 | const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); |
800 | struct bio_list bl; | 800 | struct bio_list bl; |
801 | unsigned long flags; | 801 | unsigned long flags; |
802 | mdk_rdev_t *blocked_rdev; | 802 | mdk_rdev_t *blocked_rdev; |
803 | 803 | ||
804 | if (unlikely(bio_barrier(bio))) { | 804 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { |
805 | bio_endio(bio, -EOPNOTSUPP); | 805 | bio_endio(bio, -EOPNOTSUPP); |
806 | return 0; | 806 | return 0; |
807 | } | 807 | } |
@@ -1610,7 +1610,7 @@ static void raid10d(mddev_t *mddev) | |||
1610 | raid_end_bio_io(r10_bio); | 1610 | raid_end_bio_io(r10_bio); |
1611 | bio_put(bio); | 1611 | bio_put(bio); |
1612 | } else { | 1612 | } else { |
1613 | const int do_sync = bio_sync(r10_bio->master_bio); | 1613 | const bool do_sync = bio_rw_flagged(r10_bio->master_bio, BIO_RW_SYNCIO); |
1614 | bio_put(bio); | 1614 | bio_put(bio); |
1615 | rdev = conf->mirrors[mirror].rdev; | 1615 | rdev = conf->mirrors[mirror].rdev; |
1616 | if (printk_ratelimit()) | 1616 | if (printk_ratelimit()) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index b8a2c5dc67ba..826eb3467357 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3606,7 +3606,7 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3606 | const int rw = bio_data_dir(bi); | 3606 | const int rw = bio_data_dir(bi); |
3607 | int cpu, remaining; | 3607 | int cpu, remaining; |
3608 | 3608 | ||
3609 | if (unlikely(bio_barrier(bi))) { | 3609 | if (unlikely(bio_rw_flagged(bi, BIO_RW_BARRIER))) { |
3610 | bio_endio(bi, -EOPNOTSUPP); | 3610 | bio_endio(bi, -EOPNOTSUPP); |
3611 | return 0; | 3611 | return 0; |
3612 | } | 3612 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 662024d86949..5987da857103 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -898,8 +898,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
898 | scsi_print_sense("", cmd); | 898 | scsi_print_sense("", cmd); |
899 | scsi_print_command(cmd); | 899 | scsi_print_command(cmd); |
900 | } | 900 | } |
901 | blk_end_request_all(req, -EIO); | 901 | if (blk_end_request_err(req, -EIO)) |
902 | scsi_next_command(cmd); | 902 | scsi_requeue_command(q, cmd); |
903 | else | ||
904 | scsi_next_command(cmd); | ||
903 | break; | 905 | break; |
904 | case ACTION_REPREP: | 906 | case ACTION_REPREP: |
905 | /* Unprep the request and put it back at the head of the queue. | 907 | /* Unprep the request and put it back at the head of the queue. |
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c index 84724187ec3e..ac8577358ba0 100644 --- a/drivers/staging/dst/dcore.c +++ b/drivers/staging/dst/dcore.c | |||
@@ -112,8 +112,9 @@ static int dst_request(struct request_queue *q, struct bio *bio) | |||
112 | * I worked with. | 112 | * I worked with. |
113 | * | 113 | * |
114 | * Empty barriers are not allowed anyway, see 51fd77bd9f512 | 114 | * Empty barriers are not allowed anyway, see 51fd77bd9f512 |
115 | * for example, although later it was changed to bio_discard() | 115 | * for example, although later it was changed to |
116 | * only, which does not work in this case. | 116 | * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not |
117 | * work in this case. | ||
117 | */ | 118 | */ |
118 | //err = -EOPNOTSUPP; | 119 | //err = -EOPNOTSUPP; |
119 | err = 0; | 120 | err = 0; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 72a2b9c28e9f..535f85ba104f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1511,7 +1511,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, | |||
1511 | static void btrfs_issue_discard(struct block_device *bdev, | 1511 | static void btrfs_issue_discard(struct block_device *bdev, |
1512 | u64 start, u64 len) | 1512 | u64 start, u64 len) |
1513 | { | 1513 | { |
1514 | blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL); | 1514 | blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, |
1515 | DISCARD_FL_BARRIER); | ||
1515 | } | 1516 | } |
1516 | #endif | 1517 | #endif |
1517 | 1518 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 5dbefd11b4af..5cf405b0828d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -260,7 +260,7 @@ loop_lock: | |||
260 | num_run++; | 260 | num_run++; |
261 | batch_run++; | 261 | batch_run++; |
262 | 262 | ||
263 | if (bio_sync(cur)) | 263 | if (bio_rw_flagged(cur, BIO_RW_SYNCIO)) |
264 | num_sync_run++; | 264 | num_sync_run++; |
265 | 265 | ||
266 | if (need_resched()) { | 266 | if (need_resched()) { |
@@ -2903,7 +2903,7 @@ static noinline int schedule_bio(struct btrfs_root *root, | |||
2903 | bio->bi_rw |= rw; | 2903 | bio->bi_rw |= rw; |
2904 | 2904 | ||
2905 | spin_lock(&device->io_lock); | 2905 | spin_lock(&device->io_lock); |
2906 | if (bio_sync(bio)) | 2906 | if (bio_rw_flagged(bio, BIO_RW_SYNCIO)) |
2907 | pending_bios = &device->pending_sync_bios; | 2907 | pending_bios = &device->pending_sync_bios; |
2908 | else | 2908 | else |
2909 | pending_bios = &device->pending_bios; | 2909 | pending_bios = &device->pending_bios; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 18d3a28554ac..28c590b7c9da 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -857,7 +857,8 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
857 | goto start_new_extent; | 857 | goto start_new_extent; |
858 | if ((start + nr_sects) != blk) { | 858 | if ((start + nr_sects) != blk) { |
859 | rv = blkdev_issue_discard(bdev, start, | 859 | rv = blkdev_issue_discard(bdev, start, |
860 | nr_sects, GFP_NOFS); | 860 | nr_sects, GFP_NOFS, |
861 | DISCARD_FL_BARRIER); | ||
861 | if (rv) | 862 | if (rv) |
862 | goto fail; | 863 | goto fail; |
863 | nr_sects = 0; | 864 | nr_sects = 0; |
@@ -871,7 +872,8 @@ start_new_extent: | |||
871 | } | 872 | } |
872 | } | 873 | } |
873 | if (nr_sects) { | 874 | if (nr_sects) { |
874 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS); | 875 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, |
876 | DISCARD_FL_BARRIER); | ||
875 | if (rv) | 877 | if (rv) |
876 | goto fail; | 878 | goto fail; |
877 | } | 879 | } |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index ea4e6cb29e13..619ba99dfe39 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -248,11 +248,19 @@ ssize_t part_stat_show(struct device *dev, | |||
248 | part_stat_read(p, merges[WRITE]), | 248 | part_stat_read(p, merges[WRITE]), |
249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), | 249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), |
250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), | 250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), |
251 | p->in_flight, | 251 | part_in_flight(p), |
252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), | 252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), |
253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); | 253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
254 | } | 254 | } |
255 | 255 | ||
256 | ssize_t part_inflight_show(struct device *dev, | ||
257 | struct device_attribute *attr, char *buf) | ||
258 | { | ||
259 | struct hd_struct *p = dev_to_part(dev); | ||
260 | |||
261 | return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); | ||
262 | } | ||
263 | |||
256 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 264 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
257 | ssize_t part_fail_show(struct device *dev, | 265 | ssize_t part_fail_show(struct device *dev, |
258 | struct device_attribute *attr, char *buf) | 266 | struct device_attribute *attr, char *buf) |
@@ -281,6 +289,7 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | |||
281 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 289 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
282 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 290 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
283 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 291 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
292 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | ||
284 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 293 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
285 | static struct device_attribute dev_attr_fail = | 294 | static struct device_attribute dev_attr_fail = |
286 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 295 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
@@ -292,6 +301,7 @@ static struct attribute *part_attrs[] = { | |||
292 | &dev_attr_size.attr, | 301 | &dev_attr_size.attr, |
293 | &dev_attr_alignment_offset.attr, | 302 | &dev_attr_alignment_offset.attr, |
294 | &dev_attr_stat.attr, | 303 | &dev_attr_stat.attr, |
304 | &dev_attr_inflight.attr, | ||
295 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 305 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
296 | &dev_attr_fail.attr, | 306 | &dev_attr_fail.attr, |
297 | #endif | 307 | #endif |
diff --git a/fs/splice.c b/fs/splice.c index 819023733f8e..7394e9e17534 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -502,8 +502,10 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
502 | len = left; | 502 | len = left; |
503 | 503 | ||
504 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); | 504 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); |
505 | if (ret > 0) | 505 | if (ret > 0) { |
506 | *ppos += ret; | 506 | *ppos += ret; |
507 | file_accessed(in); | ||
508 | } | ||
507 | 509 | ||
508 | return ret; | 510 | return ret; |
509 | } | 511 | } |
@@ -963,8 +965,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
963 | 965 | ||
964 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | 966 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); |
965 | ret = file_remove_suid(out); | 967 | ret = file_remove_suid(out); |
966 | if (!ret) | 968 | if (!ret) { |
969 | file_update_time(out); | ||
967 | ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); | 970 | ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); |
971 | } | ||
968 | mutex_unlock(&inode->i_mutex); | 972 | mutex_unlock(&inode->i_mutex); |
969 | } while (ret > 0); | 973 | } while (ret > 0); |
970 | splice_from_pipe_end(pipe, &sd); | 974 | splice_from_pipe_end(pipe, &sd); |
diff --git a/include/linux/bio.h b/include/linux/bio.h index 2892b710771c..5be93f18d842 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -142,56 +142,51 @@ struct bio { | |||
142 | * | 142 | * |
143 | * bit 0 -- data direction | 143 | * bit 0 -- data direction |
144 | * If not set, bio is a read from device. If set, it's a write to device. | 144 | * If not set, bio is a read from device. If set, it's a write to device. |
145 | * bit 1 -- rw-ahead when set | 145 | * bit 1 -- fail fast device errors |
146 | * bit 2 -- barrier | 146 | * bit 2 -- fail fast transport errors |
147 | * bit 3 -- fail fast driver errors | ||
148 | * bit 4 -- rw-ahead when set | ||
149 | * bit 5 -- barrier | ||
147 | * Insert a serialization point in the IO queue, forcing previously | 150 | * Insert a serialization point in the IO queue, forcing previously |
148 | * submitted IO to be completed before this one is issued. | 151 | * submitted IO to be completed before this one is issued. |
149 | * bit 3 -- synchronous I/O hint. | 152 | * bit 6 -- synchronous I/O hint. |
150 | * bit 4 -- Unplug the device immediately after submitting this bio. | 153 | * bit 7 -- Unplug the device immediately after submitting this bio. |
151 | * bit 5 -- metadata request | 154 | * bit 8 -- metadata request |
152 | * Used for tracing to differentiate metadata and data IO. May also | 155 | * Used for tracing to differentiate metadata and data IO. May also |
153 | * get some preferential treatment in the IO scheduler | 156 | * get some preferential treatment in the IO scheduler |
154 | * bit 6 -- discard sectors | 157 | * bit 9 -- discard sectors |
155 | * Informs the lower level device that this range of sectors is no longer | 158 | * Informs the lower level device that this range of sectors is no longer |
156 | * used by the file system and may thus be freed by the device. Used | 159 | * used by the file system and may thus be freed by the device. Used |
157 | * for flash based storage. | 160 | * for flash based storage. |
158 | * bit 7 -- fail fast device errors | ||
159 | * bit 8 -- fail fast transport errors | ||
160 | * bit 9 -- fail fast driver errors | ||
161 | * Don't want driver retries for any fast fail whatever the reason. | 161 | * Don't want driver retries for any fast fail whatever the reason. |
162 | * bit 10 -- Tell the IO scheduler not to wait for more requests after this | 162 | * bit 10 -- Tell the IO scheduler not to wait for more requests after this |
163 | one has been submitted, even if it is a SYNC request. | 163 | one has been submitted, even if it is a SYNC request. |
164 | */ | 164 | */ |
165 | #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ | 165 | enum bio_rw_flags { |
166 | #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ | 166 | BIO_RW, |
167 | #define BIO_RW_BARRIER 2 | 167 | BIO_RW_FAILFAST_DEV, |
168 | #define BIO_RW_SYNCIO 3 | 168 | BIO_RW_FAILFAST_TRANSPORT, |
169 | #define BIO_RW_UNPLUG 4 | 169 | BIO_RW_FAILFAST_DRIVER, |
170 | #define BIO_RW_META 5 | 170 | /* above flags must match REQ_* */ |
171 | #define BIO_RW_DISCARD 6 | 171 | BIO_RW_AHEAD, |
172 | #define BIO_RW_FAILFAST_DEV 7 | 172 | BIO_RW_BARRIER, |
173 | #define BIO_RW_FAILFAST_TRANSPORT 8 | 173 | BIO_RW_SYNCIO, |
174 | #define BIO_RW_FAILFAST_DRIVER 9 | 174 | BIO_RW_UNPLUG, |
175 | #define BIO_RW_NOIDLE 10 | 175 | BIO_RW_META, |
176 | 176 | BIO_RW_DISCARD, | |
177 | #define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) | 177 | BIO_RW_NOIDLE, |
178 | }; | ||
178 | 179 | ||
179 | /* | 180 | /* |
180 | * Old defines, these should eventually be replaced by direct usage of | 181 | * First four bits must match between bio->bi_rw and rq->cmd_flags, make |
181 | * bio_rw_flagged() | 182 | * that explicit here. |
182 | */ | 183 | */ |
183 | #define bio_barrier(bio) bio_rw_flagged(bio, BIO_RW_BARRIER) | 184 | #define BIO_RW_RQ_MASK 0xf |
184 | #define bio_sync(bio) bio_rw_flagged(bio, BIO_RW_SYNCIO) | 185 | |
185 | #define bio_unplug(bio) bio_rw_flagged(bio, BIO_RW_UNPLUG) | 186 | static inline bool bio_rw_flagged(struct bio *bio, enum bio_rw_flags flag) |
186 | #define bio_failfast_dev(bio) bio_rw_flagged(bio, BIO_RW_FAILFAST_DEV) | 187 | { |
187 | #define bio_failfast_transport(bio) \ | 188 | return (bio->bi_rw & (1 << flag)) != 0; |
188 | bio_rw_flagged(bio, BIO_RW_FAILFAST_TRANSPORT) | 189 | } |
189 | #define bio_failfast_driver(bio) \ | ||
190 | bio_rw_flagged(bio, BIO_RW_FAILFAST_DRIVER) | ||
191 | #define bio_rw_ahead(bio) bio_rw_flagged(bio, BIO_RW_AHEAD) | ||
192 | #define bio_rw_meta(bio) bio_rw_flagged(bio, BIO_RW_META) | ||
193 | #define bio_discard(bio) bio_rw_flagged(bio, BIO_RW_DISCARD) | ||
194 | #define bio_noidle(bio) bio_rw_flagged(bio, BIO_RW_NOIDLE) | ||
195 | 190 | ||
196 | /* | 191 | /* |
197 | * upper 16 bits of bi_rw define the io priority of this bio | 192 | * upper 16 bits of bi_rw define the io priority of this bio |
@@ -216,7 +211,7 @@ struct bio { | |||
216 | #define bio_offset(bio) bio_iovec((bio))->bv_offset | 211 | #define bio_offset(bio) bio_iovec((bio))->bv_offset |
217 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) | 212 | #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) |
218 | #define bio_sectors(bio) ((bio)->bi_size >> 9) | 213 | #define bio_sectors(bio) ((bio)->bi_size >> 9) |
219 | #define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio)) | 214 | #define bio_empty_barrier(bio) (bio_rw_flagged(bio, BIO_RW_BARRIER) && !bio_has_data(bio) && !bio_rw_flagged(bio, BIO_RW_DISCARD)) |
220 | 215 | ||
221 | static inline unsigned int bio_cur_bytes(struct bio *bio) | 216 | static inline unsigned int bio_cur_bytes(struct bio *bio) |
222 | { | 217 | { |
diff --git a/include/linux/blk-iopoll.h b/include/linux/blk-iopoll.h new file mode 100644 index 000000000000..308734d3d4a2 --- /dev/null +++ b/include/linux/blk-iopoll.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef BLK_IOPOLL_H | ||
2 | #define BLK_IOPOLL_H | ||
3 | |||
4 | struct blk_iopoll; | ||
5 | typedef int (blk_iopoll_fn)(struct blk_iopoll *, int); | ||
6 | |||
7 | struct blk_iopoll { | ||
8 | struct list_head list; | ||
9 | unsigned long state; | ||
10 | unsigned long data; | ||
11 | int weight; | ||
12 | int max; | ||
13 | blk_iopoll_fn *poll; | ||
14 | }; | ||
15 | |||
16 | enum { | ||
17 | IOPOLL_F_SCHED = 0, | ||
18 | IOPOLL_F_DISABLE = 1, | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * Returns 0 if we successfully set the IOPOLL_F_SCHED bit, indicating | ||
23 | * that we were the first to acquire this iop for scheduling. If this iop | ||
24 | * is currently disabled, return "failure". | ||
25 | */ | ||
26 | static inline int blk_iopoll_sched_prep(struct blk_iopoll *iop) | ||
27 | { | ||
28 | if (!test_bit(IOPOLL_F_DISABLE, &iop->state)) | ||
29 | return test_and_set_bit(IOPOLL_F_SCHED, &iop->state); | ||
30 | |||
31 | return 1; | ||
32 | } | ||
33 | |||
34 | static inline int blk_iopoll_disable_pending(struct blk_iopoll *iop) | ||
35 | { | ||
36 | return test_bit(IOPOLL_F_DISABLE, &iop->state); | ||
37 | } | ||
38 | |||
39 | extern void blk_iopoll_sched(struct blk_iopoll *); | ||
40 | extern void blk_iopoll_init(struct blk_iopoll *, int, blk_iopoll_fn *); | ||
41 | extern void blk_iopoll_complete(struct blk_iopoll *); | ||
42 | extern void __blk_iopoll_complete(struct blk_iopoll *); | ||
43 | extern void blk_iopoll_enable(struct blk_iopoll *); | ||
44 | extern void blk_iopoll_disable(struct blk_iopoll *); | ||
45 | |||
46 | extern int blk_iopoll_enabled; | ||
47 | |||
48 | #endif | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 69103e053c92..e23a86cae5ac 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -86,13 +86,14 @@ enum { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* | 88 | /* |
89 | * request type modified bits. first two bits match BIO_RW* bits, important | 89 | * request type modified bits. first four bits match BIO_RW* bits, important |
90 | */ | 90 | */ |
91 | enum rq_flag_bits { | 91 | enum rq_flag_bits { |
92 | __REQ_RW, /* not set, read. set, write */ | 92 | __REQ_RW, /* not set, read. set, write */ |
93 | __REQ_FAILFAST_DEV, /* no driver retries of device errors */ | 93 | __REQ_FAILFAST_DEV, /* no driver retries of device errors */ |
94 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ | 94 | __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ |
95 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ | 95 | __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ |
96 | /* above flags must match BIO_RW_* */ | ||
96 | __REQ_DISCARD, /* request to discard sectors */ | 97 | __REQ_DISCARD, /* request to discard sectors */ |
97 | __REQ_SORTED, /* elevator knows about this request */ | 98 | __REQ_SORTED, /* elevator knows about this request */ |
98 | __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ | 99 | __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ |
@@ -114,6 +115,7 @@ enum rq_flag_bits { | |||
114 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ | 115 | __REQ_INTEGRITY, /* integrity metadata has been remapped */ |
115 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ | 116 | __REQ_NOIDLE, /* Don't anticipate more IO after this one */ |
116 | __REQ_IO_STAT, /* account I/O stat */ | 117 | __REQ_IO_STAT, /* account I/O stat */ |
118 | __REQ_MIXED_MERGE, /* merge of different types, fail separately */ | ||
117 | __REQ_NR_BITS, /* stops here */ | 119 | __REQ_NR_BITS, /* stops here */ |
118 | }; | 120 | }; |
119 | 121 | ||
@@ -142,6 +144,10 @@ enum rq_flag_bits { | |||
142 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) | 144 | #define REQ_INTEGRITY (1 << __REQ_INTEGRITY) |
143 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) | 145 | #define REQ_NOIDLE (1 << __REQ_NOIDLE) |
144 | #define REQ_IO_STAT (1 << __REQ_IO_STAT) | 146 | #define REQ_IO_STAT (1 << __REQ_IO_STAT) |
147 | #define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) | ||
148 | |||
149 | #define REQ_FAILFAST_MASK (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | \ | ||
150 | REQ_FAILFAST_DRIVER) | ||
145 | 151 | ||
146 | #define BLK_MAX_CDB 16 | 152 | #define BLK_MAX_CDB 16 |
147 | 153 | ||
@@ -453,10 +459,12 @@ struct request_queue | |||
453 | #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ | 459 | #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ |
454 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ | 460 | #define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ |
455 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ | 461 | #define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ |
462 | #define QUEUE_FLAG_CQ 16 /* hardware does queuing */ | ||
456 | 463 | ||
457 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 464 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
458 | (1 << QUEUE_FLAG_CLUSTER) | \ | 465 | (1 << QUEUE_FLAG_CLUSTER) | \ |
459 | (1 << QUEUE_FLAG_STACKABLE)) | 466 | (1 << QUEUE_FLAG_STACKABLE) | \ |
467 | (1 << QUEUE_FLAG_SAME_COMP)) | ||
460 | 468 | ||
461 | static inline int queue_is_locked(struct request_queue *q) | 469 | static inline int queue_is_locked(struct request_queue *q) |
462 | { | 470 | { |
@@ -575,6 +583,7 @@ enum { | |||
575 | 583 | ||
576 | #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) | 584 | #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) |
577 | #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) | 585 | #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) |
586 | #define blk_queue_queuing(q) test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags) | ||
578 | #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) | 587 | #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) |
579 | #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) | 588 | #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) |
580 | #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) | 589 | #define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) |
@@ -828,11 +837,13 @@ static inline void blk_run_address_space(struct address_space *mapping) | |||
828 | } | 837 | } |
829 | 838 | ||
830 | /* | 839 | /* |
831 | * blk_rq_pos() : the current sector | 840 | * blk_rq_pos() : the current sector |
832 | * blk_rq_bytes() : bytes left in the entire request | 841 | * blk_rq_bytes() : bytes left in the entire request |
833 | * blk_rq_cur_bytes() : bytes left in the current segment | 842 | * blk_rq_cur_bytes() : bytes left in the current segment |
834 | * blk_rq_sectors() : sectors left in the entire request | 843 | * blk_rq_err_bytes() : bytes left till the next error boundary |
835 | * blk_rq_cur_sectors() : sectors left in the current segment | 844 | * blk_rq_sectors() : sectors left in the entire request |
845 | * blk_rq_cur_sectors() : sectors left in the current segment | ||
846 | * blk_rq_err_sectors() : sectors left till the next error boundary | ||
836 | */ | 847 | */ |
837 | static inline sector_t blk_rq_pos(const struct request *rq) | 848 | static inline sector_t blk_rq_pos(const struct request *rq) |
838 | { | 849 | { |
@@ -849,6 +860,8 @@ static inline int blk_rq_cur_bytes(const struct request *rq) | |||
849 | return rq->bio ? bio_cur_bytes(rq->bio) : 0; | 860 | return rq->bio ? bio_cur_bytes(rq->bio) : 0; |
850 | } | 861 | } |
851 | 862 | ||
863 | extern unsigned int blk_rq_err_bytes(const struct request *rq); | ||
864 | |||
852 | static inline unsigned int blk_rq_sectors(const struct request *rq) | 865 | static inline unsigned int blk_rq_sectors(const struct request *rq) |
853 | { | 866 | { |
854 | return blk_rq_bytes(rq) >> 9; | 867 | return blk_rq_bytes(rq) >> 9; |
@@ -859,6 +872,11 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq) | |||
859 | return blk_rq_cur_bytes(rq) >> 9; | 872 | return blk_rq_cur_bytes(rq) >> 9; |
860 | } | 873 | } |
861 | 874 | ||
875 | static inline unsigned int blk_rq_err_sectors(const struct request *rq) | ||
876 | { | ||
877 | return blk_rq_err_bytes(rq) >> 9; | ||
878 | } | ||
879 | |||
862 | /* | 880 | /* |
863 | * Request issue related functions. | 881 | * Request issue related functions. |
864 | */ | 882 | */ |
@@ -885,10 +903,12 @@ extern bool blk_end_request(struct request *rq, int error, | |||
885 | unsigned int nr_bytes); | 903 | unsigned int nr_bytes); |
886 | extern void blk_end_request_all(struct request *rq, int error); | 904 | extern void blk_end_request_all(struct request *rq, int error); |
887 | extern bool blk_end_request_cur(struct request *rq, int error); | 905 | extern bool blk_end_request_cur(struct request *rq, int error); |
906 | extern bool blk_end_request_err(struct request *rq, int error); | ||
888 | extern bool __blk_end_request(struct request *rq, int error, | 907 | extern bool __blk_end_request(struct request *rq, int error, |
889 | unsigned int nr_bytes); | 908 | unsigned int nr_bytes); |
890 | extern void __blk_end_request_all(struct request *rq, int error); | 909 | extern void __blk_end_request_all(struct request *rq, int error); |
891 | extern bool __blk_end_request_cur(struct request *rq, int error); | 910 | extern bool __blk_end_request_cur(struct request *rq, int error); |
911 | extern bool __blk_end_request_err(struct request *rq, int error); | ||
892 | 912 | ||
893 | extern void blk_complete_request(struct request *); | 913 | extern void blk_complete_request(struct request *); |
894 | extern void __blk_complete_request(struct request *); | 914 | extern void __blk_complete_request(struct request *); |
@@ -915,6 +935,7 @@ extern void blk_queue_alignment_offset(struct request_queue *q, | |||
915 | unsigned int alignment); | 935 | unsigned int alignment); |
916 | extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min); | 936 | extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min); |
917 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); | 937 | extern void blk_queue_io_min(struct request_queue *q, unsigned int min); |
938 | extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt); | ||
918 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); | 939 | extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt); |
919 | extern void blk_set_default_limits(struct queue_limits *lim); | 940 | extern void blk_set_default_limits(struct queue_limits *lim); |
920 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | 941 | extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, |
@@ -977,15 +998,18 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, | |||
977 | } | 998 | } |
978 | 999 | ||
979 | extern int blkdev_issue_flush(struct block_device *, sector_t *); | 1000 | extern int blkdev_issue_flush(struct block_device *, sector_t *); |
980 | extern int blkdev_issue_discard(struct block_device *, | 1001 | #define DISCARD_FL_WAIT 0x01 /* wait for completion */ |
981 | sector_t sector, sector_t nr_sects, gfp_t); | 1002 | #define DISCARD_FL_BARRIER 0x02 /* issue DISCARD_BARRIER request */ |
1003 | extern int blkdev_issue_discard(struct block_device *, sector_t sector, | ||
1004 | sector_t nr_sects, gfp_t, int flags); | ||
982 | 1005 | ||
983 | static inline int sb_issue_discard(struct super_block *sb, | 1006 | static inline int sb_issue_discard(struct super_block *sb, |
984 | sector_t block, sector_t nr_blocks) | 1007 | sector_t block, sector_t nr_blocks) |
985 | { | 1008 | { |
986 | block <<= (sb->s_blocksize_bits - 9); | 1009 | block <<= (sb->s_blocksize_bits - 9); |
987 | nr_blocks <<= (sb->s_blocksize_bits - 9); | 1010 | nr_blocks <<= (sb->s_blocksize_bits - 9); |
988 | return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL); | 1011 | return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL, |
1012 | DISCARD_FL_BARRIER); | ||
989 | } | 1013 | } |
990 | 1014 | ||
991 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); | 1015 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 37f53216998a..b21cf6b9c80b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -161,8 +161,8 @@ struct inodes_stat_t { | |||
161 | * These aren't really reads or writes, they pass down information about | 161 | * These aren't really reads or writes, they pass down information about |
162 | * parts of device that are now unused by the file system. | 162 | * parts of device that are now unused by the file system. |
163 | */ | 163 | */ |
164 | #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) | 164 | #define DISCARD_NOBARRIER (WRITE | (1 << BIO_RW_DISCARD)) |
165 | #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) | 165 | #define DISCARD_BARRIER (DISCARD_NOBARRIER | (1 << BIO_RW_BARRIER)) |
166 | 166 | ||
167 | #define SEL_IN 1 | 167 | #define SEL_IN 1 |
168 | #define SEL_OUT 2 | 168 | #define SEL_OUT 2 |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 45fc320a53c6..44263cb27121 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -98,7 +98,7 @@ struct hd_struct { | |||
98 | int make_it_fail; | 98 | int make_it_fail; |
99 | #endif | 99 | #endif |
100 | unsigned long stamp; | 100 | unsigned long stamp; |
101 | int in_flight; | 101 | int in_flight[2]; |
102 | #ifdef CONFIG_SMP | 102 | #ifdef CONFIG_SMP |
103 | struct disk_stats *dkstats; | 103 | struct disk_stats *dkstats; |
104 | #else | 104 | #else |
@@ -322,18 +322,23 @@ static inline void free_part_stats(struct hd_struct *part) | |||
322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | 322 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ |
323 | part_stat_add(cpu, gendiskp, field, -subnd) | 323 | part_stat_add(cpu, gendiskp, field, -subnd) |
324 | 324 | ||
325 | static inline void part_inc_in_flight(struct hd_struct *part) | 325 | static inline void part_inc_in_flight(struct hd_struct *part, int rw) |
326 | { | 326 | { |
327 | part->in_flight++; | 327 | part->in_flight[rw]++; |
328 | if (part->partno) | 328 | if (part->partno) |
329 | part_to_disk(part)->part0.in_flight++; | 329 | part_to_disk(part)->part0.in_flight[rw]++; |
330 | } | 330 | } |
331 | 331 | ||
332 | static inline void part_dec_in_flight(struct hd_struct *part) | 332 | static inline void part_dec_in_flight(struct hd_struct *part, int rw) |
333 | { | 333 | { |
334 | part->in_flight--; | 334 | part->in_flight[rw]--; |
335 | if (part->partno) | 335 | if (part->partno) |
336 | part_to_disk(part)->part0.in_flight--; | 336 | part_to_disk(part)->part0.in_flight[rw]--; |
337 | } | ||
338 | |||
339 | static inline int part_in_flight(struct hd_struct *part) | ||
340 | { | ||
341 | return part->in_flight[0] + part->in_flight[1]; | ||
337 | } | 342 | } |
338 | 343 | ||
339 | /* block/blk-core.c */ | 344 | /* block/blk-core.c */ |
@@ -546,6 +551,8 @@ extern ssize_t part_size_show(struct device *dev, | |||
546 | struct device_attribute *attr, char *buf); | 551 | struct device_attribute *attr, char *buf); |
547 | extern ssize_t part_stat_show(struct device *dev, | 552 | extern ssize_t part_stat_show(struct device *dev, |
548 | struct device_attribute *attr, char *buf); | 553 | struct device_attribute *attr, char *buf); |
554 | extern ssize_t part_inflight_show(struct device *dev, | ||
555 | struct device_attribute *attr, char *buf); | ||
549 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 556 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
550 | extern ssize_t part_fail_show(struct device *dev, | 557 | extern ssize_t part_fail_show(struct device *dev, |
551 | struct device_attribute *attr, char *buf); | 558 | struct device_attribute *attr, char *buf); |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 1ac57e522a1f..8e9e151f811e 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -348,6 +348,7 @@ enum | |||
348 | NET_TX_SOFTIRQ, | 348 | NET_TX_SOFTIRQ, |
349 | NET_RX_SOFTIRQ, | 349 | NET_RX_SOFTIRQ, |
350 | BLOCK_SOFTIRQ, | 350 | BLOCK_SOFTIRQ, |
351 | BLOCK_IOPOLL_SOFTIRQ, | ||
351 | TASKLET_SOFTIRQ, | 352 | TASKLET_SOFTIRQ, |
352 | SCHED_SOFTIRQ, | 353 | SCHED_SOFTIRQ, |
353 | HRTIMER_SOFTIRQ, | 354 | HRTIMER_SOFTIRQ, |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3125cff1c570..6bb59f707402 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -91,6 +91,7 @@ extern int sysctl_nr_trim_pages; | |||
91 | #ifdef CONFIG_RCU_TORTURE_TEST | 91 | #ifdef CONFIG_RCU_TORTURE_TEST |
92 | extern int rcutorture_runnable; | 92 | extern int rcutorture_runnable; |
93 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ | 93 | #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ |
94 | extern int blk_iopoll_enabled; | ||
94 | 95 | ||
95 | /* Constants used for minimum and maximum */ | 96 | /* Constants used for minimum and maximum */ |
96 | #ifdef CONFIG_DETECT_SOFTLOCKUP | 97 | #ifdef CONFIG_DETECT_SOFTLOCKUP |
@@ -997,7 +998,14 @@ static struct ctl_table kern_table[] = { | |||
997 | .proc_handler = &proc_dointvec, | 998 | .proc_handler = &proc_dointvec, |
998 | }, | 999 | }, |
999 | #endif | 1000 | #endif |
1000 | 1001 | { | |
1002 | .ctl_name = CTL_UNNUMBERED, | ||
1003 | .procname = "blk_iopoll", | ||
1004 | .data = &blk_iopoll_enabled, | ||
1005 | .maxlen = sizeof(int), | ||
1006 | .mode = 0644, | ||
1007 | .proc_handler = &proc_dointvec, | ||
1008 | }, | ||
1001 | /* | 1009 | /* |
1002 | * NOTE: do not add new entries to this table unless you have read | 1010 | * NOTE: do not add new entries to this table unless you have read |
1003 | * Documentation/sysctl/ctl_unnumbered.txt | 1011 | * Documentation/sysctl/ctl_unnumbered.txt |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 8ffdc0d23c53..74f1102e8749 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -161,7 +161,8 @@ static int discard_swap(struct swap_info_struct *si) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | err = blkdev_issue_discard(si->bdev, start_block, | 163 | err = blkdev_issue_discard(si->bdev, start_block, |
164 | nr_blocks, GFP_KERNEL); | 164 | nr_blocks, GFP_KERNEL, |
165 | DISCARD_FL_BARRIER); | ||
165 | if (err) | 166 | if (err) |
166 | break; | 167 | break; |
167 | 168 | ||
@@ -200,7 +201,8 @@ static void discard_swap_cluster(struct swap_info_struct *si, | |||
200 | start_block <<= PAGE_SHIFT - 9; | 201 | start_block <<= PAGE_SHIFT - 9; |
201 | nr_blocks <<= PAGE_SHIFT - 9; | 202 | nr_blocks <<= PAGE_SHIFT - 9; |
202 | if (blkdev_issue_discard(si->bdev, start_block, | 203 | if (blkdev_issue_discard(si->bdev, start_block, |
203 | nr_blocks, GFP_NOIO)) | 204 | nr_blocks, GFP_NOIO, |
205 | DISCARD_FL_BARRIER)) | ||
204 | break; | 206 | break; |
205 | } | 207 | } |
206 | 208 | ||