+++ /dev/null
-Index: linux-2.6.12/fs/ext3/super.c
-===================================================================
---- linux-2.6.12.orig/fs/ext3/super.c 2005-06-17 13:48:29.000000000 -0600
-+++ linux-2.6.12/fs/ext3/super.c 2005-11-25 05:59:47.000000000 -0700
-@@ -2165,13 +2165,13 @@
- {
- struct ext3_super_block *es = EXT3_SB(sb)->s_es;
- unsigned long overhead;
-- int i;
-
- if (test_opt (sb, MINIX_DF))
- overhead = 0;
- else {
-- unsigned long ngroups;
-- ngroups = EXT3_SB(sb)->s_groups_count;
-+ unsigned long ngroups = EXT3_SB(sb)->s_groups_count, group;
-+ unsigned long three = 1, five = 5, seven = 7;
-+ unsigned long metabg = -1UL;
- smp_rmb();
-
- /*
-@@ -2189,11 +2188,14 @@
- * block group descriptors. If the sparse superblocks
- * feature is turned on, then not all groups have this.
- */
-- for (i = 0; i < ngroups; i++) {
-- overhead += ext3_bg_has_super(sb, i) +
-- ext3_bg_num_gdb(sb, i);
-- cond_resched();
-- }
-+ overhead += 1 + EXT3_SB(sb)->s_gdb_count; /* group 0 */
-+ if (EXT3_HAS_INCOMPAT_FEATURE(sb,EXT3_FEATURE_INCOMPAT_META_BG))
-+ metabg =le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg);
-+
-+ while ((group = ext3_list_backups(sb, &three, &five, &seven)) <
-+ ngroups) /* sb + group descriptors backups */
-+ overhead += 1 + (group >= metabg ? 1 :
-+ EXT3_SB(sb)->s_gdb_count);
-
- /*
- * Every block group has an inode bitmap, a block
-@@ -2205,12 +2204,16 @@
- 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_bfree = ext3_count_free_blocks (sb);
-+ buf->f_bfree = percpu_counter_read(&EXT3_SB(sb)->s_freeblocks_counter);
-+ if (buf->f_bfree < 0)
-+ buf->f_bfree = 0;
- 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);
-+ buf->f_ffree = percpu_counter_read(&EXT3_SB(sb)->s_freeinodes_counter);
-+ if (buf->f_ffree < 0)
-+ buf->f_ffree = 0;
- buf->f_namelen = EXT3_NAME_LEN;
- return 0;
- }
-Index: linux-2.6.12/fs/ext3/resize.c
-===================================================================
---- linux-2.6.12.orig/fs/ext3/resize.c 2005-11-24 15:17:06.000000000 -0700
-+++ linux-2.6.12/fs/ext3/resize.c 2005-11-25 06:01:01.000000000 -0700
-@@ -285,17 +285,17 @@
- * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
- * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
- */
--static unsigned ext3_list_backups(struct super_block *sb, unsigned *three,
-- unsigned *five, unsigned *seven)
-+unsigned long ext3_list_backups(struct super_block *sb, unsigned long *three,
-+ unsigned long *five, unsigned long *seven)
- {
-- unsigned *min = three;
-+ unsigned long metabg = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_meta_bg);
-+ unsigned long *min = three, ret;
- int mult = 3;
-- unsigned ret;
-
- if (!EXT3_HAS_RO_COMPAT_FEATURE(sb,
- EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-- ret = *min;
-- *min += 1;
-+ ret = *three;
-+ *three += 1;
- return ret;
- }
-
-@@ -308,8 +307,26 @@
- mult = 7;
- }
-
-- ret = *min;
-- *min *= mult;
-+ if (EXT3_HAS_INCOMPAT_FEATURE(sb,EXT3_FEATURE_INCOMPAT_META_BG) &&
-+ *min >= metabg * EXT3_DESC_PER_BLOCK(sb)) {
-+ ret = *min;
-+ switch (ret & (EXT3_DESC_PER_BLOCK(sb) - 1)) {
-+ case 0:
-+ *three = ret + 1;
-+ break;
-+ case 1:
-+ *three = ret + EXT3_DESC_PER_BLOCK(sb) - 2;
-+ break;
-+ default:
-+ *three = (ret | (EXT3_DESC_PER_BLOCK(sb) - 1)) + 1;
-+ break;
-+ }
-+ *five = -1UL;
-+ *seven = -1UL;
-+ } else {
-+ ret = *min;
-+ *min *= mult;
-+ }
-
- return ret;
- }
-@@ -324,17 +337,17 @@
- {
- const unsigned long blk = primary->b_blocknr;
- const unsigned long end = EXT3_SB(sb)->s_groups_count;
-- unsigned three = 1;
-- unsigned five = 5;
-- unsigned seven = 7;
-- unsigned grp;
-+ unsigned long three = 1;
-+ unsigned long five = 5;
-+ unsigned long seven = 7;
-+ unsigned long grp;
- __u32 *p = (__u32 *)primary->b_data;
- int gdbackups = 0;
-
- while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) {
- if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){
- ext3_warning(sb, __FUNCTION__,
-- "reserved GDT %ld missing grp %d (%ld)\n",
-+ "reserved GDT %ld missing grp %ld (%ld)\n",
- blk, grp,
- grp * EXT3_BLOCKS_PER_GROUP(sb) + blk);
- return -EINVAL;
-@@ -618,10 +631,8 @@
- struct ext3_sb_info *sbi = EXT3_SB(sb);
- const unsigned long last = sbi->s_groups_count;
- const int bpg = EXT3_BLOCKS_PER_GROUP(sb);
-- unsigned three = 1;
-- unsigned five = 5;
-- unsigned seven = 7;
-- unsigned group;
-+ unsigned long three = 1, five = 5, seven = 7;
-+ unsigned long group;
- int rest = sb->s_blocksize - size;
- handle_t *handle;
- int err = 0, err2;
-@@ -672,7 +683,7 @@
- exit_err:
- if (err) {
- ext3_warning(sb, __FUNCTION__,
-- "can't update backup for group %d (err %d), "
-+ "can't update backup for group %ld (err %d), "
- "forcing fsck on next reboot\n", group, err);
- sbi->s_mount_state &= ~EXT3_VALID_FS;
- sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS);
-Index: linux-2.6.12/include/linux/ext3_fs.h
-===================================================================
---- linux-2.6.12.orig/include/linux/ext3_fs.h 2005-06-17 13:48:29.000000000 -0600
-+++ linux-2.6.12/include/linux/ext3_fs.h 2005-11-25 05:59:47.000000000 -0700
-@@ -788,6 +788,10 @@
- extern int ext3_group_extend(struct super_block *sb,
- struct ext3_super_block *es,
- unsigned long n_blocks_count);
-+extern unsigned long ext3_list_backups(struct super_block *sb,
-+ unsigned long *three,
-+ unsigned long *five,
-+ unsigned long *seven);
-
- /* super.c */
- extern void ext3_error (struct super_block *, const char *, const char *, ...)