From 10f5222f50310d903aa96274d415f8ee03be1b9e Mon Sep 17 00:00:00 2001
From: rupesh <rupesh>
Date: Wed, 17 Oct 2007 12:16:08 +0000
Subject: [PATCH] bz 13164 description: statfs speedup patches for rhel5 and
 sles10 reviewed by: adilger@clusterfs.com, scjody@clusterfs.com,
 kalpak@clusterfs.com

---
 .../patches/ext3-statfs-2.6-rhel5.patch       | 70 ++++++++++++++++++
 .../patches/ext3-statfs-2.6-sles10.patch      | 71 +++++++++++++++++++
 .../series/ldiskfs-2.6-rhel5.series           |  1 +
 .../series/ldiskfs-2.6-sles10.series          |  1 +
 4 files changed, 143 insertions(+)
 create mode 100644 ldiskfs/kernel_patches/patches/ext3-statfs-2.6-rhel5.patch
 create mode 100644 ldiskfs/kernel_patches/patches/ext3-statfs-2.6-sles10.patch

diff --git a/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-rhel5.patch b/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-rhel5.patch
new file mode 100644
index 0000000000..7435625c97
--- /dev/null
+++ b/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-rhel5.patch
@@ -0,0 +1,70 @@
+Index: linux-2.6.18-8.1.8/fs/ext3/super.c
+===================================================================
+--- linux-2.6.18-8.1.8.orig/fs/ext3/super.c
++++ linux-2.6.18-8.1.8/fs/ext3/super.c
+@@ -2923,18 +2923,18 @@ static int ext3_statfs (struct dentry * 
+ 	struct super_block *sb = dentry->d_sb;
+ 	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 	struct ext3_super_block *es = sbi->s_es;
+-	ext3_fsblk_t overhead;
+-	int i;
+ 
+-	if (test_opt (sb, MINIX_DF))
+-		overhead = 0;
+-	else {
+-		unsigned long ngroups;
+-		ngroups = EXT3_SB(sb)->s_groups_count;
++	if (test_opt(sb, MINIX_DF)) {
++		sbi->s_overhead_last = 0;
++	} else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
++		unsigned long ngroups = sbi->s_groups_count, i;
++		ext3_fsblk_t overhead = 0;
+ 		smp_rmb();
+ 
+ 		/*
+-		 * Compute the overhead (FS structures)
++		 * Compute the overhead (FS structures).  This is constant
++		 * for a given filesystem unless the number of block groups
++		 * changes so we cache the previous value until it does.
+ 		 */
+ 
+ 		/*
+@@ -2956,18 +2956,23 @@ static int ext3_statfs (struct dentry * 
+ 		 * Every block group has an inode bitmap, a block
+ 		 * bitmap, and an inode table.
+ 		 */
+-		overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group));
++		overhead += ngroups * (2 + sbi->s_itb_per_group);
++		sbi->s_overhead_last = overhead;
++		smp_wmb();
++		sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
+ 	}
+ 
+ 	buf->f_type = EXT3_SUPER_MAGIC;
+ 	buf->f_bsize = sb->s_blocksize;
+-	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
++	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
+ 	buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
++	es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
+ 	buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
+ 	if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
+ 		buf->f_bavail = 0;
+ 	buf->f_files = le32_to_cpu(es->s_inodes_count);
+ 	buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
++	es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
+ 	buf->f_namelen = EXT3_NAME_LEN;
+ 	return 0;
+ }
+Index: linux-2.6.18-8.1.8/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.6.18-8.1.8.orig/include/linux/ext3_fs_sb.h
++++ linux-2.6.18-8.1.8/include/linux/ext3_fs_sb.h
+@@ -45,6 +45,8 @@ struct ext3_sb_info {
+ 	unsigned long s_gdb_count;	/* Number of group descriptor blocks */
+ 	unsigned long s_desc_per_block;	/* Number of group descriptors per block */
+ 	unsigned long s_groups_count;	/* Number of groups in the fs */
++	unsigned long s_overhead_last;  /* Last calculated overhead */
++	unsigned long s_blocks_last;    /* Last seen block count */
+ 	struct buffer_head * s_sbh;	/* Buffer containing the super block */
+ 	struct ext3_super_block * s_es;	/* Pointer to the super block in the buffer */
+ 	struct buffer_head ** s_group_desc;
diff --git a/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-sles10.patch b/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-sles10.patch
new file mode 100644
index 0000000000..1e1a4db112
--- /dev/null
+++ b/ldiskfs/kernel_patches/patches/ext3-statfs-2.6-sles10.patch
@@ -0,0 +1,71 @@
+Index: linux-2.6.16.46-0.14/fs/ext3/super.c
+===================================================================
+--- linux-2.6.16.46-0.14.orig/fs/ext3/super.c
++++ linux-2.6.16.46-0.14/fs/ext3/super.c
+@@ -2908,18 +2908,19 @@ restore_opts:
+ static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
+ {
+ 	struct ext3_super_block *es = EXT3_SB(sb)->s_es;
+-	unsigned long overhead;
+-	int i;
++	struct ext3_sb_info *sbi = EXT3_SB(sb);
+ 
+-	if (test_opt (sb, MINIX_DF))
+-		overhead = 0;
+-	else {
+-		unsigned long ngroups;
+-		ngroups = EXT3_SB(sb)->s_groups_count;
++	if (test_opt(sb, MINIX_DF)) {
++		sbi->s_overhead_last = 0;
++	} else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
++		unsigned long ngroups = sbi->s_groups_count, i;
++		unsigned long overhead = 0;
+ 		smp_rmb();
+ 
+ 		/*
+-		 * Compute the overhead (FS structures)
++		 * Compute the overhead (FS structures).  This is constant
++		 * for a given filesystem unless the number of block groups
++		 * changes so we cache the previous value until it does.
+ 		 */
+ 
+ 		/*
+@@ -2941,18 +2942,23 @@ static int ext3_statfs (struct super_blo
+ 		 * Every block group has an inode bitmap, a block
+ 		 * bitmap, and an inode table.
+ 		 */
+-		overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group));
++		overhead += ngroups * (2 + sbi->s_itb_per_group);
++		sbi->s_overhead_last = overhead;
++		smp_wmb();
++		sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
+ 	}
+ 
+ 	buf->f_type = EXT3_SUPER_MAGIC;
+ 	buf->f_bsize = sb->s_blocksize;
+-	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
++	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
+ 	buf->f_bfree = ext3_count_free_blocks (sb);
++	es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
+ 	buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
+ 	if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
+ 		buf->f_bavail = 0;
+ 	buf->f_files = le32_to_cpu(es->s_inodes_count);
+ 	buf->f_ffree = ext3_count_free_inodes (sb);
++	es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
+ 	buf->f_namelen = EXT3_NAME_LEN;
+ 	return 0;
+ }
+Index: linux-2.6.16.46-0.14/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.6.16.46-0.14.orig/include/linux/ext3_fs_sb.h
++++ linux-2.6.16.46-0.14/include/linux/ext3_fs_sb.h
+@@ -45,6 +45,8 @@ struct ext3_sb_info {
+ 	unsigned long s_gdb_count;	/* Number of group descriptor blocks */
+ 	unsigned long s_desc_per_block;	/* Number of group descriptors per block */
+ 	unsigned long s_groups_count;	/* Number of groups in the fs */
++	unsigned long s_overhead_last;  /* Last calculated overhead */
++	unsigned long s_blocks_last;    /* Last seen block count */
+ 	struct buffer_head * s_sbh;	/* Buffer containing the super block */
+ 	struct ext3_super_block * s_es;	/* Pointer to the super block in the buffer */
+ 	struct buffer_head ** s_group_desc;
diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
index 1de2c141b5..efa74ed660 100644
--- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
+++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
@@ -17,3 +17,4 @@ ext3-mmp-2.6.18-vanilla.patch
 ext3-unlink-race.patch
 ext3-fiemap-2.6.18-vanilla.patch
 ext3-block-bitmap-validation-2.6-rhel5.patch
+ext3-statfs-2.6-rhel5.patch
diff --git a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series
index 50e86e7b68..6e09977724 100644
--- a/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series
+++ b/ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series
@@ -21,3 +21,4 @@ ext3-inode-version-2.6-sles10.patch
 ext3-mmp-2.6-sles10.patch
 ext3-fiemap-2.6-sles10.patch
 ext3-block-bitmap-validation-2.6-SLES10.patch
+ext3-statfs-2.6-sles10.patch
-- 
GitLab