There is no locking around the increment of this per-filesystem counter. 
Create a new lock, just for this.



 fs/ext2/ialloc.c           |    2 ++
 fs/ext2/super.c            |    1 +
 include/linux/ext2_fs_sb.h |    1 +
 3 files changed, 4 insertions(+)

diff -puN fs/ext2/ialloc.c~ext2-s_next_generation-fix fs/ext2/ialloc.c
--- 25/fs/ext2/ialloc.c~ext2-s_next_generation-fix	2004-01-03 00:52:56.000000000 -0800
+++ 25-akpm/fs/ext2/ialloc.c	2004-01-03 00:52:56.000000000 -0800
@@ -599,7 +599,9 @@ got:
 	ei->i_dir_start_lookup = 0;
 	ei->i_state = EXT2_STATE_NEW;
 	ext2_set_inode_flags(inode);
+	spin_lock(&sbi->s_next_gen_lock);
 	inode->i_generation = sbi->s_next_generation++;
+	spin_unlock(&sbi->s_next_gen_lock);
 	insert_inode_hash(inode);
 
 	if (DQUOT_ALLOC_INODE(inode)) {
diff -puN include/linux/ext2_fs_sb.h~ext2-s_next_generation-fix include/linux/ext2_fs_sb.h
--- 25/include/linux/ext2_fs_sb.h~ext2-s_next_generation-fix	2004-01-03 00:52:56.000000000 -0800
+++ 25-akpm/include/linux/ext2_fs_sb.h	2004-01-03 00:52:56.000000000 -0800
@@ -45,6 +45,7 @@ struct ext2_sb_info {
 	int s_desc_per_block_bits;
 	int s_inode_size;
 	int s_first_ino;
+	spinlock_t s_next_gen_lock;
 	u32 s_next_generation;
 	unsigned long s_dir_count;
 	u8 *s_debts;
diff -puN fs/ext2/super.c~ext2-s_next_generation-fix fs/ext2/super.c
--- 25/fs/ext2/super.c~ext2-s_next_generation-fix	2004-01-03 00:52:56.000000000 -0800
+++ 25-akpm/fs/ext2/super.c	2004-01-03 01:01:39.000000000 -0800
@@ -809,6 +809,7 @@ static int ext2_fill_super(struct super_
 	}
 	sbi->s_gdb_count = db_count;
 	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
+	spin_lock_init(&sbi->s_next_gen_lock);
 	/*
 	 * set up enough so that it can read an inode
 	 */

_