From: Alex Tomas We don't need to abandon the entire blockgroup if another CPU happened to steal our target inode - just go onto the next inode. fs/ext2/ialloc.c | 19 +++++++++++++------ 1 files changed, 13 insertions(+), 6 deletions(-) diff -puN fs/ext2/ialloc.c~ext2_new_inode-fixes-tweaks fs/ext2/ialloc.c --- 25/fs/ext2/ialloc.c~ext2_new_inode-fixes-tweaks 2003-11-08 13:12:27.000000000 -0800 +++ 25-akpm/fs/ext2/ialloc.c 2003-11-08 13:12:27.000000000 -0800 @@ -503,7 +503,6 @@ struct inode *ext2_new_inode(struct inod ei = EXT2_I(inode); sbi = EXT2_SB(sb); es = sbi->s_es; -repeat: if (S_ISDIR(mode)) { if (test_opt(sb, OLDALLOC)) group = find_group_dir(sb, dir); @@ -525,9 +524,11 @@ repeat: err = -EIO; goto fail; } + ino = 0; - ino = ext2_find_first_zero_bit((unsigned long *)bitmap_bh->b_data, - EXT2_INODES_PER_GROUP(sb)); +repeat_in_this_group: + ino = ext2_find_next_zero_bit((unsigned long *)bitmap_bh->b_data, + EXT2_INODES_PER_GROUP(sb), ino); if (ino >= EXT2_INODES_PER_GROUP(sb)) { /* * Rare race: find_group_xx() decided that there were @@ -543,9 +544,15 @@ repeat: } if (ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), ino, bitmap_bh->b_data)) { - if (++group == sbi->s_groups_count) - group = 0; - continue; + /* we lost this inode */ + if (++ino >= EXT2_INODES_PER_GROUP(sb)) { + /* this group is exhausted, try next group */ + if (++group == sbi->s_groups_count) + group = 0; + continue; + } + /* try to find free inode in the same group */ + goto repeat_in_this_group; } goto got; } _