diff options
Diffstat (limited to 'block/blk-core.c')
| -rw-r--r-- | block/blk-core.c | 100 |
1 files changed, 63 insertions, 37 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index a824e49c0d0a..ca69f3d94100 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -64,11 +64,12 @@ static struct workqueue_struct *kblockd_workqueue; | |||
| 64 | 64 | ||
| 65 | static void drive_stat_acct(struct request *rq, int new_io) | 65 | static void drive_stat_acct(struct request *rq, int new_io) |
| 66 | { | 66 | { |
| 67 | struct gendisk *disk = rq->rq_disk; | ||
| 67 | struct hd_struct *part; | 68 | struct hd_struct *part; |
| 68 | int rw = rq_data_dir(rq); | 69 | int rw = rq_data_dir(rq); |
| 69 | int cpu; | 70 | int cpu; |
| 70 | 71 | ||
| 71 | if (!blk_fs_request(rq) || !rq->rq_disk) | 72 | if (!blk_fs_request(rq) || !disk || !blk_queue_io_stat(disk->queue)) |
| 72 | return; | 73 | return; |
| 73 | 74 | ||
| 74 | cpu = part_stat_lock(); | 75 | cpu = part_stat_lock(); |
| @@ -599,8 +600,7 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) | |||
| 599 | q->request_fn = rfn; | 600 | q->request_fn = rfn; |
| 600 | q->prep_rq_fn = NULL; | 601 | q->prep_rq_fn = NULL; |
| 601 | q->unplug_fn = generic_unplug_device; | 602 | q->unplug_fn = generic_unplug_device; |
| 602 | q->queue_flags = (1 << QUEUE_FLAG_CLUSTER | | 603 | q->queue_flags = QUEUE_FLAG_DEFAULT; |
| 603 | 1 << QUEUE_FLAG_STACKABLE); | ||
| 604 | q->queue_lock = lock; | 604 | q->queue_lock = lock; |
| 605 | 605 | ||
| 606 | blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); | 606 | blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK); |
| @@ -1125,6 +1125,8 @@ void init_request_from_bio(struct request *req, struct bio *bio) | |||
| 1125 | 1125 | ||
| 1126 | if (bio_sync(bio)) | 1126 | if (bio_sync(bio)) |
| 1127 | req->cmd_flags |= REQ_RW_SYNC; | 1127 | req->cmd_flags |= REQ_RW_SYNC; |
| 1128 | if (bio_unplug(bio)) | ||
| 1129 | req->cmd_flags |= REQ_UNPLUG; | ||
| 1128 | if (bio_rw_meta(bio)) | 1130 | if (bio_rw_meta(bio)) |
| 1129 | req->cmd_flags |= REQ_RW_META; | 1131 | req->cmd_flags |= REQ_RW_META; |
| 1130 | 1132 | ||
| @@ -1141,6 +1143,7 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
| 1141 | int el_ret, nr_sectors; | 1143 | int el_ret, nr_sectors; |
| 1142 | const unsigned short prio = bio_prio(bio); | 1144 | const unsigned short prio = bio_prio(bio); |
| 1143 | const int sync = bio_sync(bio); | 1145 | const int sync = bio_sync(bio); |
| 1146 | const int unplug = bio_unplug(bio); | ||
| 1144 | int rw_flags; | 1147 | int rw_flags; |
| 1145 | 1148 | ||
| 1146 | nr_sectors = bio_sectors(bio); | 1149 | nr_sectors = bio_sectors(bio); |
| @@ -1244,7 +1247,7 @@ get_rq: | |||
| 1244 | blk_plug_device(q); | 1247 | blk_plug_device(q); |
| 1245 | add_request(q, req); | 1248 | add_request(q, req); |
| 1246 | out: | 1249 | out: |
| 1247 | if (sync || blk_queue_nonrot(q)) | 1250 | if (unplug || blk_queue_nonrot(q)) |
| 1248 | __generic_unplug_device(q); | 1251 | __generic_unplug_device(q); |
| 1249 | spin_unlock_irq(q->queue_lock); | 1252 | spin_unlock_irq(q->queue_lock); |
| 1250 | return 0; | 1253 | return 0; |
| @@ -1448,6 +1451,11 @@ static inline void __generic_make_request(struct bio *bio) | |||
| 1448 | err = -EOPNOTSUPP; | 1451 | err = -EOPNOTSUPP; |
| 1449 | goto end_io; | 1452 | goto end_io; |
| 1450 | } | 1453 | } |
| 1454 | if (bio_barrier(bio) && bio_has_data(bio) && | ||
| 1455 | (q->next_ordered == QUEUE_ORDERED_NONE)) { | ||
| 1456 | err = -EOPNOTSUPP; | ||
| 1457 | goto end_io; | ||
| 1458 | } | ||
| 1451 | 1459 | ||
| 1452 | ret = q->make_request_fn(q, bio); | 1460 | ret = q->make_request_fn(q, bio); |
| 1453 | } while (ret); | 1461 | } while (ret); |
| @@ -1655,6 +1663,55 @@ void blkdev_dequeue_request(struct request *req) | |||
| 1655 | } | 1663 | } |
| 1656 | EXPORT_SYMBOL(blkdev_dequeue_request); | 1664 | EXPORT_SYMBOL(blkdev_dequeue_request); |
| 1657 | 1665 | ||
| 1666 | static void blk_account_io_completion(struct request *req, unsigned int bytes) | ||
| 1667 | { | ||
| 1668 | struct gendisk *disk = req->rq_disk; | ||
| 1669 | |||
| 1670 | if (!disk || !blk_queue_io_stat(disk->queue)) | ||
| 1671 | return; | ||
| 1672 | |||
| 1673 | if (blk_fs_request(req)) { | ||
| 1674 | const int rw = rq_data_dir(req); | ||
| 1675 | struct hd_struct *part; | ||
| 1676 | int cpu; | ||
| 1677 | |||
| 1678 | cpu = part_stat_lock(); | ||
| 1679 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | ||
| 1680 | part_stat_add(cpu, part, sectors[rw], bytes >> 9); | ||
| 1681 | part_stat_unlock(); | ||
| 1682 | } | ||
| 1683 | } | ||
| 1684 | |||
| 1685 | static void blk_account_io_done(struct request *req) | ||
| 1686 | { | ||
| 1687 | struct gendisk *disk = req->rq_disk; | ||
| 1688 | |||
| 1689 | if (!disk || !blk_queue_io_stat(disk->queue)) | ||
| 1690 | return; | ||
| 1691 | |||
| 1692 | /* | ||
| 1693 | * Account IO completion. bar_rq isn't accounted as a normal | ||
| 1694 | * IO on queueing nor completion. Accounting the containing | ||
| 1695 | * request is enough. | ||
| 1696 | */ | ||
| 1697 | if (blk_fs_request(req) && req != &req->q->bar_rq) { | ||
| 1698 | unsigned long duration = jiffies - req->start_time; | ||
| 1699 | const int rw = rq_data_dir(req); | ||
| 1700 | struct hd_struct *part; | ||
| 1701 | int cpu; | ||
| 1702 | |||
| 1703 | cpu = part_stat_lock(); | ||
| 1704 | part = disk_map_sector_rcu(disk, req->sector); | ||
| 1705 | |||
| 1706 | part_stat_inc(cpu, part, ios[rw]); | ||
| 1707 | part_stat_add(cpu, part, ticks[rw], duration); | ||
| 1708 | part_round_stats(cpu, part); | ||
| 1709 | part_dec_in_flight(part); | ||
| 1710 | |||
| 1711 | part_stat_unlock(); | ||
| 1712 | } | ||
| 1713 | } | ||
| 1714 | |||
| 1658 | /** | 1715 | /** |
| 1659 | * __end_that_request_first - end I/O on a request | 1716 | * __end_that_request_first - end I/O on a request |
| 1660 | * @req: the request being processed | 1717 | * @req: the request being processed |
| @@ -1690,16 +1747,7 @@ static int __end_that_request_first(struct request *req, int error, | |||
| 1690 | (unsigned long long)req->sector); | 1747 | (unsigned long long)req->sector); |
| 1691 | } | 1748 | } |
| 1692 | 1749 | ||
| 1693 | if (blk_fs_request(req) && req->rq_disk) { | 1750 | blk_account_io_completion(req, nr_bytes); |
| 1694 | const int rw = rq_data_dir(req); | ||
| 1695 | struct hd_struct *part; | ||
| 1696 | int cpu; | ||
| 1697 | |||
| 1698 | cpu = part_stat_lock(); | ||
| 1699 | part = disk_map_sector_rcu(req->rq_disk, req->sector); | ||
| 1700 | part_stat_add(cpu, part, sectors[rw], nr_bytes >> 9); | ||
| 1701 | part_stat_unlock(); | ||
| 1702 | } | ||
| 1703 | 1751 | ||
| 1704 | total_bytes = bio_nbytes = 0; | 1752 | total_bytes = bio_nbytes = 0; |
| 1705 | while ((bio = req->bio) != NULL) { | 1753 | while ((bio = req->bio) != NULL) { |
| @@ -1779,8 +1827,6 @@ static int __end_that_request_first(struct request *req, int error, | |||
| 1779 | */ | 1827 | */ |
| 1780 | static void end_that_request_last(struct request *req, int error) | 1828 | static void end_that_request_last(struct request *req, int error) |
| 1781 | { | 1829 | { |
| 1782 | struct gendisk *disk = req->rq_disk; | ||
| 1783 | |||
| 1784 | if (blk_rq_tagged(req)) | 1830 | if (blk_rq_tagged(req)) |
| 1785 | blk_queue_end_tag(req->q, req); | 1831 | blk_queue_end_tag(req->q, req); |
| 1786 | 1832 | ||
| @@ -1792,27 +1838,7 @@ static void end_that_request_last(struct request *req, int error) | |||
| 1792 | 1838 | ||
| 1793 | blk_delete_timer(req); | 1839 | blk_delete_timer(req); |
| 1794 | 1840 | ||
| 1795 | /* | 1841 | blk_account_io_done(req); |
| 1796 | * Account IO completion. bar_rq isn't accounted as a normal | ||
| 1797 | * IO on queueing nor completion. Accounting the containing | ||
| 1798 | * request is enough. | ||
| 1799 | */ | ||
| 1800 | if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { | ||
| 1801 | unsigned long duration = jiffies - req->start_time; | ||
| 1802 | const int rw = rq_data_dir(req); | ||
| 1803 | struct hd_struct *part; | ||
| 1804 | int cpu; | ||
| 1805 | |||
| 1806 | cpu = part_stat_lock(); | ||
| 1807 | part = disk_map_sector_rcu(disk, req->sector); | ||
| 1808 | |||
| 1809 | part_stat_inc(cpu, part, ios[rw]); | ||
| 1810 | part_stat_add(cpu, part, ticks[rw], duration); | ||
| 1811 | part_round_stats(cpu, part); | ||
| 1812 | part_dec_in_flight(part); | ||
| 1813 | |||
| 1814 | part_stat_unlock(); | ||
| 1815 | } | ||
| 1816 | 1842 | ||
| 1817 | if (req->end_io) | 1843 | if (req->end_io) |
| 1818 | req->end_io(req, error); | 1844 | req->end_io(req, error); |
