Whamcloud - gitweb
Branch b1_6
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-statfs-2.6.18.patch
diff --git a/ldiskfs/kernel_patches/patches/ext3-statfs-2.6.18.patch b/ldiskfs/kernel_patches/patches/ext3-statfs-2.6.18.patch
new file mode 100644 (file)
index 0000000..64bac55
--- /dev/null
@@ -0,0 +1,70 @@
+Index: linux-2.6.18.8/fs/ext3/super.c
+===================================================================
+--- linux-2.6.18.8.orig/fs/ext3/super.c        2007-07-20 16:51:14.000000000 +0200
++++ linux-2.6.18.8/fs/ext3/super.c     2007-07-20 16:54:17.000000000 +0200
+@@ -2572,18 +2572,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.
+                */
+               /*
+@@ -2605,18 +2605,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/include/linux/ext3_fs_sb.h
+===================================================================
+--- linux-2.6.18.8.orig/include/linux/ext3_fs_sb.h     2007-07-20 16:51:23.000000000 +0200
++++ linux-2.6.18.8/include/linux/ext3_fs_sb.h  2007-07-20 16:51:43.000000000 +0200
+@@ -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;