How about something simpler, using fixed-size allocations per major,
without a built-in linear search prior to each and every disk access?
Something like below?
-ml
/**********************************************************/
++disk_stats[MAJOR(req->rq_dev)][unit].ds_disk_rio;
where "unit" is obtained from a switch() stmt similar to the existing
code.
At this time, I would suggest that a coded limit would be a simpler
alternative to dynamic expansion of the number of possible units per
major,
yielding code that might do something like this:
#define MAX_DISKSTATS_UNITS_PER_MAJOR 8 /* or 16, or
whatever.. */
struct kernel_stat_disk *disk_stats[MAX_BLKDEV];
...
static inline void disk_stat_acct(int cmd, unsigned long
nr_sectors,short disk_index)
{
struct kernel_stat_disk *stats;
stats = disk_stats[MAJOR(req->rq_dev)];
if (!stats) {
stats = disk_stats(MAJOR(req->rq_dev)] =
kmalloc(sizeof(struct kernel_stat_disk)
* MAX_DISKSTATS_UNITS_PER_MAJOR, GFP_KERNEL);
}
if (stats && disk_index < MAX_DISKSTATS_UNITS_PER_MAJOR) {
if (cmd == READ) {
++stats[disk_index].ds_disk_rio;
++stats[disk_index].ds_disk_rblks;
} else if (cmd == WRITE) {
++stats[disk_index].ds_disk_wio;
++stats[disk_index].ds_disk_wblks;
}
}
}
-- mlord@pobox.com The Linux IDE guy