1 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/fs/ext3/ialloc.c 2005-05-16 14:10:54.000000000 -0600
4 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/ialloc.c 2005-05-16 14:18:29.000000000 -0600
9 -static int find_group_other(struct super_block *sb, struct inode *parent)
10 +static int find_group_other(struct super_block *sb, struct inode *parent,
13 int parent_group = EXT3_I(parent)->i_block_group;
14 + struct ext3_sb_info *sbi = EXT3_SB(sb);
15 int ngroups = EXT3_SB(sb)->s_groups_count;
16 struct ext3_group_desc *desc;
17 struct buffer_head *bh;
19 + int best_group = -1;
20 + int avefreeb, freeb, best_group_freeb = 0;
23 * Try to place the inode in its parent directory
26 desc = ext3_get_group_desc (sb, group, &bh);
27 if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
28 - le16_to_cpu(desc->bg_free_blocks_count))
29 + (!S_ISREG(mode) || le16_to_cpu(desc->bg_free_blocks_count)))
32 + avefreeb = le32_to_cpu(sbi->s_es->s_free_blocks_count) / ngroups;
34 * We're going to place this inode in a different blockgroup from its
35 * parent. We want to cause files in a common directory to all land in
37 group = (group + parent->i_ino) % ngroups;
40 - * Use a quadratic hash to find a group with a free inode and some free
42 + * Use a quadratic hash to find a group with a free inode and
43 + * average number of free blocks.
45 for (i = 1; i < ngroups; i <<= 1) {
49 desc = ext3_get_group_desc (sb, group, &bh);
50 - if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
51 - le16_to_cpu(desc->bg_free_blocks_count))
52 + if (!desc || !desc->bg_free_inodes_count)
56 + if (le16_to_cpu(desc->bg_free_blocks_count) >= avefreeb)
61 - * That failed: try linear search for a free inode, even if that group
62 - * has no free blocks.
63 + * That failed: start from last group used to allocate inode
64 + * try linear search for a free inode and prefereably
67 - group = parent_group;
68 + group = sbi->s_last_alloc_group;
70 + group = parent_group;
72 for (i = 0; i < ngroups; i++) {
73 if (++group >= ngroups)
75 desc = ext3_get_group_desc (sb, group, &bh);
76 - if (desc && le16_to_cpu(desc->bg_free_inodes_count))
78 + if (!desc || !desc->bg_free_inodes_count)
80 + freeb = le16_to_cpu(desc->bg_free_blocks_count);
81 + if (freeb > best_group_freeb) {
82 + best_group_freeb = freeb;
84 + if (freeb >= avefreeb || !S_ISREG(mode))
90 + sbi->s_last_alloc_group = best_group;
97 group = find_group_orlov(sb, dir);
99 - group = find_group_other(sb, dir);
100 + group = find_group_other(sb, dir, mode);
104 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/super.c
105 ===================================================================
106 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/fs/ext3/super.c 2005-05-16 14:10:54.000000000 -0600
107 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/fs/ext3/super.c 2005-05-16 14:17:14.000000000 -0600
108 @@ -1297,6 +1297,7 @@
109 percpu_counter_init(&sbi->s_dirs_counter);
110 bgl_lock_init(&sbi->s_blockgroup_lock);
112 + sbi->s_last_alloc_group = -1;
113 for (i = 0; i < db_count; i++) {
114 block = descriptor_loc(sb, logic_sb_block, i);
115 sbi->s_group_desc[i] = sb_bread(sb, block);
116 Index: linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/include/linux/ext3_fs_sb.h
117 ===================================================================
118 --- linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891.orig/include/linux/ext3_fs_sb.h 2005-05-16 14:10:54.000000000 -0600
119 +++ linux-2.6.5-SLES9_SP1_BRANCH_2004111114454891/include/linux/ext3_fs_sb.h 2005-05-16 14:17:14.000000000 -0600
121 struct percpu_counter s_freeinodes_counter;
122 struct percpu_counter s_dirs_counter;
123 struct blockgroup_lock s_blockgroup_lock;
124 + /* Last group used to allocate inode */
125 + int s_last_alloc_group;
127 /* root of the per fs reservation window tree */
128 spinlock_t s_rsv_window_lock;