Commit 2103a00b authored by Alexander Viro's avatar Alexander Viro Committed by James Bottomley

[PATCH] IO counters - per-partition part

	This chunk and the next one basically do equivalent of sard in the
right way - counters are exported per-disk in driverfs, as attributes of
disk or partition nodes.
parent 5cdeb2cc
...@@ -1777,12 +1777,24 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1777,12 +1777,24 @@ static int __make_request(request_queue_t *q, struct bio *bio)
static inline void blk_partition_remap(struct bio *bio) static inline void blk_partition_remap(struct bio *bio)
{ {
struct block_device *bdev = bio->bi_bdev; struct block_device *bdev = bio->bi_bdev;
struct gendisk *disk = bdev->bd_disk;
struct hd_struct *p;
if (bdev == bdev->bd_contains) if (bdev == bdev->bd_contains)
return; return;
p = &disk->part[bdev->bd_dev-MKDEV(disk->major,disk->first_minor)-1];
switch (bio->bi_rw) {
case READ:
p->read_sectors += bio_sectors(bio);
p->reads++;
break;
case WRITE:
p->write_sectors += bio_sectors(bio);
p->writes++;
break;
}
bio->bi_sector += bdev->bd_offset; bio->bi_sector += bdev->bd_offset;
bio->bi_bdev = bdev->bd_contains; bio->bi_bdev = bdev->bd_contains;
/* lots of checks are possible */
} }
/** /**
......
...@@ -298,6 +298,14 @@ static ssize_t part_size_read(struct device *dev, ...@@ -298,6 +298,14 @@ static ssize_t part_size_read(struct device *dev,
struct hd_struct *p = dev->driver_data; struct hd_struct *p = dev->driver_data;
return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)p->nr_sects); return off ? 0 : sprintf(page, "%llu\n",(unsigned long long)p->nr_sects);
} }
static ssize_t part_stat_read(struct device *dev,
char *page, size_t count, loff_t off)
{
struct hd_struct *p = dev->driver_data;
return off ? 0 : sprintf(page, "%u %u %u %u\n",
p->reads, p->read_sectors,
p->writes, p->write_sectors);
}
static struct device_attribute part_attr_dev = { static struct device_attribute part_attr_dev = {
.attr = {.name = "dev", .mode = S_IRUGO }, .attr = {.name = "dev", .mode = S_IRUGO },
.show = part_dev_read .show = part_dev_read
...@@ -310,6 +318,10 @@ static struct device_attribute part_attr_size = { ...@@ -310,6 +318,10 @@ static struct device_attribute part_attr_size = {
.attr = {.name = "size", .mode = S_IRUGO }, .attr = {.name = "size", .mode = S_IRUGO },
.show = part_size_read .show = part_size_read
}; };
static struct device_attribute part_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
.show = part_stat_read
};
void delete_partition(struct gendisk *disk, int part) void delete_partition(struct gendisk *disk, int part)
{ {
...@@ -319,10 +331,12 @@ void delete_partition(struct gendisk *disk, int part) ...@@ -319,10 +331,12 @@ void delete_partition(struct gendisk *disk, int part)
return; return;
p->start_sect = 0; p->start_sect = 0;
p->nr_sects = 0; p->nr_sects = 0;
p->reads = p->writes = p->read_sectors = p->write_sectors = 0;
devfs_unregister(p->de); devfs_unregister(p->de);
dev = p->hd_driverfs_dev; dev = p->hd_driverfs_dev;
p->hd_driverfs_dev = NULL; p->hd_driverfs_dev = NULL;
if (dev) { if (dev) {
device_remove_file(dev, &part_attr_stat);
device_remove_file(dev, &part_attr_size); device_remove_file(dev, &part_attr_size);
device_remove_file(dev, &part_attr_start); device_remove_file(dev, &part_attr_start);
device_remove_file(dev, &part_attr_dev); device_remove_file(dev, &part_attr_dev);
...@@ -356,6 +370,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) ...@@ -356,6 +370,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
device_create_file(dev, &part_attr_dev); device_create_file(dev, &part_attr_dev);
device_create_file(dev, &part_attr_start); device_create_file(dev, &part_attr_start);
device_create_file(dev, &part_attr_size); device_create_file(dev, &part_attr_size);
device_create_file(dev, &part_attr_stat);
p->hd_driverfs_dev = dev; p->hd_driverfs_dev = dev;
} }
......
...@@ -63,6 +63,7 @@ struct hd_struct { ...@@ -63,6 +63,7 @@ struct hd_struct {
sector_t nr_sects; sector_t nr_sects;
devfs_handle_t de; /* primary (master) devfs entry */ devfs_handle_t de; /* primary (master) devfs entry */
struct device *hd_driverfs_dev; /* support driverfs hiearchy */ struct device *hd_driverfs_dev; /* support driverfs hiearchy */
unsigned reads, read_sectors, writes, write_sectors;
int policy; int policy;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment