printk ("EXT2-fs: not enough memory\n");
                goto failed_mount;
        }
-       percpu_counter_init(&sbi->s_freeblocks_counter);
-       percpu_counter_init(&sbi->s_freeinodes_counter);
-       percpu_counter_init(&sbi->s_dirs_counter);
        bgl_lock_init(&sbi->s_blockgroup_lock);
        sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
                               GFP_KERNEL);
        sbi->s_gdb_count = db_count;
        get_random_bytes(&sbi->s_next_generation, sizeof(u32));
        spin_lock_init(&sbi->s_next_gen_lock);
+
+       percpu_counter_init(&sbi->s_freeblocks_counter,
+                               ext2_count_free_blocks(sb));
+       percpu_counter_init(&sbi->s_freeinodes_counter,
+                               ext2_count_free_inodes(sb));
+       percpu_counter_init(&sbi->s_dirs_counter,
+                               ext2_count_dirs(sb));
        /*
         * set up enough so that it can read an inode
         */
        if (!sb->s_root) {
                iput(root);
                printk(KERN_ERR "EXT2-fs: get root inode failed\n");
-               goto failed_mount2;
+               goto failed_mount3;
        }
        if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
                dput(sb->s_root);
                sb->s_root = NULL;
                printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n");
-               goto failed_mount2;
+               goto failed_mount3;
        }
        if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
                ext2_warning(sb, __FUNCTION__,
                        "mounting ext3 filesystem as ext2");
        ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
-       percpu_counter_mod(&sbi->s_freeblocks_counter,
-                               ext2_count_free_blocks(sb));
-       percpu_counter_mod(&sbi->s_freeinodes_counter,
-                               ext2_count_free_inodes(sb));
-       percpu_counter_mod(&sbi->s_dirs_counter,
-                               ext2_count_dirs(sb));
        return 0;
 
 cantfind_ext2:
                printk("VFS: Can't find an ext2 filesystem on dev %s.\n",
                       sb->s_id);
        goto failed_mount;
-
+failed_mount3:
+       percpu_counter_destroy(&sbi->s_freeblocks_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
 failed_mount2:
        for (i = 0; i < db_count; i++)
                brelse(sbi->s_group_desc[i]);
 
                goto failed_mount;
        }
 
-       percpu_counter_init(&sbi->s_freeblocks_counter);
-       percpu_counter_init(&sbi->s_freeinodes_counter);
-       percpu_counter_init(&sbi->s_dirs_counter);
        bgl_lock_init(&sbi->s_blockgroup_lock);
 
        for (i = 0; i < db_count; i++) {
        sbi->s_gdb_count = db_count;
        get_random_bytes(&sbi->s_next_generation, sizeof(u32));
        spin_lock_init(&sbi->s_next_gen_lock);
+
+       percpu_counter_init(&sbi->s_freeblocks_counter,
+               ext3_count_free_blocks(sb));
+       percpu_counter_init(&sbi->s_freeinodes_counter,
+               ext3_count_free_inodes(sb));
+       percpu_counter_init(&sbi->s_dirs_counter,
+               ext3_count_dirs(sb));
+
        /* per fileystem reservation list head & lock */
        spin_lock_init(&sbi->s_rsv_window_lock);
        sbi->s_rsv_window_root = RB_ROOT;
        if (!test_opt(sb, NOLOAD) &&
            EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
                if (ext3_load_journal(sb, es, journal_devnum))
-                       goto failed_mount2;
+                       goto failed_mount3;
        } else if (journal_inum) {
                if (ext3_create_journal(sb, es, journal_inum))
-                       goto failed_mount2;
+                       goto failed_mount3;
        } else {
                if (!silent)
                        printk (KERN_ERR
                                "ext3: No journal on filesystem on %s\n",
                                sb->s_id);
-               goto failed_mount2;
+               goto failed_mount3;
        }
 
        /* We have now updated the journal if required, so we can
                    (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
                        printk(KERN_ERR "EXT3-fs: Journal does not support "
                               "requested data journaling mode\n");
-                       goto failed_mount3;
+                       goto failed_mount4;
                }
        default:
                break;
        if (!sb->s_root) {
                printk(KERN_ERR "EXT3-fs: get root inode failed\n");
                iput(root);
-               goto failed_mount3;
+               goto failed_mount4;
        }
        if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
                dput(sb->s_root);
                sb->s_root = NULL;
                printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n");
-               goto failed_mount3;
+               goto failed_mount4;
        }
 
        ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
                test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
                "writeback");
 
-       percpu_counter_mod(&sbi->s_freeblocks_counter,
-               ext3_count_free_blocks(sb));
-       percpu_counter_mod(&sbi->s_freeinodes_counter,
-               ext3_count_free_inodes(sb));
-       percpu_counter_mod(&sbi->s_dirs_counter,
-               ext3_count_dirs(sb));
-
        lock_kernel();
        return 0;
 
                       sb->s_id);
        goto failed_mount;
 
-failed_mount3:
+failed_mount4:
        journal_destroy(sbi->s_journal);
+failed_mount3:
+       percpu_counter_destroy(&sbi->s_freeblocks_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
 failed_mount2:
        for (i = 0; i < db_count; i++)
                brelse(sbi->s_group_desc[i]);
 
        if (files_stat.max_files < NR_FILE)
                files_stat.max_files = NR_FILE;
        files_defer_init();
-       percpu_counter_init(&nr_files);
+       percpu_counter_init(&nr_files, 0);
 } 
 
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/percpu.h>
+#include <linux/types.h>
 
 #ifdef CONFIG_SMP
 
 struct percpu_counter {
        spinlock_t lock;
-       long count;
-       long *counters;
+       s64 count;
+       s32 *counters;
 };
 
 #if NR_CPUS >= 16
 #define FBC_BATCH      (NR_CPUS*4)
 #endif
 
-static inline void percpu_counter_init(struct percpu_counter *fbc)
+static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
 {
        spin_lock_init(&fbc->lock);
-       fbc->count = 0;
-       fbc->counters = alloc_percpu(long);
+       fbc->count = amount;
+       fbc->counters = alloc_percpu(s32);
 }
 
 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
        free_percpu(fbc->counters);
 }
 
-void percpu_counter_mod(struct percpu_counter *fbc, long amount);
-long percpu_counter_sum(struct percpu_counter *fbc);
+void percpu_counter_mod(struct percpu_counter *fbc, s32 amount);
+s64 percpu_counter_sum(struct percpu_counter *fbc);
 
-static inline long percpu_counter_read(struct percpu_counter *fbc)
+static inline s64 percpu_counter_read(struct percpu_counter *fbc)
 {
        return fbc->count;
 }
 /*
  * It is possible for the percpu_counter_read() to return a small negative
  * number for some counter which should never be negative.
+ *
  */
-static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
+static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
 {
-       long ret = fbc->count;
+       s64 ret = fbc->count;
 
        barrier();              /* Prevent reloads of fbc->count */
-       if (ret > 0)
+       if (ret >= 0)
                return ret;
        return 1;
 }
 #else
 
 struct percpu_counter {
-       long count;
+       s64 count;
 };
 
-static inline void percpu_counter_init(struct percpu_counter *fbc)
+static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
 {
-       fbc->count = 0;
+       fbc->count = amount;
 }
 
 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
 }
 
 static inline void
-percpu_counter_mod(struct percpu_counter *fbc, long amount)
+percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
 {
        preempt_disable();
        fbc->count += amount;
        preempt_enable();
 }
 
-static inline long percpu_counter_read(struct percpu_counter *fbc)
+static inline s64 percpu_counter_read(struct percpu_counter *fbc)
 {
        return fbc->count;
 }
 
-static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
+static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
 {
        return fbc->count;
 }
 
-static inline long percpu_counter_sum(struct percpu_counter *fbc)
+static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
 {
        return percpu_counter_read_positive(fbc);
 }
 
 #include <linux/percpu_counter.h>
 #include <linux/module.h>
 
-void percpu_counter_mod(struct percpu_counter *fbc, long amount)
+void percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
 {
        long count;
-       long *pcount;
+       s32 *pcount;
        int cpu = get_cpu();
 
        pcount = per_cpu_ptr(fbc->counters, cpu);
  * Add up all the per-cpu counts, return the result.  This is a more accurate
  * but much slower version of percpu_counter_read_positive()
  */
-long percpu_counter_sum(struct percpu_counter *fbc)
+s64 percpu_counter_sum(struct percpu_counter *fbc)
 {
-       long ret;
+       s64 ret;
        int cpu;
 
        spin_lock(&fbc->lock);
        ret = fbc->count;
        for_each_possible_cpu(cpu) {
-               long *pcount = per_cpu_ptr(fbc->counters, cpu);
+               s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
                ret += *pcount;
        }
        spin_unlock(&fbc->lock);