return;
 
        if (!new_io) {
-               __disk_stat_inc(rq->rq_disk, merges[rw]);
+               __all_stat_inc(rq->rq_disk, merges[rw], rq->sector);
        } else {
+               struct hd_struct *part = get_part(rq->rq_disk, rq->sector);
                disk_round_stats(rq->rq_disk);
                rq->rq_disk->in_flight++;
+               if (part) {
+                       part_round_stats(part);
+                       part->in_flight++;
+               }
        }
 }
 
 }
 EXPORT_SYMBOL_GPL(disk_round_stats);
 
+void part_round_stats(struct hd_struct *part)
+{
+       unsigned long now = jiffies;
+
+       if (now == part->stamp)
+               return;
+
+       if (part->in_flight) {
+               __part_stat_add(part, time_in_queue,
+                               part->in_flight * (now - part->stamp));
+               __part_stat_add(part, io_ticks, (now - part->stamp));
+       }
+       part->stamp = now;
+}
+
 /*
  * queue lock must be held
  */
        if (blk_fs_request(req) && req->rq_disk) {
                const int rw = rq_data_dir(req);
 
-               disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
+               all_stat_add(req->rq_disk, sectors[rw],
+                            nr_bytes >> 9, req->sector);
        }
 
        total_bytes = bio_nbytes = 0;
        if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
                unsigned long duration = jiffies - req->start_time;
                const int rw = rq_data_dir(req);
+               struct hd_struct *part = get_part(disk, req->sector);
 
-               __disk_stat_inc(disk, ios[rw]);
-               __disk_stat_add(disk, ticks[rw], duration);
+               __all_stat_inc(disk, ios[rw], req->sector);
+               __all_stat_add(disk, ticks[rw], duration, req->sector);
                disk_round_stats(disk);
                disk->in_flight--;
+               if (part) {
+                       part_round_stats(part);
+                       part->in_flight--;
+               }
        }
 
        if (req->end_io)
 
        elv_merge_requests(q, req, next);
 
        if (req->rq_disk) {
+               struct hd_struct *part
+                       = get_part(req->rq_disk, req->sector);
                disk_round_stats(req->rq_disk);
                req->rq_disk->in_flight--;
+               if (part) {
+                       part_round_stats(part);
+                       part->in_flight--;
+               }
        }
 
        req->ioprio = ioprio_best(req->ioprio, next->ioprio);
 
 #include <linux/fs.h>
 #include <linux/kmod.h>
 #include <linux/ctype.h>
+#include <linux/genhd.h>
 
 #include "check.h"
 
 static void part_release(struct device *dev)
 {
        struct hd_struct *p = dev_to_part(dev);
+       free_part_stats(p);
        kfree(p);
 }
 
        p->nr_sects = 0;
        p->ios[0] = p->ios[1] = 0;
        p->sectors[0] = p->sectors[1] = 0;
+       part_stat_set_all(p, 0);
        kobject_put(p->holder_dir);
        device_del(&p->dev);
        put_device(&p->dev);
        if (!p)
                return;
 
+       if (!init_part_stats(p)) {
+               kfree(p);
+               return;
+       }
        p->start_sect = start;
        p->nr_sects = len;
        p->partno = part;