📄 sd_iostats-2.6-rhel4.patch
字号:
+ unsigned long flags;+ + + spin_lock_irqsave (&sd_iostats_lock, flags);+ memset (stats, 0, sizeof(*stats));+ do_gettimeofday(&stats->iostat_timeval);+ spin_unlock_irqrestore (&sd_iostats_lock, flags);++ return len;+}++static struct file_operations sd_iostats_proc_fops = {+ .owner = THIS_MODULE,+ .open = sd_iostats_seq_open,+ .read = seq_read,+ .write = sd_iostats_seq_write,+ .llseek = seq_lseek,+ .release = seq_release,+};++extern struct proc_dir_entry *proc_scsi;++void+sd_iostats_init(void)+{+ int i;++ spin_lock_init(&sd_iostats_lock);++ sd_iostats = kmalloc(SD_STATS * sizeof(iostat_stats_t *), GFP_KERNEL);+ if (sd_iostats == NULL) {+ printk(KERN_WARNING "Can't keep sd iostats: "+ "ENOMEM allocating stats array size %ld\n",+ SD_STATS * sizeof(iostat_stats_t *));+ return;+ }++ for (i = 0; i < SD_STATS; i++)+ sd_iostats[i] = NULL;++ if (proc_scsi == NULL) {+ printk(KERN_WARNING "No access to sd iostats: "+ "proc_scsi is NULL\n");+ return;+ }++ sd_iostats_procdir = create_proc_entry(sd_iostats_procdir_name,+ S_IFDIR | S_IRUGO | S_IXUGO,+ proc_scsi);+ if (sd_iostats_procdir == NULL) {+ printk(KERN_WARNING "No access to sd iostats: "+ "can't create /proc/scsi/%s\n", sd_iostats_procdir_name);+ return;+ }+}++void+sd_iostats_init_disk(struct gendisk *disk)+{+ struct proc_dir_entry *pde;+ unsigned long flags;+ iostat_stats_t *stats;++ if (sd_iostats == NULL ||+ sd_iostats_procdir == NULL)+ return;++ if (scsi_disk(disk)->index > SD_STATS) {+ printk(KERN_ERR "sd_iostats_init_disk: "+ "unexpected disk index %d(%d)\n",+ scsi_disk(disk)->index, SD_STATS);+ return;+ }++ if (sd_iostats[scsi_disk(disk)->index] != NULL)+ return;++ stats = kmalloc(sizeof(*stats), GFP_KERNEL);+ if (stats == NULL) {+ printk(KERN_WARNING "Can't keep %s iostats: "+ "ENOMEM allocating stats size %ld\n", + disk->disk_name, sizeof(*stats));+ return;+ }++ memset (stats, 0, sizeof(*stats));+ do_gettimeofday(&stats->iostat_timeval);++ spin_lock_irqsave(&sd_iostats_lock, flags);++ if (sd_iostats[scsi_disk(disk)->index] != NULL) {+ spin_unlock_irqrestore(&sd_iostats_lock, flags);+ kfree (stats);+ return;+ }++ sd_iostats[scsi_disk(disk)->index] = stats;+ + spin_unlock_irqrestore(&sd_iostats_lock, flags);+ + pde = create_proc_entry(disk->disk_name, S_IRUGO | S_IWUSR, + sd_iostats_procdir);+ if (pde == NULL) {+ printk(KERN_WARNING "Can't create /proc/scsi/%s/%s\n",+ sd_iostats_procdir_name, disk->disk_name);+ } else {+ pde->proc_fops = &sd_iostats_proc_fops;+ pde->data = disk;+ }+}++static void sd_devname(unsigned int disknum, char *buffer)+{+ if (disknum < 26)+ sprintf(buffer, "sd%c", 'a' + disknum);+ else {+ unsigned int min1;+ unsigned int min2;+ /*+ * For larger numbers of disks, we need to go to a new+ * naming scheme.+ */+ min1 = disknum / 26;+ min2 = disknum % 26;+ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);+ }+}++void+sd_iostats_fini(void)+{+ char name[6];+ int i;+ + if (sd_iostats_procdir != NULL) {+ for (i = 0; i < SD_STATS; i++) {+ sd_devname(i, name);+ remove_proc_entry(name, sd_iostats_procdir);+ }++ if (proc_scsi == NULL) {+ printk(KERN_ERR "sd_iostats_fini: proc_scsi NULL\n");+ BUG();+ }+ remove_proc_entry(sd_iostats_procdir_name,+ proc_scsi);++ sd_iostats_procdir = NULL;+ }+ + if (sd_iostats != NULL) {+ for (i = 0; i < SD_STATS; i++) {+ if (sd_iostats[i] != NULL)+ kfree (sd_iostats[i]);+ }+ + kfree(sd_iostats);+ sd_iostats = NULL;+ }+}++void+sd_iostats_bump(int disk, unsigned int nsect, int iswrite)+{+ iostat_stats_t *stats;+ iostat_counter_t *counter;+ int bucket;+ int tmp;+ unsigned long irqflags;++ if (sd_iostats == NULL)+ return;++ if (disk < 0 || disk >= SD_STATS) {+ printk(KERN_ERR "sd_iostats_bump: unexpected disk index %d([0-%d])\n",+ disk, SD_STATS);+ BUG();+ }++ for (bucket = 0, tmp = nsect; tmp > 1; bucket++)+ tmp /= 2;++ if (bucket >= IOSTAT_NCOUNTERS) {+ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);+ BUG();+ }++ spin_lock_irqsave(&sd_iostats_lock, irqflags);+ + stats = sd_iostats[disk];+ if (stats != NULL) {+ counter = iswrite ? + &stats->iostat_write_histogram[bucket] :+ &stats->iostat_read_histogram[bucket];++ counter->iostat_size += nsect;+ counter->iostat_count++;+ }++ spin_unlock_irqrestore(&sd_iostats_lock, irqflags);+}+#endif+ /** * init_sd - entry point for this driver (both when built in or when * a module).@@ -1584,6 +1969,7 @@ static void sd_shutdown(struct device *d static int __init init_sd(void) { int majors = 0, i;+ int rc = 0; SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n")); @@ -1594,7 +1980,10 @@ static int __init init_sd(void) if (!majors) return -ENODEV; - return scsi_register_driver(&sd_template.gendrv);+ rc = scsi_register_driver(&sd_template.gendrv);+ if (rc == 0)+ sd_iostats_init();+ return rc; } /**@@ -1608,6 +1997,7 @@ static void __exit exit_sd(void) SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); + sd_iostats_fini(); scsi_unregister_driver(&sd_template.gendrv); for (i = 0; i < SD_MAJORS; i++) unregister_blkdev(sd_major(i), "sd");Index: linux+rhel4+chaos/drivers/scsi/scsi_proc.c===================================================================--- linux+rhel4+chaos.orig/drivers/scsi/scsi_proc.c+++ linux+rhel4+chaos/drivers/scsi/scsi_proc.c@@ -38,7 +38,8 @@ /* 4K page size, but our output routines, use some slack for overruns */ #define PROC_BLOCK_SIZE (3*1024) -static struct proc_dir_entry *proc_scsi;+struct proc_dir_entry *proc_scsi;+EXPORT_SYMBOL(proc_scsi); /* Protect sht->present and sht->proc_dir */ static DECLARE_MUTEX(global_host_template_sem);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -