[Pkg-lustre-svn-commit] updated: [c793485] Lustre kernel patchset adapted
Marco Nelles
marco.nelles at credativ.com
Mon Jul 2 10:58:03 UTC 2012
The following commit has been merged in the master branch:
commit c7934855f6faf7b88a7fe11c98d3c9476f2fefa1
Author: Marco Nelles <marco.nelles at credativ.com>
Date: Mon Jul 2 14:57:29 2012 +0200
Lustre kernel patchset adapted
diff --git a/debian/patches/lustre-kernel-patchset.patch b/debian/patches/lustre-kernel-patchset.patch
index c6fe8ed..ac96d5f 100644
--- a/debian/patches/lustre-kernel-patchset.patch
+++ b/debian/patches/lustre-kernel-patchset.patch
@@ -228,6 +228,82 @@ index 0000000..4a72c93
+ extern int set_blocksize(struct block_device *, int);
+ extern int sb_set_blocksize(struct super_block *, int);
+ extern int sb_min_blocksize(struct super_block *, int);
+diff --git a/lustre/kernel_patches/patches/iopen-misc-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/iopen-misc-2.6.32-vanilla.patch
+new file mode 100644
+index 0000000..93b329f
+--- /dev/null
++++ b/lustre/kernel_patches/patches/iopen-misc-2.6.32-vanilla.patch
+@@ -0,0 +1,70 @@
++This patch is needed to allow sharing the kernel with 1.8, and until
++the MGS and llog code has been moved over to using the OSD interface.
++
++Index: linux-source-2.6.32/fs/dcache.c
++===================================================================
++--- linux-source-2.6.32.orig/fs/dcache.c 2012-07-02 14:26:15.005193731 +0200
+++++ linux-source-2.6.32/fs/dcache.c 2012-07-02 14:26:22.869196311 +0200
++@@ -1557,13 +1557,22 @@
++ * Adds a dentry to the hash according to its name.
++ */
++
++-void d_rehash(struct dentry * entry)
+++void d_rehash_cond(struct dentry * entry, int lock)
++ {
++- spin_lock(&dcache_lock);
+++ if (lock)
+++ spin_lock(&dcache_lock);
++ spin_lock(&entry->d_lock);
++ _d_rehash(entry);
++ spin_unlock(&entry->d_lock);
++- spin_unlock(&dcache_lock);
+++ if (lock)
+++ spin_unlock(&dcache_lock);
+++}
+++
+++EXPORT_SYMBOL(d_rehash_cond);
+++
+++void d_rehash(struct dentry * entry)
+++{
+++ d_rehash_cond(entry, 1);
++ }
++
++ /*
++@@ -1638,7 +1647,7 @@
++ * Update the dcache to reflect the move of a file name. Negative
++ * dcache entries should not be moved in this way.
++ */
++-static void d_move_locked(struct dentry * dentry, struct dentry * target)
+++void d_move_locked(struct dentry * dentry, struct dentry * target)
++ {
++ struct hlist_head *list;
++
++@@ -1695,6 +1704,7 @@
++ spin_unlock(&dentry->d_lock);
++ write_sequnlock(&rename_lock);
++ }
+++EXPORT_SYMBOL(d_move_locked);
++
++ /**
++ * d_move - move a dentry
++Index: linux-source-2.6.32/include/linux/dcache.h
++===================================================================
++--- linux-source-2.6.32.orig/include/linux/dcache.h 2012-07-02 14:26:14.905193576 +0200
+++++ linux-source-2.6.32/include/linux/dcache.h 2012-07-02 14:26:22.869196311 +0200
++@@ -263,6 +263,7 @@
++ * This adds the entry to the hash queues.
++ */
++ extern void d_rehash(struct dentry *);
+++extern void d_rehash_cond(struct dentry *, int lock);
++
++ /**
++ * d_add - add dentry to hash queues
++@@ -298,6 +299,7 @@
++
++ /* used for rename() and baskets */
++ extern void d_move(struct dentry *, struct dentry *);
+++extern void d_move_locked(struct dentry *, struct dentry *);
++ extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
++
++ /* appendix may either be NULL or be used for transname suffixes */
diff --git a/lustre/kernel_patches/patches/jbd2-jcberr-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/jbd2-jcberr-2.6.32-vanilla.patch
new file mode 100644
index 0000000..ed41849
@@ -510,6 +586,295 @@ index 0000000..1fa1d26
+ #else
+ #define MPT_SCSI_SG_DEPTH CONFIG_FUSION_MAX_SGE
+ #endif
+diff --git a/lustre/kernel_patches/patches/quota-support-64-bit-quota-format-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/quota-support-64-bit-quota-format-2.6.32-vanilla.patch
+new file mode 100644
+index 0000000..137410e
+--- /dev/null
++++ b/lustre/kernel_patches/patches/quota-support-64-bit-quota-format-2.6.32-vanilla.patch
+@@ -0,0 +1,283 @@
++From: Jan Kara <jack at suse.cz>
++
++Implement conversion functions for new version (version 1) of quota format
++which supports 64-bit block and inode limits and 64-bit inode usage. The
++original implementation has been written by Andrew Perepechko.
++
++Signed-off-by: Andrew Perepechko <andrew.perepechko at sun.com>
++Signed-off-by: Jan Kara <jack at suse.cz>
++Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
++---
++
++ fs/quota_v2.c | 140 ++++++++++++++++++++++++++++++++++++----------
++ fs/quotaio_v2.h | 26 ++++++--
++ 2 files changed, 132 insertions(+), 34 deletions(-)
++
++Index: linux-source-2.6.32/fs/quota/quota_v2.c
++===================================================================
++--- linux-source-2.6.32.orig/fs/quota/quota_v2.c 2009-12-03 04:51:21.000000000 +0100
+++++ linux-source-2.6.32/fs/quota/quota_v2.c 2012-07-02 14:50:02.977192453 +0200
++@@ -23,14 +23,24 @@
++
++ #define __QUOTA_V2_PARANOIA
++
++-static void v2_mem2diskdqb(void *dp, struct dquot *dquot);
++-static void v2_disk2memdqb(struct dquot *dquot, void *dp);
++-static int v2_is_id(void *dp, struct dquot *dquot);
++-
++-static struct qtree_fmt_operations v2_qtree_ops = {
++- .mem2disk_dqblk = v2_mem2diskdqb,
++- .disk2mem_dqblk = v2_disk2memdqb,
++- .is_id = v2_is_id,
+++static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
+++static void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
+++static int v2r0_is_id(void *dp, struct dquot *dquot);
+++
+++static struct qtree_fmt_operations v2r0_qtree_ops = {
+++ .mem2disk_dqblk = v2r0_mem2diskdqb,
+++ .disk2mem_dqblk = v2r0_disk2memdqb,
+++ .is_id = v2r0_is_id,
+++};
+++
+++static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
+++static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
+++static int v2r1_is_id(void *dp, struct dquot *dquot);
+++
+++static struct qtree_fmt_operations v2r1_qtree_ops = {
+++ .mem2disk_dqblk = v2r1_mem2diskdqb,
+++ .disk2mem_dqblk = v2r1_disk2memdqb,
+++ .is_id = v2r1_is_id,
++ };
++
++ #define QUOTABLOCK_BITS 10
++@@ -46,8 +56,7 @@
++ return blocks << QUOTABLOCK_BITS;
++ }
++
++-/* Check whether given file is really vfsv0 quotafile */
++-static int v2_check_quota_file(struct super_block *sb, int type)
+++static int v2_check_quota_file_header(struct super_block *sb, int type)
++ {
++ struct v2_disk_dqheader dqhead;
++ ssize_t size;
++@@ -59,12 +68,20 @@
++ if (size != sizeof(struct v2_disk_dqheader)) {
++ printk("quota_v2: failed read expected=%zd got=%zd\n",
++ sizeof(struct v2_disk_dqheader), size);
++- return 0;
+++ return -EIO;
++ }
++- if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
++- le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
++- return 0;
++- return 1;
+++ if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
+++ return -ENOENT;
+++ if (le32_to_cpu(dqhead.dqh_version) > quota_versions[type])
+++ return -EOPNOTSUPP;
+++ return le32_to_cpu(dqhead.dqh_version);
+++}
+++
+++
+++/* Check whether given file is really vfsv0 quotafile */
+++static int v2_check_quota_file(struct super_block *sb, int type)
+++{
+++ return v2_check_quota_file_header(sb, type) >= 0;
++ }
++
++ /* Read information header from quota file */
++@@ -74,7 +91,13 @@
++ struct mem_dqinfo *info = sb_dqinfo(sb, type);
++ struct qtree_mem_dqinfo *qinfo;
++ ssize_t size;
+++ int version = v2_check_quota_file_header(sb, type);
++
+++ if (version < 0) {
+++ printk(KERN_WARNING "Cannot identify quota file version on "
+++ "device %s: %d\n", sb->s_id, version);
+++ return -1;
+++ }
++ size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
++ sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
++ if (size != sizeof(struct v2_disk_dqinfo)) {
++@@ -89,9 +112,14 @@
++ return -1;
++ }
++ qinfo = info->dqi_priv;
++- /* limits are stored as unsigned 32-bit data */
++- info->dqi_maxblimit = 0xffffffff;
++- info->dqi_maxilimit = 0xffffffff;
+++ if (version == 0) {
+++ /* limits are stored as unsigned 32-bit data */
+++ info->dqi_maxblimit = 0xffffffff;
+++ info->dqi_maxilimit = 0xffffffff;
+++ } else {
+++ info->dqi_maxblimit = 0x7fffffffffffffffULL;
+++ info->dqi_maxilimit = 0x7fffffffffffffffULL;
+++ }
++ info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
++ info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
++ info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
++@@ -103,8 +131,13 @@
++ qinfo->dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
++ qinfo->dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
++ qinfo->dqi_qtree_depth = qtree_depth(qinfo);
++- qinfo->dqi_entry_size = sizeof(struct v2_disk_dqblk);
++- qinfo->dqi_ops = &v2_qtree_ops;
+++ if (version == 0) {
+++ qinfo->dqi_entry_size = sizeof(struct v2r0_disk_dqblk);
+++ qinfo->dqi_ops = &v2r0_qtree_ops;
+++ } else {
+++ qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
+++ qinfo->dqi_ops = &v2r1_qtree_ops;
+++ }
++ return 0;
++ }
++
++@@ -135,9 +168,9 @@
++ return 0;
++ }
++
++-static void v2_disk2memdqb(struct dquot *dquot, void *dp)
+++static void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
++ {
++- struct v2_disk_dqblk *d = dp, empty;
+++ struct v2r0_disk_dqblk *d = dp, empty;
++ struct mem_dqblk *m = &dquot->dq_dqb;
++
++ m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
++@@ -149,15 +182,15 @@
++ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
++ m->dqb_btime = le64_to_cpu(d->dqb_btime);
++ /* We need to escape back all-zero structure */
++- memset(&empty, 0, sizeof(struct v2_disk_dqblk));
+++ memset(&empty, 0, sizeof(struct v2r0_disk_dqblk));
++ empty.dqb_itime = cpu_to_le64(1);
++- if (!memcmp(&empty, dp, sizeof(struct v2_disk_dqblk)))
+++ if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
++ m->dqb_itime = 0;
++ }
++
++-static void v2_mem2diskdqb(void *dp, struct dquot *dquot)
+++static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
++ {
++- struct v2_disk_dqblk *d = dp;
+++ struct v2r0_disk_dqblk *d = dp;
++ struct mem_dqblk *m = &dquot->dq_dqb;
++ struct qtree_mem_dqinfo *info =
++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
++@@ -175,9 +208,60 @@
++ d->dqb_itime = cpu_to_le64(1);
++ }
++
++-static int v2_is_id(void *dp, struct dquot *dquot)
+++static int v2r0_is_id(void *dp, struct dquot *dquot)
+++{
+++ struct v2r0_disk_dqblk *d = dp;
+++ struct qtree_mem_dqinfo *info =
+++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
+++
+++ if (qtree_entry_unused(info, dp))
+++ return 0;
+++ return le32_to_cpu(d->dqb_id) == dquot->dq_id;
+++}
+++
+++static void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
+++{
+++ struct v2r1_disk_dqblk *d = dp, empty;
+++ struct mem_dqblk *m = &dquot->dq_dqb;
+++
+++ m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
+++ m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
+++ m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
+++ m->dqb_itime = le64_to_cpu(d->dqb_itime);
+++ m->dqb_bhardlimit = v2_qbtos(le64_to_cpu(d->dqb_bhardlimit));
+++ m->dqb_bsoftlimit = v2_qbtos(le64_to_cpu(d->dqb_bsoftlimit));
+++ m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
+++ m->dqb_btime = le64_to_cpu(d->dqb_btime);
+++ /* We need to escape back all-zero structure */
+++ memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
+++ empty.dqb_itime = cpu_to_le64(1);
+++ if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
+++ m->dqb_itime = 0;
+++}
+++
+++static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
+++{
+++ struct v2r1_disk_dqblk *d = dp;
+++ struct mem_dqblk *m = &dquot->dq_dqb;
+++ struct qtree_mem_dqinfo *info =
+++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
+++
+++ d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
+++ d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
+++ d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
+++ d->dqb_itime = cpu_to_le64(m->dqb_itime);
+++ d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
+++ d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
+++ d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
+++ d->dqb_btime = cpu_to_le64(m->dqb_btime);
+++ d->dqb_id = cpu_to_le32(dquot->dq_id);
+++ if (qtree_entry_unused(info, dp))
+++ d->dqb_itime = cpu_to_le64(1);
+++}
+++
+++static int v2r1_is_id(void *dp, struct dquot *dquot)
++ {
++- struct v2_disk_dqblk *d = dp;
+++ struct v2r1_disk_dqblk *d = dp;
++ struct qtree_mem_dqinfo *info =
++ sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
++
++Index: linux-source-2.6.32/fs/quota/quotaio_v2.h
++===================================================================
++--- linux-source-2.6.32.orig/fs/quota/quotaio_v2.h 2009-12-03 04:51:21.000000000 +0100
+++++ linux-source-2.6.32/fs/quota/quotaio_v2.h 2012-07-02 14:50:02.977192453 +0200
++@@ -17,8 +17,8 @@
++ }
++
++ #define V2_INITQVERSIONS {\
++- 0, /* USRQUOTA */\
++- 0 /* GRPQUOTA */\
+++ 1, /* USRQUOTA */\
+++ 1 /* GRPQUOTA */\
++ }
++
++ /* First generic header */
++@@ -28,11 +28,11 @@
++ };
++
++ /*
++- * The following structure defines the format of the disk quota file
++- * (as it appears on disk) - the file is a radix tree whose leaves point
++- * to blocks of these structures.
+++ * The following structure defines the format of the disk quota file in version
+++ * 0 - the file is a radix tree whose leaves point to blocks of these
+++ * structures.
++ */
++-struct v2_disk_dqblk {
+++struct v2r0_disk_dqblk {
++ __le32 dqb_id; /* id this quota applies to */
++ __le32 dqb_ihardlimit; /* absolute limit on allocated inodes */
++ __le32 dqb_isoftlimit; /* preferred inode limit */
++@@ -42,6 +42,20 @@
++ __le64 dqb_curspace; /* current space occupied (in bytes) */
++ __le64 dqb_btime; /* time limit for excessive disk use */
++ __le64 dqb_itime; /* time limit for excessive inode use */
+++};
+++
+++/* The same structure in quota file version 1 */
+++struct v2r1_disk_dqblk {
+++ __le32 dqb_id; /* id this quota applies to */
+++ __le32 dqb_padding; /* padding field */
+++ __le64 dqb_ihardlimit; /* absolute limit on allocated inodes */
+++ __le64 dqb_isoftlimit; /* preferred inode limit */
+++ __le64 dqb_curinodes; /* current # allocated inodes */
+++ __le64 dqb_bhardlimit; /* absolute limit on disk space */
+++ __le64 dqb_bsoftlimit; /* preferred limit on disk space */
+++ __le64 dqb_curspace; /* current space occupied (in bytes) */
+++ __le64 dqb_btime; /* time limit for excessive disk use */
+++ __le64 dqb_itime; /* time limit for excessive inode use */
++ };
++
++ /* Header with type and version specific information */
diff --git a/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/raid5-mmp-unplug-dev-2.6.32-vanilla.patch
new file mode 100644
index 0000000..d421e25
@@ -540,6 +905,591 @@ index 0000000..d421e25
+ return 0;
+ }
+
+diff --git a/lustre/kernel_patches/patches/sd_iostats-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/sd_iostats-2.6.32-vanilla.patch
+new file mode 100644
+index 0000000..bf5e226
+--- /dev/null
++++ b/lustre/kernel_patches/patches/sd_iostats-2.6.32-vanilla.patch
+@@ -0,0 +1,579 @@
++Index: linux-source-2.6.32/drivers/scsi/Kconfig
++===================================================================
++--- linux-source-2.6.32.orig/drivers/scsi/Kconfig 2012-05-05 19:43:27.000000000 +0200
+++++ linux-source-2.6.32/drivers/scsi/Kconfig 2012-07-02 14:36:01.093197984 +0200
++@@ -82,6 +82,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-source-2.6.32/drivers/scsi/scsi_proc.c
++===================================================================
++--- linux-source-2.6.32.orig/drivers/scsi/scsi_proc.c 2009-12-03 04:51:21.000000000 +0100
+++++ linux-source-2.6.32/drivers/scsi/scsi_proc.c 2012-07-02 14:36:01.093197984 +0200
++@@ -40,7 +40,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 DEFINE_MUTEX(global_host_template_mutex);
++Index: linux-source-2.6.32/drivers/scsi/sd.c
++===================================================================
++--- linux-source-2.6.32.orig/drivers/scsi/sd.c 2012-05-05 19:43:27.000000000 +0200
+++++ linux-source-2.6.32/drivers/scsi/sd.c 2012-07-02 14:36:01.097202891 +0200
++@@ -121,6 +121,24 @@
++ struct kmem_cache *sd_cdb_cache;
++ mempool_t *sd_cdb_pool;
++
+++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
+++# include <linux/proc_fs.h>
+++# include <linux/seq_file.h>
+++struct proc_dir_entry *sd_iostats_procdir = NULL;
+++char sd_iostats_procdir_name[] = "sd_iostats";
+++static struct file_operations sd_iostats_proc_fops;
+++
+++extern void sd_iostats_init(void);
+++extern void sd_iostats_fini(void);
+++void sd_iostats_start_req(struct scsi_cmnd *SCpnt);
+++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt);
+++#else
+++static inline void sd_iostats_init(void) {}
+++static inline void sd_iostats_fini(void) {}
+++static inline void sd_iostats_start_req(struct scsi_cmnd *SCpnt) {}
+++static inline void sd_iostats_finish_req(struct scsi_cmnd *SCpnt) {}
+++#endif
+++
++ static const char *sd_cache_types[] = {
++ "write through", "none", "write back",
++ "write back, no read (daft)"
++@@ -647,6 +665,8 @@
++ if (host_dif || scsi_prot_sg_count(SCpnt))
++ sd_prot_op(SCpnt, host_dif);
++
+++ sd_iostats_start_req(SCpnt);
+++
++ /*
++ * We shouldn't disconnect in the middle of a sector, so with a dumb
++ * host adapter, it's safe to assume that we can at least transfer
++@@ -1164,6 +1184,7 @@
++ break;
++ }
++ out:
+++ sd_iostats_finish_req(SCpnt);
++ if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt))
++ sd_dif_complete(SCpnt, good_bytes);
++
++@@ -2116,6 +2137,36 @@
++ if (sdp->removable)
++ gd->flags |= GENHD_FL_REMOVABLE;
++
+++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
+++ sdkp->stats = kzalloc(sizeof(iostat_stats_t), GFP_KERNEL);
+++ if (!sdkp->stats) {
+++ printk(KERN_WARNING "cannot allocate iostat structure for"
+++ "%s\n", gd->disk_name);
+++ } else {
+++ do_gettimeofday(&sdkp->stats->iostat_timeval);
+++ sdkp->stats->iostat_queue_stamp = jiffies;
+++ spin_lock_init(&sdkp->stats->iostat_lock);
+++ if (sd_iostats_procdir) {
+++ struct proc_dir_entry *pde;
+++ pde = create_proc_entry(gd->disk_name, S_IRUGO | S_IWUSR,
+++ sd_iostats_procdir);
+++ if (!pde) {
+++ printk(KERN_WARNING "Can't create /proc/scsi/"
+++ "%s/%s\n",
+++ sd_iostats_procdir_name,
+++ gd->disk_name);
+++ kfree(sdkp->stats);
+++ sdkp->stats = NULL;
+++ } else {
+++ pde->proc_fops = &sd_iostats_proc_fops;
+++ pde->data = gd;
+++ }
+++ } else {
+++ kfree(sdkp->stats);
+++ sdkp->stats = NULL;
+++ }
+++ }
+++#endif
++ dev_set_drvdata(dev, sdkp);
++ add_disk(gd);
++ sd_dif_config_host(sdkp);
++@@ -2263,6 +2314,366 @@
++ return 0;
++ }
++
+++#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;
+++
+++ stats = scsi_disk(disk)->stats;
+++ 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",
+++ (unsigned long) 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\n", "total",
+++ read_num_tot, read_len_tot,
+++ write_num_tot, write_len_tot);
+++
+++ seq_printf(seq, "%8s %8s %8s\n", "qdepth", "ticks", "%");
+++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
+++ unsigned long long ticks, percent;
+++ ticks = stats->iostat_queue_ticks[i];
+++ if (ticks == 0)
+++ continue;
+++ percent = stats->iostat_queue_ticks[i] * 100;
+++ do_div(percent, stats->iostat_queue_ticks_sum);
+++ seq_printf(seq, "%8d %8llu %8llu\n", i, ticks, percent);
+++ }
+++
+++ if (stats->iostat_reqs != 0) {
+++ unsigned long long aveseek = 0, percent = 0;
+++
+++ if (stats->iostat_seeks) {
+++ aveseek = stats->iostat_seek_sectors;
+++ do_div(aveseek, stats->iostat_seeks);
+++ percent = stats->iostat_seeks * 100;
+++ do_div(percent, stats->iostat_reqs);
+++ }
+++
+++ seq_printf(seq, "\n%llu sectors in %llu reqs: %llu seek(s) over "
+++ "%llu sectors in ave, %llu%% of all reqs\n",
+++ stats->iostat_sectors, stats->iostat_reqs,
+++ stats->iostat_seeks, aveseek, percent);
+++ }
+++
+++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "process time", "reads",
+++ "%%", "writes", "%%");
+++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
+++ unsigned long read_percent = 0, write_percent = 0;
+++ if (stats->iostat_wtime[i] == 0 &&
+++ stats->iostat_rtime[i] == 0)
+++ continue;
+++ if (stats->iostat_read_reqs)
+++ read_percent = stats->iostat_rtime[i] * 100 /
+++ stats->iostat_read_reqs;
+++ if (stats->iostat_write_reqs)
+++ write_percent = stats->iostat_wtime[i] * 100 /
+++ stats->iostat_write_reqs;
+++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
+++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
+++ stats->iostat_rtime[i], read_percent,
+++ stats->iostat_wtime[i], write_percent);
+++ }
+++
+++ seq_printf(seq, "\n%16s %8s %8s %8s %8s\n", "time in queue", "reads",
+++ "%%", "writes", "%%");
+++ for (i = 0; i < IOSTAT_NCOUNTERS; i++) {
+++ unsigned long read_percent = 0, write_percent = 0;
+++ if (stats->iostat_wtime_in_queue[i] == 0 &&
+++ stats->iostat_rtime_in_queue[i] == 0)
+++ continue;
+++ if (stats->iostat_read_reqs)
+++ read_percent = stats->iostat_rtime_in_queue[i] * 100 /
+++ stats->iostat_read_reqs;
+++ if (stats->iostat_write_reqs)
+++ write_percent = stats->iostat_wtime_in_queue[i] * 100 /
+++ stats->iostat_write_reqs;
+++ seq_printf(seq, "%16u %8lu %8lu %8lu %8lu\n",
+++ jiffies_to_msecs(((1UL << i) >> 1) << 1),
+++ stats->iostat_rtime_in_queue[i],
+++ read_percent,
+++ stats->iostat_wtime_in_queue[i],
+++ write_percent);
+++ }
+++
+++ 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 = scsi_disk(disk)->stats;
+++ unsigned long flags;
+++ unsigned long qdepth;
+++
+++
+++ spin_lock_irqsave (&stats->iostat_lock, flags);
+++ qdepth = stats->iostat_queue_depth;
+++ memset (stats, 0, offsetof(iostat_stats_t, iostat_lock));
+++ do_gettimeofday(&stats->iostat_timeval);
+++ stats->iostat_queue_stamp = jiffies;
+++ stats->iostat_queue_depth = qdepth;
+++ spin_unlock_irqrestore (&stats->iostat_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)
+++{
+++ 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_fini(void)
+++{
+++ if (proc_scsi != NULL && sd_iostats_procdir != NULL)
+++ remove_proc_entry(sd_iostats_procdir_name, proc_scsi);
+++
+++ sd_iostats_procdir = NULL;
+++}
+++
+++void sd_iostats_finish_req(struct scsi_cmnd *SCpnt)
+++{
+++ struct request *rq = SCpnt->request;
+++ iostat_stats_t *stats;
+++ unsigned long *tcounter;
+++ int tbucket;
+++ int tmp;
+++ unsigned long irqflags;
+++ unsigned long i;
+++
+++ stats = scsi_disk(rq->rq_disk)->stats;
+++ if (stats == NULL)
+++ return;
+++
+++ tmp = jiffies - rq->start_time;
+++ for (tbucket = 0; tmp > 1; tbucket++)
+++ tmp >>= 1;
+++ if (tbucket >= IOSTAT_NCOUNTERS)
+++ tbucket = IOSTAT_NCOUNTERS - 1;
+++ //printk("%u ticks in D to %u\n", jiffies - rq->start_time, tbucket);
+++
+++ tcounter = rq_data_dir(rq) == WRITE ?
+++ &stats->iostat_wtime[tbucket] : &stats->iostat_rtime[tbucket];
+++
+++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
+++
+++ /* update delay stats */
+++ (*tcounter)++;
+++
+++ /* update queue depth stats */
+++ i = stats->iostat_queue_depth;
+++ if (i >= IOSTAT_NCOUNTERS)
+++ i = IOSTAT_NCOUNTERS - 1;
+++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
+++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
+++ BUG_ON(stats->iostat_queue_depth == 0);
+++ stats->iostat_queue_depth--;
+++
+++ /* update seek stats. XXX: not sure about nr_sectors */
+++ stats->iostat_sectors += rq->nr_sectors;
+++ stats->iostat_reqs++;
+++ if (rq->sector != stats->iostat_next_sector) {
+++ stats->iostat_seek_sectors +=
+++ rq->sector > stats->iostat_next_sector ?
+++ rq->sector - stats->iostat_next_sector :
+++ stats->iostat_next_sector - rq->sector;
+++ stats->iostat_seeks++;
+++ }
+++ stats->iostat_next_sector = rq->sector + rq->nr_sectors;
+++
+++ stats->iostat_queue_stamp = jiffies;
+++
+++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
+++}
+++
+++void sd_iostats_start_req(struct scsi_cmnd *SCpnt)
+++{
+++ struct request *rq = SCpnt->request;
+++ iostat_stats_t *stats;
+++ iostat_counter_t *counter;
+++ int bucket;
+++ int tbucket;
+++ int tmp;
+++ unsigned long irqflags;
+++ unsigned long i;
+++ int nsect;
+++
+++ stats = scsi_disk(rq->rq_disk)->stats;
+++ if (stats == NULL)
+++ return;
+++
+++ nsect = scsi_bufflen(SCpnt) >> 9;
+++ for (bucket = 0, tmp = nsect; tmp > 1; bucket++)
+++ tmp >>= 1;
+++
+++ if (bucket >= IOSTAT_NCOUNTERS) {
+++ printk (KERN_ERR "sd_iostats_bump: nsect %d too big\n", nsect);
+++ BUG();
+++ }
+++
+++ counter = rq_data_dir(rq) == WRITE ?
+++ &stats->iostat_write_histogram[bucket] :
+++ &stats->iostat_read_histogram[bucket];
+++
+++ tmp = jiffies - rq->start_time;
+++ for (tbucket = 0; tmp > 1; tbucket++)
+++ tmp >>= 1;
+++ if (tbucket >= IOSTAT_NCOUNTERS)
+++ tbucket = IOSTAT_NCOUNTERS - 1;
+++ //printk("%u ticks in Q to %u\n", jiffies - rq->start_time, tbucket);
+++
+++ /* an ugly hack to know exact processing time. the right
+++ * solution is to add one more field to struct request
+++ * hopefully it will break nothing ... */
+++ rq->start_time = jiffies;
+++
+++ spin_lock_irqsave(&stats->iostat_lock, irqflags);
+++
+++ /* update queue depth stats */
+++ i = stats->iostat_queue_depth;
+++ if (i >= IOSTAT_NCOUNTERS)
+++ i = IOSTAT_NCOUNTERS - 1;
+++ stats->iostat_queue_ticks[i] += jiffies - stats->iostat_queue_stamp;
+++ stats->iostat_queue_ticks_sum += jiffies - stats->iostat_queue_stamp;
+++ stats->iostat_queue_depth++;
+++
+++ /* update delay stats */
+++ if (rq_data_dir(rq) == WRITE) {
+++ stats->iostat_wtime_in_queue[tbucket]++;
+++ stats->iostat_write_reqs++;
+++ } else {
+++ stats->iostat_rtime_in_queue[tbucket]++;
+++ stats->iostat_read_reqs++;
+++ }
+++
+++ /* update size stats */
+++ counter->iostat_size += nsect;
+++ counter->iostat_count++;
+++
+++ stats->iostat_queue_stamp = jiffies;
+++
+++ spin_unlock_irqrestore(&stats->iostat_lock, irqflags);
+++}
+++#endif
+++
++ /**
++ * scsi_disk_release - Called to free the scsi_disk structure
++ * @dev: pointer to embedded class device
++@@ -2281,10 +2692,16 @@
++ ida_remove(&sd_index_ida, sdkp->index);
++ spin_unlock(&sd_index_lock);
++
+++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
+++ if (sdkp->stats) {
+++ remove_proc_entry(disk->disk_name, sd_iostats_procdir);
+++ kfree(sdkp->stats);
+++ sdkp->stats = NULL;
+++ }
+++#endif
++ disk->private_data = NULL;
++ put_disk(disk);
++ put_device(&sdkp->device->sdev_gendev);
++-
++ kfree(sdkp);
++ }
++
++@@ -2401,6 +2818,8 @@
++ if (!majors)
++ return -ENODEV;
++
+++ sd_iostats_init();
+++
++ err = class_register(&sd_disk_class);
++ if (err)
++ goto err_out;
++@@ -2432,6 +2851,7 @@
++ err_out:
++ for (i = 0; i < SD_MAJORS; i++)
++ unregister_blkdev(sd_major(i), "sd");
+++ sd_iostats_fini();
++ return err;
++ }
++
++Index: linux-source-2.6.32/drivers/scsi/sd.h
++===================================================================
++--- linux-source-2.6.32.orig/drivers/scsi/sd.h 2009-12-03 04:51:21.000000000 +0100
+++++ linux-source-2.6.32/drivers/scsi/sd.h 2012-07-02 14:36:01.097202891 +0200
++@@ -42,6 +42,46 @@
++ SD_MEMPOOL_SIZE = 2, /* CDB pool size */
++ };
++
+++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
+++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;
+++
+++ /* queue depth: how well the pipe is filled up */
+++ unsigned long long iostat_queue_ticks[IOSTAT_NCOUNTERS];
+++ unsigned long long iostat_queue_ticks_sum;
+++ unsigned long iostat_queue_depth;
+++ unsigned long iostat_queue_stamp;
+++
+++ /* seeks: how linear the traffic is */
+++ unsigned long long iostat_next_sector;
+++ unsigned long long iostat_seek_sectors;
+++ unsigned long long iostat_seeks;
+++ unsigned long long iostat_sectors;
+++ unsigned long long iostat_reqs;
+++ unsigned long iostat_read_reqs;
+++ unsigned long iostat_write_reqs;
+++
+++ /* process time: how long it takes to process requests */
+++ unsigned long iostat_rtime[IOSTAT_NCOUNTERS];
+++ unsigned long iostat_wtime[IOSTAT_NCOUNTERS];
+++
+++ /* queue time: how long process spent in elevator's queue */
+++ unsigned long iostat_rtime_in_queue[IOSTAT_NCOUNTERS];
+++ unsigned long iostat_wtime_in_queue[IOSTAT_NCOUNTERS];
+++
+++ /* must be the last field, as it's used to know size to be memset'ed */
+++ spinlock_t iostat_lock;
+++} ____cacheline_aligned_in_smp iostat_stats_t;
+++#endif
+++
++ struct scsi_disk {
++ struct scsi_driver *driver; /* always &sd_template */
++ struct scsi_device *device;
++@@ -60,6 +100,9 @@
++ unsigned RCD : 1; /* state of disk RCD bit, unused */
++ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
++ unsigned first_scan : 1;
+++#if (defined(CONFIG_SD_IOSTATS) && defined(CONFIG_PROC_FS))
+++ iostat_stats_t *stats; /* scsi disk statistics */
+++#endif
++ };
++ #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
++
diff --git a/lustre/kernel_patches/patches/vfs_races-2.6.32-vanilla.patch b/lustre/kernel_patches/patches/vfs_races-2.6.32-vanilla.patch
new file mode 100644
index 0000000..4cd09d1
@@ -579,16 +1529,19 @@ index 0000000..4cd09d1
+
diff --git a/lustre/kernel_patches/series/2.6.32-vanilla.series b/lustre/kernel_patches/series/2.6.32-vanilla.series
new file mode 100644
-index 0000000..339372d
+index 0000000..ad055df
--- /dev/null
+++ b/lustre/kernel_patches/series/2.6.32-vanilla.series
-@@ -0,0 +1,9 @@
+@@ -0,0 +1,12 @@
+lustre_version.patch
+mpt-fusion-max-sge-2.6.32-vanilla.patch
+raid5-mmp-unplug-dev-2.6.32-vanilla.patch
+vfs_races-2.6.32-vanilla.patch
++iopen-misc-2.6.32-vanilla.patch
+dev_read_only-2.6.32-vanilla.patch
+blkdev_tunables-2.6.32-vanilla.patch
+export-2.6.32-vanilla.patch
++sd_iostats-2.6.32-vanilla.patch
++quota-support-64-bit-quota-format-2.6.32-vanilla.patch
+jbd2-jcberr-2.6.32-vanilla.patch
+bh_lru_size_config-2.6.32-vanilla.patch
--
Lustre Debian Packaging
More information about the Pkg-lustre-svn-commit
mailing list