Whamcloud - gitweb
When removing a scsi device from a kernel with your sd_iostats
authorshadow <shadow>
Tue, 22 May 2007 07:41:38 +0000 (07:41 +0000)
committershadow <shadow>
Tue, 22 May 2007 07:41:38 +0000 (07:41 +0000)
patch you can cause a node to crash when reading from
/proc/scsi/sd_iostats/sdX

b=11654
i=shadow
i=deen

lustre/kernel_patches/patches/sd_iostats-2.4.21-chaos.patch
lustre/kernel_patches/patches/sd_iostats-2.6-rhel4.patch
lustre/kernel_patches/patches/sd_iostats-2.6-suse.patch [deleted file]
lustre/kernel_patches/series/2.6-suse-newer.series

index bf0adc7..ba97b76 100644 (file)
@@ -1,11 +1,7 @@
-Index: linux/Documentation/Configure.help
-===================================================================
-RCS file: /home/cvs/master/68chaos_eebperf/Documentation/Configure.help,v
-retrieving revision 1.1.1.1
-diff -u -p -r1.1.1.1 Configure.help
---- linux/Documentation/Configure.help 20 Aug 2004 18:09:23 -0000      1.1.1.1
-+++ linux/Documentation/Configure.help 26 Aug 2004 12:34:40 -0000
-@@ -7679,6 +7679,11 @@ CONFIG_SCSI_LOGGING
+diff -urp RH_2_4_21_47_0_1.orig/Documentation/Configure.help RH_2_4_21_47_0_1/Documentation/Configure.help
+--- RH_2_4_21_47_0_1.orig/Documentation/Configure.help 2006-11-20 16:59:49.000000000 +0200
++++ RH_2_4_21_47_0_1/Documentation/Configure.help      2007-05-21 19:13:23.000000000 +0300
+@@ -7620,6 +7620,11 @@ CONFIG_SCSI_LOGGING
    there should be no noticeable performance impact as long as you have
    logging turned off.
  
@@ -17,28 +13,20 @@ diff -u -p -r1.1.1.1 Configure.help
  QDIO base support for IBM S/390 and zSeries
  CONFIG_QDIO
    This driver provides the Queued Direct I/O base support for the
-Index: linux/drivers/scsi/Config.in
-===================================================================
-RCS file: /home/cvs/master/68chaos_eebperf/drivers/scsi/Config.in,v
-retrieving revision 1.1.1.1
-diff -u -p -r1.1.1.1 Config.in
---- linux/drivers/scsi/Config.in       20 Aug 2004 18:10:13 -0000      1.1.1.1
-+++ linux/drivers/scsi/Config.in       24 Aug 2004 14:30:08 -0000
+diff -urp RH_2_4_21_47_0_1.orig/drivers/scsi/Config.in RH_2_4_21_47_0_1/drivers/scsi/Config.in
+--- RH_2_4_21_47_0_1.orig/drivers/scsi/Config.in       2006-11-20 16:59:49.000000000 +0200
++++ RH_2_4_21_47_0_1/drivers/scsi/Config.in    2007-05-21 19:13:23.000000000 +0300
 @@ -4,6 +4,7 @@ dep_tristate '  SCSI disk support' CONFI
  
  if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
     int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
 +   bool 'SCSI disk I/O stats' CONFIG_SD_IOSTATS y
  fi
- dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-Index: linux/drivers/scsi/sd.c
-===================================================================
-RCS file: /home/cvs/master/68chaos_eebperf/drivers/scsi/sd.c,v
-retrieving revision 1.1.1.1
-diff -u -p -r1.1.1.1 sd.c
---- linux/drivers/scsi/sd.c    20 Aug 2004 18:10:16 -0000      1.1.1.1
-+++ linux/drivers/scsi/sd.c    26 Aug 2004 13:34:39 -0000
+ if [ "$CONFIG_BLK_DEV_SD" != "n" -a "$CONFIG_DISKDUMP" != "n" ]; then
+    dep_tristate '  SCSI dump support' CONFIG_SCSI_DUMP $CONFIG_SCSI
+diff -urp RH_2_4_21_47_0_1.orig/drivers/scsi/sd.c RH_2_4_21_47_0_1/drivers/scsi/sd.c
+--- RH_2_4_21_47_0_1.orig/drivers/scsi/sd.c    2006-11-20 16:59:45.000000000 +0200
++++ RH_2_4_21_47_0_1/drivers/scsi/sd.c 2007-05-21 19:14:27.000000000 +0300
 @@ -65,6 +65,40 @@
   *  static const char RCSid[] = "$Header:";
   */
@@ -80,7 +68,7 @@ diff -u -p -r1.1.1.1 sd.c
  /* device number --> sd_gendisks index */
  #define SD_MAJOR_IDX(i)               ( ((MAJOR(i) & 0x80) >> 4) + (MAJOR(i) & 7) )
  /* sd_gendisks index --> system major */
-@@ -351,6 +385,8 @@ static int sd_init_command(Scsi_Cmnd * S
+@@ -372,6 +406,8 @@ static int sd_init_command(Scsi_Cmnd * S
        SCSI_LOG_HLQUEUE(2, printk("%s : real dev = /dev/%d, block = %d\n",
                                   nbuff, dev, block));
  
@@ -89,7 +77,7 @@ diff -u -p -r1.1.1.1 sd.c
        /*
         * If we have a 1K hardware sectorsize, prevent access to single
         * 512 byte sectors.  In theory we could handle this - in fact
-@@ -545,7 +581,7 @@ static int sd_open(struct inode *inode, 
+@@ -575,7 +611,7 @@ static int sd_open(struct inode *inode, 
                        if (scsi_block_when_processing_errors(SDev))
                                scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, NULL);
  
@@ -98,7 +86,43 @@ diff -u -p -r1.1.1.1 sd.c
        return 0;
  
  error_out:
-@@ -1179,6 +1215,8 @@ static int sd_init()
+@@ -593,18 +629,31 @@ static int sd_release(struct inode *inod
+ {
+       int target;
+       Scsi_Device * SDev;
++      char nbuff[6];
+       target = DEVICE_NR(inode->i_rdev);
+       SDev = rscsi_disks[target].device;
+       if (!SDev)
+               return -ENODEV;
+-      SDev->access_count--;
+-
+-      if (SDev->removable) {
+-              if (!SDev->access_count)
++      if (!--SDev->access_count) {
++              /*
++               * Remove sd_iostats information about this disk
++               */
++              if (sd_iostats_procdir != NULL) {
++                      sd_devname(target, nbuff);
++                      remove_proc_entry(nbuff, sd_iostats_procdir);
++              }
++              if (sd_iostats != NULL) {
++                      if (sd_iostats[target] != NULL) {
++                              kfree (sd_iostats[target]);
++                              sd_iostats[target] = NULL;
++                      }
++              }
++              if (SDev->removable) {
+                       if (scsi_block_when_processing_errors(SDev))
+                               scsi_ioctl(SDev, SCSI_IOCTL_DOORUNLOCK, NULL);
++              }
+       }
+       if (SDev->host->hostt->module)
+               __MOD_DEC_USE_COUNT(SDev->host->hostt->module);
+@@ -1260,6 +1309,8 @@ static int sd_init()
  
        memset(sd_varyio, 0, (sd_template.dev_max << 4)); 
  
@@ -107,7 +131,7 @@ diff -u -p -r1.1.1.1 sd.c
        for (i = 0; i < sd_template.dev_max << 4; i++) {
                sd_blocksizes[i] = 1024;
                sd_hardsizes[i] = 512;
-@@ -1243,6 +1281,7 @@ cleanup_gendisks_de_arr:
+@@ -1324,6 +1375,7 @@ cleanup_gendisks_de_arr:
        kfree(sd_gendisks);
        sd_gendisks = NULL;
  cleanup_sd_gendisks:
@@ -115,7 +139,7 @@ diff -u -p -r1.1.1.1 sd.c
        kfree(sd_varyio);
  cleanup_varyio:
        kfree(sd_max_sectors);
-@@ -1466,6 +1505,316 @@ static void sd_detach(Scsi_Device * SDp)
+@@ -1547,6 +1599,321 @@ static void sd_detach(Scsi_Device * SDp)
        return;
  }
  
@@ -137,15 +161,20 @@ diff -u -p -r1.1.1.1 sd.c
 +        int                i;
 +      int                maxi;
 +
-+      if (sd_iostats == NULL) {
++      if (seq == NULL || sd_iostats == NULL) {
 +              printk(KERN_ERR "sd_iostats_seq_show: NULL stats array\n");
 +              BUG();
 +      }
++      
++      if (index >= sd_template.dev_max || !rscsi_disks[index].device)
++              return -ENXIO;  /* No such device */
 +
 +      stats = sd_iostats[index];
 +      if (stats == NULL) {
-+              printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
-+              BUG();
++                seq_printf(seq, "sd_iostats_seq_show: sd_iostats "
++                              "entry %d does not exist\n",
++                              index);
++              return 0;
 +      }
 +
 +        do_gettimeofday(&now);
@@ -432,7 +461,7 @@ diff -u -p -r1.1.1.1 sd.c
  static int __init init_sd(void)
  {
        sd_template.module = THIS_MODULE;
-@@ -1488,6 +1837,7 @@ static void __exit exit_sd(void)
+@@ -1569,6 +1936,7 @@ static void __exit exit_sd(void)
                kfree(sd_blocksizes);
                kfree(sd_hardsizes);
                kfree(sd_varyio);
index 12e4ac0..4e06c09 100644 (file)
@@ -1,8 +1,10 @@
-Index: linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig
+Index: linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig\r
+===================================================================\r
+Index: linux+rhel4+chaos/drivers/scsi/Kconfig
 ===================================================================
---- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/Kconfig     2005-04-01 18:36:39.218039672 +0300
-+++ linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig  2005-04-01 18:36:45.571073864 +0300
-@@ -61,6 +61,14 @@
+--- linux+rhel4+chaos.orig/drivers/scsi/Kconfig
++++ linux+rhel4+chaos/drivers/scsi/Kconfig
+@@ -61,6 +61,14 @@ config SCSI_DUMP
        help
           SCSI dump support
  
@@ -17,10 +19,10 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/Kconfig
  config CHR_DEV_ST
        tristate "SCSI tape support"
        depends on SCSI
-Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
+Index: linux+rhel4+chaos/drivers/scsi/sd.c
 ===================================================================
---- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/sd.c        2005-04-01 18:36:39.223038912 +0300
-+++ linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c     2005-04-01 18:37:42.537413664 +0300
+--- linux+rhel4+chaos.orig/drivers/scsi/sd.c
++++ linux+rhel4+chaos/drivers/scsi/sd.c
 @@ -63,6 +63,38 @@
  
  #include "scsi_logging.h"
@@ -68,7 +70,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
  /*
   * Time out in seconds for disks and Magneto-opticals (which are slower).
   */
-@@ -276,6 +309,9 @@
+@@ -278,6 +311,9 @@ static int sd_init_command(struct scsi_c
        SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n",
                                   disk->disk_name, (unsigned long long)block));
  
@@ -78,7 +80,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
        /*
         * If we have a 1K hardware sectorsize, prevent access to single
         * 512 byte sectors.  In theory we could handle this - in fact
-@@ -472,6 +508,7 @@
+@@ -474,6 +510,7 @@ static int sd_open(struct inode *inode, 
                        scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
        }
  
@@ -86,7 +88,30 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
        return 0;
  
  error_out:
-@@ -1573,6 +1610,327 @@
+@@ -500,8 +537,20 @@ static int sd_release(struct inode *inod
+       SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
+-      if (!--sdkp->openers && sdev->removable) {
+-              if (scsi_block_when_processing_errors(sdev))
++      if (!--sdkp->openers) {
++              /*
++               * Remove sd_iostats information about this disk
++               */
++              if (sd_iostats_procdir != NULL) {
++                      remove_proc_entry(disk->disk_name, sd_iostats_procdir);
++              }
++              if (sd_iostats != NULL) {
++                      if (sd_iostats[sdkp->index] != NULL) {
++                              kfree (sd_iostats[sdkp->index]);
++                              sd_iostats[sdkp->index] = NULL;
++                      }
++              }
++              if (sdev->removable && scsi_block_when_processing_errors(sdev))
+                       scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
+       }
+@@ -1575,6 +1624,342 @@ static void sd_shutdown(struct device *d
        sd_sync_cache(sdp);
  }     
  
@@ -95,7 +120,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
 +sd_iostats_seq_show(struct seq_file *seq, void *v)
 +{
 +        struct timeval     now;
-+        struct gendisk *disk = seq->private;
++        struct gendisk *disk;
 +        iostat_stats_t    *stats;
 +        unsigned long long read_len;
 +        unsigned long long read_len_tot;
@@ -108,6 +133,19 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
 +        int                i;
 +        int                maxi;
 +
++      if (seq == NULL || seq->private == NULL) {
++              printk(KERN_ERR "sd_iostats_seq_show: NULL disk\n");
++              BUG();
++      }
++
++      disk = seq->private;
++
++      if (scsi_disk(disk) == NULL || (disk->flags & GENHD_FL_UP) == 0) {
++              seq_printf(seq, "sd_iostats_seq_show: Device %s "
++                              "does not exist\n", disk->disk_name);
++              return 0;
++      }
++
 +        if (sd_iostats == NULL) {
 +                printk(KERN_ERR "sd_iostats_seq_show: NULL stats array\n");
 +                BUG();
@@ -115,8 +153,10 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
 +
 +        stats = sd_iostats[scsi_disk(disk)->index];
 +        if (stats == NULL) {
-+                printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
-+                BUG();
++                seq_printf(seq, "sd_iostats_seq_show: sd_iostats "
++                              "entry %d does not exist\n",
++                              scsi_disk(disk)->index);
++              return 0;
 +        }
 +
 +        do_gettimeofday(&now);
@@ -414,7 +454,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
  /**
   *    init_sd - entry point for this driver (both when built in or when
   *    a module).
-@@ -1582,6 +1940,7 @@
+@@ -1584,6 +1969,7 @@ static void sd_shutdown(struct device *d
  static int __init init_sd(void)
  {
        int majors = 0, i;
@@ -422,7 +462,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
  
        SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
  
-@@ -1592,7 +1951,10 @@
+@@ -1594,7 +1980,10 @@ static int __init init_sd(void)
        if (!majors)
                return -ENODEV;
  
@@ -434,7 +474,7 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
  }
  
  /**
-@@ -1606,6 +1968,7 @@
+@@ -1608,6 +1997,7 @@ static void __exit exit_sd(void)
  
        SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
  
@@ -442,10 +482,10 @@ Index: linux-2.6.9-5.0.3.EL/drivers/scsi/sd.c
        scsi_unregister_driver(&sd_template.gendrv);
        for (i = 0; i < SD_MAJORS; i++)
                unregister_blkdev(sd_major(i), "sd");
-Index: linux-2.6.9-5.0.3.EL/drivers/scsi/scsi_proc.c
+Index: linux+rhel4+chaos/drivers/scsi/scsi_proc.c
 ===================================================================
---- linux-2.6.9-5.0.3.EL.orig/drivers/scsi/scsi_proc.c 2005-04-01 18:36:39.234037240 +0300
-+++ linux-2.6.9-5.0.3.EL/drivers/scsi/scsi_proc.c      2005-04-01 18:36:45.578072800 +0300
+--- 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)
diff --git a/lustre/kernel_patches/patches/sd_iostats-2.6-suse.patch b/lustre/kernel_patches/patches/sd_iostats-2.6-suse.patch
deleted file mode 100644 (file)
index f12319c..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/Kconfig
-===================================================================
---- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/Kconfig  2004-11-11 07:28:52.000000000 -0800
-+++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/Kconfig       2005-01-06 22:58:42.338770968 -0800
-@@ -55,6 +55,14 @@
-         In this case, do not compile the driver for your SCSI host adapter
-         (below) as a module either.
-+config SD_IOSTATS
-+   bool "Enable SCSI disk I/O stats"
-+   depends on BLK_DEV_SD
-+   default y
-+   ---help---
-+     This enables SCSI disk I/O stats collection.  You must also enable
-+     /proc file system support if you want this feature.
-+
- config CHR_DEV_ST
-       tristate "SCSI tape support"
-       depends on SCSI
-Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/sd.c
-===================================================================
---- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/sd.c     2004-11-11 07:28:28.000000000 -0800
-+++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/sd.c  2005-01-07 01:29:47.033727872 -0800
-@@ -59,12 +59,44 @@
- #include "scsi_logging.h"
-+#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-+# include <linux/proc_fs.h>
-+# include <linux/seq_file.h>
-+
-+typedef struct {
-+        unsigned long long iostat_size;
-+        unsigned long long iostat_count;
-+} iostat_counter_t;
-+
-+#define IOSTAT_NCOUNTERS 16
-+typedef struct {
-+        iostat_counter_t        iostat_read_histogram[IOSTAT_NCOUNTERS];
-+        iostat_counter_t        iostat_write_histogram[IOSTAT_NCOUNTERS];
-+        struct timeval          iostat_timeval;
-+} iostat_stats_t;
-+
-+iostat_stats_t       **sd_iostats;
-+spinlock_t             sd_iostats_lock;
-+struct proc_dir_entry *sd_iostats_procdir;
-+char                   sd_iostats_procdir_name[] = "sd_iostats";
-+
-+extern void sd_iostats_init(void);
-+extern void sd_iostats_init_disk(struct gendisk *);
-+extern void sd_iostats_fini(void);
-+extern void sd_iostats_bump(int disk, unsigned int nsect, int iswrite);
-+#else
-+static inline void sd_iostats_init(void) {}
-+static inline void sd_iostats_init_disk(struct gendisk *disk) {}
-+static inline void sd_iostats_fini(void) {}
-+static inline void sd_iostats_bump(int disk, unsigned int nsect, int iswrite) {}
-+#endif
- /*
-  * Remaining dev_t-handling stuff
-  */
- #define SD_MAJORS     16
- #define SD_DISKS      32768   /* anything between 256 and 262144 */
-+#define SD_STATS 256
- /*
-  * Time out in seconds for disks and Magneto-opticals (which are slower).
-@@ -264,6 +296,9 @@
-       SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n",
-                                  disk->disk_name, (unsigned long long)block));
-+   sd_iostats_bump(scsi_disk(disk)->index, this_count,
-+                   rq_data_dir(SCpnt->request) == WRITE);
-+
-       /*
-        * If we have a 1K hardware sectorsize, prevent access to single
-        * 512 byte sectors.  In theory we could handle this - in fact
-@@ -460,6 +495,7 @@
-                       scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
-       }
-+   sd_iostats_init_disk(disk);
-       return 0;
- error_out:
-@@ -1548,6 +1584,327 @@
-       sd_sync_cache(sdp);
- }     
-+#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
-+static int
-+sd_iostats_seq_show(struct seq_file *seq, void *v)
-+{
-+        struct timeval     now;
-+        struct gendisk *disk = seq->private;
-+        iostat_stats_t    *stats;
-+        unsigned long long read_len;
-+        unsigned long long read_len_tot;
-+        unsigned long      read_num;
-+        unsigned long      read_num_tot;
-+        unsigned long long write_len;
-+        unsigned long long write_len_tot;
-+        unsigned long      write_num;
-+        unsigned long      write_num_tot;
-+        int                i;
-+        int                maxi;
-+
-+        if (sd_iostats == NULL) {
-+                printk(KERN_ERR "sd_iostats_seq_show: NULL stats array\n");
-+                BUG();
-+        }
-+
-+        stats = sd_iostats[scsi_disk(disk)->index];
-+        if (stats == NULL) {
-+                printk(KERN_ERR "sd_iostats_seq_show: NULL stats entry\n");
-+                BUG();
-+        }
-+
-+        do_gettimeofday(&now);
-+        now.tv_sec -= stats->iostat_timeval.tv_sec;
-+        now.tv_usec -= stats->iostat_timeval.tv_usec;
-+        if (now.tv_usec < 0) {
-+                now.tv_usec += 1000000;
-+                now.tv_sec--;
-+        }
-+
-+        /* this sampling races with updates */
-+        seq_printf(seq, "index:        %lu   snapshot_time:         %lu.%06lu\n",
-+                   scsi_disk(disk)->index, now.tv_sec, now.tv_usec);
-+
-+        for (i = IOSTAT_NCOUNTERS - 1; i > 0; i--)
-+                if (stats->iostat_read_histogram[i].iostat_count != 0 ||
-+                    stats->iostat_write_histogram[i].iostat_count != 0)
-+                        break;
-+        maxi = i;
-+
-+        seq_printf(seq, "%8s %8s %12s %8s %12s\n", "size", 
-+                   "reads", "total", "writes", "total");
-+
-+        read_len_tot = write_len_tot = 0;
-+        read_num_tot = write_num_tot = 0;
-+        for (i = 0; i <= maxi; i++) {
-+                read_len = stats->iostat_read_histogram[i].iostat_size;
-+                read_len_tot += read_len;
-+                read_num = stats->iostat_read_histogram[i].iostat_count;
-+                read_num_tot += read_num;
-+
-+                write_len = stats->iostat_write_histogram[i].iostat_size;
-+                write_len_tot += write_len;
-+                write_num = stats->iostat_write_histogram[i].iostat_count;
-+                write_num_tot += write_num;
-+
-+                seq_printf (seq, "%8d %8lu %12llu %8lu %12llu\n", 
-+                            512<<i, read_num, read_len, write_num, write_len);
-+        }
-+        
-+        seq_printf(seq, "%8s %8lu %12llu %8lu %12llu\n", "total",
-+                   read_num_tot, read_len_tot, 
-+                   write_num_tot, write_len_tot);
-+        return 0;
-+}
-+
-+static void *
-+sd_iostats_seq_start(struct seq_file *p, loff_t *pos)
-+{
-+        return (*pos == 0) ? (void *)1 : NULL;
-+}
-+
-+static void *
-+sd_iostats_seq_next(struct seq_file *p, void *v, loff_t *pos)
-+{
-+        ++*pos;
-+        return NULL;
-+}
-+
-+static void
-+sd_iostats_seq_stop(struct seq_file *p, void *v)
-+{
-+}
-+
-+static struct seq_operations sd_iostats_seqops = {
-+        .start = sd_iostats_seq_start,
-+        .stop  = sd_iostats_seq_stop,
-+        .next  = sd_iostats_seq_next,
-+        .show  = sd_iostats_seq_show,
-+};
-+
-+static int
-+sd_iostats_seq_open (struct inode *inode, struct file *file)
-+{
-+        int                    rc;
-+
-+        rc = seq_open(file, &sd_iostats_seqops);
-+        if (rc != 0)
-+                return rc;
-+
-+        ((struct seq_file *)file->private_data)->private = PDE(inode)->data;
-+        return 0;
-+}
-+
-+static ssize_t
-+sd_iostats_seq_write(struct file *file, const char *buffer,
-+                     size_t len, loff_t *off)
-+{
-+        struct seq_file   *seq = file->private_data;
-+        struct gendisk *disk = seq->private;
-+        iostat_stats_t    *stats = sd_iostats[scsi_disk(disk)->index];
-+        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).
-@@ -1557,6 +1914,7 @@
- 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"));
-@@ -1567,7 +1925,10 @@
-       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;
- }
- /**
-@@ -1581,6 +1942,7 @@
-       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-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/scsi_proc.c
-===================================================================
---- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik.orig/drivers/scsi/scsi_proc.c      2004-04-03 19:36:17.000000000 -0800
-+++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891_lustre.1.4.0-phik/drivers/scsi/scsi_proc.c   2005-01-07 00:15:53.905665776 -0800
-@@ -37,7 +37,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);
index c284949..1e56ba5 100644 (file)
@@ -1,7 +1,7 @@
 lustre-version-revert_suse.patch
 lustre_version.patch
 dev_read_only-2.6-lnxi.patch
-sd_iostats-2.6-suse.patch
+sd_iostats-2.6-rhel4.patch 
 blkdev_tunables-2.6-suse.patch
 uml-exprt-clearuser.patch
 qsnet-suse-2.6.patch