aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-core.c34
-rw-r--r--block/blk-merge.c6
-rw-r--r--fs/partitions/check.c7
-rw-r--r--include/linux/genhd.h1
4 files changed, 44 insertions, 4 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index fba4ca7c6086..2358fc5de5a4 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
@@ -997,6 +1002,21 @@ void disk_round_stats(struct gendisk *disk)
997} 1002}
998EXPORT_SYMBOL_GPL(disk_round_stats); 1003EXPORT_SYMBOL_GPL(disk_round_stats);
999 1004
1005void 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
1000/* 1020/*
1001 * queue lock must be held 1021 * queue lock must be held
1002 */ 1022 */
@@ -1530,7 +1550,8 @@ static int __end_that_request_first(struct request *req, int error,
1530 if (blk_fs_request(req) && req->rq_disk) { 1550 if (blk_fs_request(req) && req->rq_disk) {
1531 const int rw = rq_data_dir(req); 1551 const int rw = rq_data_dir(req);
1532 1552
1533 disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9); 1553 all_stat_add(req->rq_disk, sectors[rw],
1554 nr_bytes >> 9, req->sector);
1534 } 1555 }
1535 1556
1536 total_bytes = bio_nbytes = 0; 1557 total_bytes = bio_nbytes = 0;
@@ -1715,11 +1736,16 @@ static void end_that_request_last(struct request *req, int error)
1715 if (disk && blk_fs_request(req) && req != &req->q->bar_rq) { 1736 if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
1716 unsigned long duration = jiffies - req->start_time; 1737 unsigned long duration = jiffies - req->start_time;
1717 const int rw = rq_data_dir(req); 1738 const int rw = rq_data_dir(req);
1739 struct hd_struct *part = get_part(disk, req->sector);
1718 1740
1719 __disk_stat_inc(disk, ios[rw]); 1741 __all_stat_inc(disk, ios[rw], req->sector);
1720 __disk_stat_add(disk, ticks[rw], duration); 1742 __all_stat_add(disk, ticks[rw], duration, req->sector);
1721 disk_round_stats(disk); 1743 disk_round_stats(disk);
1722 disk->in_flight--; 1744 disk->in_flight--;
1745 if (part) {
1746 part_round_stats(part);
1747 part->in_flight--;
1748 }
1723 } 1749 }
1724 1750
1725 if (req->end_io) 1751 if (req->end_io)
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 845ef8131108..d3b84bbb776a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -454,8 +454,14 @@ static int attempt_merge(struct request_queue *q, struct request *req,
454 elv_merge_requests(q, req, next); 454 elv_merge_requests(q, req, next);
455 455
456 if (req->rq_disk) { 456 if (req->rq_disk) {
457 struct hd_struct *part
458 = get_part(req->rq_disk, req->sector);
457 disk_round_stats(req->rq_disk); 459 disk_round_stats(req->rq_disk);
458 req->rq_disk->in_flight--; 460 req->rq_disk->in_flight--;
461 if (part) {
462 part_round_stats(part);
463 part->in_flight--;
464 }
459 } 465 }
460 466
461 req->ioprio = ioprio_best(req->ioprio, next->ioprio); 467 req->ioprio = ioprio_best(req->ioprio, next->ioprio);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9a64045ff845..f2ec7f1b0ec5 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -18,6 +18,7 @@
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/kmod.h> 19#include <linux/kmod.h>
20#include <linux/ctype.h> 20#include <linux/ctype.h>
21#include <linux/genhd.h>
21 22
22#include "check.h" 23#include "check.h"
23 24
@@ -273,6 +274,7 @@ static struct attribute_group *part_attr_groups[] = {
273static void part_release(struct device *dev) 274static void part_release(struct device *dev)
274{ 275{
275 struct hd_struct *p = dev_to_part(dev); 276 struct hd_struct *p = dev_to_part(dev);
277 free_part_stats(p);
276 kfree(p); 278 kfree(p);
277} 279}
278 280
@@ -314,6 +316,7 @@ void delete_partition(struct gendisk *disk, int part)
314 p->nr_sects = 0; 316 p->nr_sects = 0;
315 p->ios[0] = p->ios[1] = 0; 317 p->ios[0] = p->ios[1] = 0;
316 p->sectors[0] = p->sectors[1] = 0; 318 p->sectors[0] = p->sectors[1] = 0;
319 part_stat_set_all(p, 0);
317 kobject_put(p->holder_dir); 320 kobject_put(p->holder_dir);
318 device_del(&p->dev); 321 device_del(&p->dev);
319 put_device(&p->dev); 322 put_device(&p->dev);
@@ -336,6 +339,10 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
336 if (!p) 339 if (!p)
337 return; 340 return;
338 341
342 if (!init_part_stats(p)) {
343 kfree(p);
344 return;
345 }
339 p->start_sect = start; 346 p->start_sect = start;
340 p->nr_sects = len; 347 p->nr_sects = len;
341 p->partno = part; 348 p->partno = part;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 589830aca99d..4cf25a5f4159 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -365,6 +365,7 @@ static inline void free_part_stats(struct hd_struct *part)
365 365
366/* drivers/block/ll_rw_blk.c */ 366/* drivers/block/ll_rw_blk.c */
367extern void disk_round_stats(struct gendisk *disk); 367extern void disk_round_stats(struct gendisk *disk);
368extern void part_round_stats(struct hd_struct *part);
368 369
369/* drivers/block/genhd.c */ 370/* drivers/block/genhd.c */
370extern int get_blkdev_list(char *, int); 371extern int get_blkdev_list(char *, int);