diff options
Diffstat (limited to 'block/blk-core.c')
-rw-r--r-- | block/blk-core.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 4afb39c82339..e9754dc98ec4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -60,10 +60,15 @@ static void drive_stat_acct(struct request *rq, int new_io) | |||
60 | return; | 60 | return; |
61 | 61 | ||
62 | if (!new_io) { | 62 | if (!new_io) { |
63 | __disk_stat_inc(rq->rq_disk, merges[rw]); | 63 | __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); |
64 | } else { | 64 | } else { |
65 | struct hd_struct *part = get_part(rq->rq_disk, rq->sector); | ||
65 | disk_round_stats(rq->rq_disk); | 66 | disk_round_stats(rq->rq_disk); |
66 | rq->rq_disk->in_flight++; | 67 | rq->rq_disk->in_flight++; |
68 | if (part) { | ||
69 | part_round_stats(part); | ||
70 | part->in_flight++; | ||
71 | } | ||
67 | } | 72 | } |
68 | } | 73 | } |
69 | 74 | ||
@@ -102,27 +107,38 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev) | |||
102 | } | 107 | } |
103 | EXPORT_SYMBOL(blk_get_backing_dev_info); | 108 | EXPORT_SYMBOL(blk_get_backing_dev_info); |
104 | 109 | ||
110 | /* | ||
111 | * We can't just memset() the structure, since the allocation path | ||
112 | * already stored some information in the request. | ||
113 | */ | ||
105 | void rq_init(struct request_queue *q, struct request *rq) | 114 | void rq_init(struct request_queue *q, struct request *rq) |
106 | { | 115 | { |
107 | INIT_LIST_HEAD(&rq->queuelist); | 116 | INIT_LIST_HEAD(&rq->queuelist); |
108 | INIT_LIST_HEAD(&rq->donelist); | 117 | INIT_LIST_HEAD(&rq->donelist); |
109 | 118 | rq->q = q; | |
110 | rq->errors = 0; | 119 | rq->sector = rq->hard_sector = (sector_t) -1; |
120 | rq->nr_sectors = rq->hard_nr_sectors = 0; | ||
121 | rq->current_nr_sectors = rq->hard_cur_sectors = 0; | ||
111 | rq->bio = rq->biotail = NULL; | 122 | rq->bio = rq->biotail = NULL; |
112 | INIT_HLIST_NODE(&rq->hash); | 123 | INIT_HLIST_NODE(&rq->hash); |
113 | RB_CLEAR_NODE(&rq->rb_node); | 124 | RB_CLEAR_NODE(&rq->rb_node); |
125 | rq->rq_disk = NULL; | ||
126 | rq->nr_phys_segments = 0; | ||
127 | rq->nr_hw_segments = 0; | ||
114 | rq->ioprio = 0; | 128 | rq->ioprio = 0; |
129 | rq->special = NULL; | ||
115 | rq->buffer = NULL; | 130 | rq->buffer = NULL; |
131 | rq->tag = -1; | ||
132 | rq->errors = 0; | ||
116 | rq->ref_count = 1; | 133 | rq->ref_count = 1; |
117 | rq->q = q; | 134 | rq->cmd_len = 0; |
118 | rq->special = NULL; | 135 | memset(rq->cmd, 0, sizeof(rq->cmd)); |
119 | rq->data_len = 0; | 136 | rq->data_len = 0; |
137 | rq->sense_len = 0; | ||
120 | rq->data = NULL; | 138 | rq->data = NULL; |
121 | rq->nr_phys_segments = 0; | ||
122 | rq->sense = NULL; | 139 | rq->sense = NULL; |
123 | rq->end_io = NULL; | 140 | rq->end_io = NULL; |
124 | rq->end_io_data = NULL; | 141 | rq->end_io_data = NULL; |
125 | rq->completion_data = NULL; | ||
126 | rq->next_rq = NULL; | 142 | rq->next_rq = NULL; |
127 | } | 143 | } |
128 | 144 | ||
@@ -986,6 +1002,21 @@ void disk_round_stats(struct gendisk *disk) | |||
986 | } | 1002 | } |
987 | EXPORT_SYMBOL_GPL(disk_round_stats); | 1003 | EXPORT_SYMBOL_GPL(disk_round_stats); |
988 | 1004 | ||
1005 | void part_round_stats(struct hd_struct *part) | ||
1006 | { | ||
1007 | unsigned long now = jiffies; | ||
1008 | |||
1009 | if (now == part->stamp) | ||
1010 | return; | ||
1011 | |||
1012 | if (part->in_flight) { | ||
1013 | __part_stat_add(part, time_in_queue, | ||
1014 | part->in_flight * (now - part->stamp)); | ||
1015 | __part_stat_add(part, io_ticks, (now - part->stamp)); | ||
1016 | } | ||
1017 | part->stamp = now; | ||
1018 | } | ||
1019 | |||
989 | /* | 1020 | /* |
990 | * queue lock must be held | 1021 | * queue lock must be held |
991 | */ | 1022 | */ |
@@ -1188,10 +1219,6 @@ static inline void blk_partition_remap(struct bio *bio) | |||
1188 | 1219 | ||
1189 | if (bio_sectors(bio) && bdev != bdev->bd_contains) { | 1220 | if (bio_sectors(bio) && bdev != bdev->bd_contains) { |
1190 | struct hd_struct *p = bdev->bd_part; | 1221 | struct hd_struct *p = bdev->bd_part; |
1191 | const int rw = bio_data_dir(bio); | ||
1192 | |||
1193 | p->sectors[rw] += bio_sectors(bio); | ||
1194 | p->ios[rw]++; | ||
1195 | 1222 | ||
1196 | bio->bi_sector += p->start_sect; | 1223 | bio->bi_sector += p->start_sect; |
1197 | bio->bi_bdev = bdev->bd_contains; | 1224 | bio->bi_bdev = bdev->bd_contains; |
@@ -1519,7 +1546,8 @@ static int __end_that_request_first(struct request *req, int error, | |||
1519 | if (blk_fs_request(req) && req->rq_disk) { | 1546 | if (blk_fs_request(req) && req->rq_disk) { |
1520 | const int rw = rq_data_dir(req); | 1547 | const int rw = rq_data_dir(req); |
1521 | 1548 | ||
1522 | disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9); | 1549 | all_stat_add(req->rq_disk, sectors[rw], |
1550 | nr_bytes >> 9, req->sector); | ||
1523 | } | 1551 | } |
1524 | 1552 | ||
1525 | total_bytes = bio_nbytes = 0; | 1553 | total_bytes = bio_nbytes = 0; |
@@ -1704,11 +1732,16 @@ static void end_that_request_last(struct request *req, int error) | |||
1704 | if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { | 1732 | if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { |
1705 | unsigned long duration = jiffies - req->start_time; | 1733 | unsigned long duration = jiffies - req->start_time; |
1706 | const int rw = rq_data_dir(req); | 1734 | const int rw = rq_data_dir(req); |
1735 | struct hd_struct *part = get_part(disk, req->sector); | ||
1707 | 1736 | ||
1708 | __disk_stat_inc(disk, ios[rw]); | 1737 | __all_stat_inc(disk, ios[rw], req->sector); |
1709 | __disk_stat_add(disk, ticks[rw], duration); | 1738 | __all_stat_add(disk, ticks[rw], duration, req->sector); |
1710 | disk_round_stats(disk); | 1739 | disk_round_stats(disk); |
1711 | disk->in_flight--; | 1740 | disk->in_flight--; |
1741 | if (part) { | ||
1742 | part_round_stats(part); | ||
1743 | part->in_flight--; | ||
1744 | } | ||
1712 | } | 1745 | } |
1713 | 1746 | ||
1714 | if (req->end_io) | 1747 | if (req->end_io) |